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

commit/galaxy-central: kanwei: Make tool.execute pass kwargs instead of new "set_output_history" parameter for backwards compat
by Bitbucket 02 Feb '11
by Bitbucket 02 Feb '11
02 Feb '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/5709198bdc0a/
changeset: r4980:5709198bdc0a
user: kanwei
date: 2011-02-02 21:06:10
summary: Make tool.execute pass kwargs instead of new "set_output_history" parameter for backwards compat
affected #: 1 file (44 bytes)
--- a/lib/galaxy/tools/__init__.py Tue Feb 01 15:24:45 2011 +0000
+++ b/lib/galaxy/tools/__init__.py Wed Feb 02 15:06:10 2011 -0500
@@ -1215,14 +1215,14 @@
raise Exception( "Unexpected parameter type" )
return args
- def execute( self, trans, incoming={}, set_output_hid=True, set_output_history=True, history=None ):
+ def execute( self, trans, incoming={}, set_output_hid=True, history=None, **kwargs ):
"""
Execute the tool using parameter values in `incoming`. This just
dispatches to the `ToolAction` instance specified by
`self.tool_action`. In general this will create a `Job` that
when run will build the tool's outputs, e.g. `DefaultToolAction`.
"""
- return self.tool_action.execute( self, trans, incoming=incoming, set_output_hid=set_output_hid, set_output_history=set_output_history, history=history )
+ return self.tool_action.execute( self, trans, incoming=incoming, set_output_hid=set_output_hid, history=history, **kwargs )
def params_to_strings( self, params, app ):
return params_to_strings( self.inputs, params, app )
@@ -1233,7 +1233,7 @@
def check_and_update_param_values( self, values, trans ):
"""
Check that all parameters have values, and fill in with default
- values where neccesary. This could be called after loading values
+ values where necessary. This could be called after loading values
from a database in case new parameters have been added.
"""
messages = {}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/c4c2e7dc5c02/
changeset: r4977:c4c2e7dc5c02
user: peterjc
date: 2011-01-31 18:13:13
summary: Access path field from BLAST loc file, and store ID in database instead
affected #: 5 files (1.1 KB)
--- a/tools/ncbi_blast_plus/ncbi_blastn_wrapper.xml Tue Feb 01 20:07:17 2011 -0500
+++ b/tools/ncbi_blast_plus/ncbi_blastn_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
@@ -1,4 +1,4 @@
-<tool id="ncbi_blastn_wrapper" name="NCBI BLAST+ blastn" version="0.0.7">
+<tool id="ncbi_blastn_wrapper" name="NCBI BLAST+ blastn" version="0.0.8"><description>Search nucleotide database with nucleotide query sequence(s)</description><command>
## The command is a Cheetah template which allows some Python based syntax.
@@ -6,7 +6,7 @@
blastn
-query "$query"
#if $db_opts.db_opts_selector == "db":
- -db "$db_opts.database"
+ -db "${db_opts.database.fields.path}"
#else:
-subject "$db_opts.subject"
#end if
@@ -40,13 +40,10 @@
</param><when value="db"><param name="database" type="select" label="Nucleotide BLAST database">
- <!-- The BLAST loc file has three columns:
- column 0 is an identifier (not used here, see legacy megablast wrapper),
- column 1 is the caption (show this to the user),
- column 2 is the database path (given to BLAST+) --><options from_file="blastdb.loc">
+ <column name="value" index="0"/><column name="name" index="1"/>
- <column name="value" index="2"/>
+ <column name="path" index="2"/></options></param><param name="subject" type="hidden" value="" />
--- a/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Tue Feb 01 20:07:17 2011 -0500
+++ b/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
@@ -1,4 +1,4 @@
-<tool id="ncbi_blastp_wrapper" name="NCBI BLAST+ blastp" version="0.0.7">
+<tool id="ncbi_blastp_wrapper" name="NCBI BLAST+ blastp" version="0.0.8"><description>Search protein database with protein query sequence(s)</description><command>
## The command is a Cheetah template which allows some Python based syntax.
@@ -6,7 +6,7 @@
blastp
-query "$query"
#if $db_opts.db_opts_selector == "db":
- -db "$db_opts.database"
+ -db "${db_opts.database.fields.path}"
#else:
-subject "$db_opts.subject"
#end if
@@ -41,13 +41,10 @@
</param><when value="db"><param name="database" type="select" label="Protein BLAST database">
- <!-- The BLAST loc file has three columns:
- column 0 is an identifier (not used),
- column 1 is the caption (show this to the user),
- column 2 is the database path (given to BLAST+) --><options from_file="blastdb_p.loc">
+ <column name="value" index="0"/><column name="name" index="1"/>
- <column name="value" index="2"/>
+ <column name="path" index="2"/></options></param><param name="subject" type="hidden" value="" />
--- a/tools/ncbi_blast_plus/ncbi_blastx_wrapper.xml Tue Feb 01 20:07:17 2011 -0500
+++ b/tools/ncbi_blast_plus/ncbi_blastx_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
@@ -1,4 +1,4 @@
-<tool id="ncbi_blastx_wrapper" name="NCBI BLAST+ blastx" version="0.0.7">
+<tool id="ncbi_blastx_wrapper" name="NCBI BLAST+ blastx" version="0.0.8"><description>Search protein database with translated nucleotide query sequence(s)</description><command>
## The command is a Cheetah template which allows some Python based syntax.
@@ -6,7 +6,7 @@
blastx
-query "$query"
#if $db_opts.db_opts_selector == "db":
- -db "$db_opts.database"
+ -db "${db_opts.database.fields.path}"
#else:
-subject "$db_opts.subject"
#end if
@@ -40,13 +40,10 @@
</param><when value="db"><param name="database" type="select" label="Protein BLAST database">
- <!-- The BLAST loc file has three columns:
- column 0 is an identifier (not used),
- column 1 is the caption (show this to the user),
- column 2 is the database path (given to BLAST+) --><options from_file="blastdb_p.loc">
+ <column name="value" index="0"/><column name="name" index="1"/>
- <column name="value" index="2"/>
+ <column name="path" index="2"/></options></param><param name="subject" type="hidden" value="" />
--- a/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Tue Feb 01 20:07:17 2011 -0500
+++ b/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
@@ -1,4 +1,4 @@
-<tool id="ncbi_tblastn_wrapper" name="NCBI BLAST+ tblastn" version="0.0.7">
+<tool id="ncbi_tblastn_wrapper" name="NCBI BLAST+ tblastn" version="0.0.8"><description>Search translated nucleotide database with protein query sequence(s)</description><command>
## The command is a Cheetah template which allows some Python based syntax.
@@ -6,7 +6,7 @@
tblastn
-query "$query"
#if $db_opts.db_opts_selector == "db":
- -db "$db_opts.database"
+ -db "${db_opts.database.fields.path}"
#else:
-subject "$db_opts.subject"
#end if
@@ -40,13 +40,10 @@
</param><when value="db"><param name="database" type="select" label="Nucleotide BLAST database">
- <!-- The BLAST loc file has three columns:
- column 0 is an identifier (not used here, see legacy megablast wrapper),
- column 1 is the caption (show this to the user),
- column 2 is the database path (given to BLAST+) --><options from_file="blastdb.loc">
+ <column name="value" index="0"/><column name="name" index="1"/>
- <column name="value" index="2"/>
+ <column name="path" index="2"/></options></param><param name="subject" type="hidden" value="" />
--- a/tools/ncbi_blast_plus/ncbi_tblastx_wrapper.xml Tue Feb 01 20:07:17 2011 -0500
+++ b/tools/ncbi_blast_plus/ncbi_tblastx_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
@@ -1,4 +1,4 @@
-<tool id="ncbi_tblastx_wrapper" name="NCBI BLAST+ tblastx" version="0.0.7">
+<tool id="ncbi_tblastx_wrapper" name="NCBI BLAST+ tblastx" version="0.0.8"><description>Search translated nucleotide database with translated nucleotide query sequence(s)</description><command>
## The command is a Cheetah template which allows some Python based syntax.
@@ -6,7 +6,7 @@
tblastx
-query "$query"
#if $db_opts.db_opts_selector == "db":
- -db "$db_opts.database"
+ -db "${db_opts.database.fields.path}"
#else:
-subject "$db_opts.subject"
#end if
@@ -39,13 +39,10 @@
</param><when value="db"><param name="database" type="select" label="Nucleotide BLAST database">
- <!-- The BLAST loc file has three columns:
- column 0 is an identifier (not used here, see legacy megablast wrapper),
- column 1 is the caption (show this to the user),
- column 2 is the database path (given to BLAST+) --><options from_file="blastdb.loc">
+ <column name="value" index="0"/><column name="name" index="1"/>
- <column name="value" index="2"/>
+ <column name="path" index="2"/></options></param><param name="subject" type="hidden" value="" />
http://bitbucket.org/galaxy/galaxy-central/changeset/17c2a47f67e3/
changeset: r4978:17c2a47f67e3
user: peterjc
date: 2011-02-01 11:52:50
summary: Use wrapper script to hide BLAST warnings on stderr (see issue 325)
affected #: 6 files (1.7 KB)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ncbi_blast_plus/hide_stderr.py Tue Feb 01 10:52:50 2011 +0000
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+"""A simple script to redirect stderr to stdout when the return code is zero.
+
+See https://bitbucket.org/galaxy/galaxy-central/issue/325/
+
+Currently Galaxy ignores the return code from command line tools (even if it
+is non-zero which by convention indicates an error) and treats any output on
+stderr as an error (even though by convention stderr is used for errors or
+warnings).
+
+This script runs the given command line, capturing all stdout and stderr in
+memory, and gets the return code. For a zero return code, any stderr (which
+should be warnings only) is added to the stdout. That way Galaxy believes
+everything is fine. For a non-zero return code, we output stdout as is, and
+any stderr, plus the return code to ensure there is some output on stderr.
+That way Galaxy treats this as an error.
+
+Once issue 325 is fixed, this script will not be needed.
+"""
+import sys
+import subprocess
+
+#Sadly passing the list directly to subprocess didn't seem to work.
+words = []
+for w in sys.argv[1:]:
+ if " " in w:
+ words.append('"%s"' % w)
+ else:
+ words.append(w)
+cmd = " ".join(words)
+child = subprocess.Popen(cmd, shell=True,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+#Use .communicate as can get deadlocks with .wait(),
+stdout, stderr = child.communicate()
+return_code = child.returncode
+
+if return_code:
+ sys.stdout.write(stdout)
+ sys.stderr.write(stderr)
+ sys.stderr.write("Return error code %i from command:\n" % return_code)
+ sys.stderr.write("%s\n" % cmd)
+else:
+ sys.stdout.write(stdout)
+ sys.stdout.write(stderr)
--- a/tools/ncbi_blast_plus/ncbi_blastn_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
+++ b/tools/ncbi_blast_plus/ncbi_blastn_wrapper.xml Tue Feb 01 10:52:50 2011 +0000
@@ -1,6 +1,6 @@
<tool id="ncbi_blastn_wrapper" name="NCBI BLAST+ blastn" version="0.0.8"><description>Search nucleotide database with nucleotide query sequence(s)</description>
- <command>
+ <command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
blastn
--- a/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
+++ b/tools/ncbi_blast_plus/ncbi_blastp_wrapper.xml Tue Feb 01 10:52:50 2011 +0000
@@ -1,6 +1,6 @@
<tool id="ncbi_blastp_wrapper" name="NCBI BLAST+ blastp" version="0.0.8"><description>Search protein database with protein query sequence(s)</description>
- <command>
+ <command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
blastp
--- a/tools/ncbi_blast_plus/ncbi_blastx_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
+++ b/tools/ncbi_blast_plus/ncbi_blastx_wrapper.xml Tue Feb 01 10:52:50 2011 +0000
@@ -1,6 +1,6 @@
<tool id="ncbi_blastx_wrapper" name="NCBI BLAST+ blastx" version="0.0.8"><description>Search protein database with translated nucleotide query sequence(s)</description>
- <command>
+ <command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
blastx
--- a/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
+++ b/tools/ncbi_blast_plus/ncbi_tblastn_wrapper.xml Tue Feb 01 10:52:50 2011 +0000
@@ -1,7 +1,7 @@
<tool id="ncbi_tblastn_wrapper" name="NCBI BLAST+ tblastn" version="0.0.8"><description>Search translated nucleotide database with protein query sequence(s)</description>
- <command>
-## The command is a Cheetah template which allows some Python based syntax.
+ <command interpreter="python">hide_stderr.py
+# The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
tblastn
-query "$query"
--- a/tools/ncbi_blast_plus/ncbi_tblastx_wrapper.xml Mon Jan 31 17:13:13 2011 +0000
+++ b/tools/ncbi_blast_plus/ncbi_tblastx_wrapper.xml Tue Feb 01 10:52:50 2011 +0000
@@ -1,6 +1,6 @@
<tool id="ncbi_tblastx_wrapper" name="NCBI BLAST+ tblastx" version="0.0.8"><description>Search translated nucleotide database with translated nucleotide query sequence(s)</description>
- <command>
+ <command interpreter="python">hide_stderr.py
## The command is a Cheetah template which allows some Python based syntax.
## Lines starting hash hash are comments. Galaxy will turn newlines into spaces
tblastx
http://bitbucket.org/galaxy/galaxy-central/changeset/ca4a622b52ce/
changeset: r4979:ca4a622b52ce
user: peterjc
date: 2011-02-01 16:24:45
summary: Avoid using shell=True when we call subprocess to ensure if the Python script is killed, so too is the BLAST process
affected #: 1 file (34 bytes)
--- a/tools/ncbi_blast_plus/hide_stderr.py Tue Feb 01 10:52:50 2011 +0000
+++ b/tools/ncbi_blast_plus/hide_stderr.py Tue Feb 01 15:24:45 2011 +0000
@@ -20,16 +20,14 @@
import sys
import subprocess
-#Sadly passing the list directly to subprocess didn't seem to work.
-words = []
-for w in sys.argv[1:]:
- if " " in w:
- words.append('"%s"' % w)
- else:
- words.append(w)
-cmd = " ".join(words)
-child = subprocess.Popen(cmd, shell=True,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+#Avoid using shell=True when we call subprocess to ensure if the Python
+#script is killed, so too is the BLAST process.
+try:
+ child = subprocess.Popen(sys.argv[1:],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+except Exception, err:
+ sys.stderr.write("Error invoking command:\n%s\n\n%s\n" % (cmd, err))
+ sys.exit(1)
#Use .communicate as can get deadlocks with .wait(),
stdout, stderr = child.communicate()
return_code = child.returncode
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: kanwei: Backend changes to implicitly converted datasets:
by Bitbucket 01 Feb '11
by Bitbucket 01 Feb '11
01 Feb '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/0c1407634eb8/
changeset: r4976:0c1407634eb8
user: kanwei
date: 2011-02-02 02:07:17
summary: Backend changes to implicitly converted datasets:
- Library dataset LDDAs can now be implicitly converted to another format. For this to happen, an HDA is created by copying the LDDA info, and the HDA is then used as the tool input parameter. The implicitly converted dataset table will map the LDDA to the resulting converted output HDA.
- Added set_output_history optional param to tool.execute to specify whether output dataset is added to the current (or specified) history. Defaults to true but is set to false for implicitly converted datasets so that it does not show up as a hidden history item, which show up in features like "extract workflow from history".
Initial pass at UI for adding data library datasets to trackster using the "Select Library, then Select Datasets" paradigm currently also used for adding history datasets. Currently uses browse_library.mako code but this will need to be enhanced for trackster's purposes.
affected #: 12 files (4.1 KB)
--- a/lib/galaxy/datatypes/data.py Tue Feb 01 19:56:05 2011 -0500
+++ b/lib/galaxy/datatypes/data.py Tue Feb 01 20:07:17 2011 -0500
@@ -266,7 +266,7 @@
def find_conversion_destination( self, dataset, accepted_formats, datatypes_registry, **kwd ):
"""Returns ( target_ext, existing converted dataset )"""
return datatypes_registry.find_conversion_destination_for_dataset_by_extensions( dataset, accepted_formats, **kwd )
- def convert_dataset(self, trans, original_dataset, target_type, return_output = False, visible = True, deps=None):
+ def convert_dataset(self, trans, original_dataset, target_type, return_output=False, visible=True, deps=None, set_output_history=True):
"""This function adds a job to the queue to convert a dataset to another type. Returns a message about success/failure."""
converter = trans.app.datatypes_registry.get_converter_by_target_type( original_dataset.ext, target_type )
@@ -277,14 +277,14 @@
#determine input parameter name and add to params
input_name = 'input1'
for key, value in converter.inputs.items():
- if (deps) and (value.name in deps):
+ if deps and value.name in deps:
params[value.name] = deps[value.name]
elif value.type == 'data':
input_name = key
params[input_name] = original_dataset
#Run converter, job is dispatched through Queue
- converted_dataset = converter.execute( trans, incoming = params, set_output_hid = visible )[1]
+ converted_dataset = converter.execute( trans, incoming=params, set_output_hid=visible, set_output_history=set_output_history)[1]
if len(params) > 0:
trans.log_event( "Converter params: %s" % (str(params)), tool_id=converter.id )
if not visible:
--- a/lib/galaxy/model/__init__.py Tue Feb 01 19:56:05 2011 -0500
+++ b/lib/galaxy/model/__init__.py Tue Feb 01 20:07:17 2011 -0500
@@ -742,8 +742,7 @@
pass # No deps
assoc = ImplicitlyConvertedDatasetAssociation( parent=self, file_type=target_ext, metadata_safe=False )
- new_dataset = self.datatype.convert_dataset( trans, self, target_ext, return_output=True, visible=False, deps=deps ).values()[0]
- new_dataset.hid = self.hid
+ new_dataset = self.datatype.convert_dataset( trans, self, target_ext, return_output=True, visible=False, deps=deps, set_output_history=False ).values()[0]
new_dataset.name = self.name
session = trans.sa_session
session.add( new_dataset )
@@ -1326,7 +1325,12 @@
def __init__( self, id = None, parent = None, dataset = None, file_type = None, deleted = False, purged = False, metadata_safe = True ):
self.id = id
self.dataset = dataset
- self.parent = parent
+ if isinstance(parent, HistoryDatasetAssociation):
+ self.parent_hda = parent
+ elif isinstance(parent, LibraryDatasetDatasetAssociation):
+ self.parent_ldda = parent
+ else:
+ raise AttributeError
self.type = file_type
self.deleted = deleted
self.purged = purged
--- a/lib/galaxy/model/mapping.py Tue Feb 01 19:56:05 2011 -0500
+++ b/lib/galaxy/model/mapping.py Tue Feb 01 20:07:17 2011 -0500
@@ -145,6 +145,7 @@
Column( "update_time", DateTime, default=now, onupdate=now ),
Column( "hda_id", Integer, ForeignKey( "history_dataset_association.id" ), index=True, nullable=True ),
Column( "hda_parent_id", Integer, ForeignKey( "history_dataset_association.id" ), index=True ),
+ Column( "ldda_parent_id", Integer, ForeignKey( "library_dataset_dataset_association.id" ), index=True ),
Column( "deleted", Boolean, index=True, default=False ),
Column( "metadata_safe", Boolean, index=True, default=True ),
Column( "type", TrimmedString( 255 ) ) )
@@ -1135,13 +1136,17 @@
user = relation( User ) ) )
assign_mapper( context, ImplicitlyConvertedDatasetAssociation, ImplicitlyConvertedDatasetAssociation.table,
- properties=dict( parent=relation(
- HistoryDatasetAssociation,
- primaryjoin=( ImplicitlyConvertedDatasetAssociation.table.c.hda_parent_id == HistoryDatasetAssociation.table.c.id ) ),
+ properties=dict( parent_hda=relation(
+ HistoryDatasetAssociation,
+ primaryjoin=( ImplicitlyConvertedDatasetAssociation.table.c.hda_parent_id == HistoryDatasetAssociation.table.c.id ) ),
+
+ parent_ldda=relation(
+ LibraryDatasetDatasetAssociation,
+ primaryjoin=( ImplicitlyConvertedDatasetAssociation.table.c.ldda_parent_id == LibraryDatasetDatasetAssociation.table.c.id ) ),
dataset=relation(
- HistoryDatasetAssociation,
- primaryjoin=( ImplicitlyConvertedDatasetAssociation.table.c.hda_id == HistoryDatasetAssociation.table.c.id ) ) ) )
+ HistoryDatasetAssociation,
+ primaryjoin=( ImplicitlyConvertedDatasetAssociation.table.c.hda_id == HistoryDatasetAssociation.table.c.id ) ) ) )
assign_mapper( context, History, History.table,
properties=dict( galaxy_sessions=relation( GalaxySessionToHistoryAssociation ),
@@ -1322,6 +1327,9 @@
HistoryDatasetAssociation,
primaryjoin=( HistoryDatasetAssociation.table.c.copied_from_library_dataset_dataset_association_id == LibraryDatasetDatasetAssociation.table.c.id ),
backref=backref( "copied_from_library_dataset_dataset_association", primaryjoin=( HistoryDatasetAssociation.table.c.copied_from_library_dataset_dataset_association_id == LibraryDatasetDatasetAssociation.table.c.id ), remote_side=[LibraryDatasetDatasetAssociation.table.c.id], uselist=False ) ),
+ implicitly_converted_datasets=relation(
+ ImplicitlyConvertedDatasetAssociation,
+ primaryjoin=( ImplicitlyConvertedDatasetAssociation.table.c.ldda_parent_id == LibraryDatasetDatasetAssociation.table.c.id ) ),
children=relation(
LibraryDatasetDatasetAssociation,
primaryjoin=( LibraryDatasetDatasetAssociation.table.c.parent_id == LibraryDatasetDatasetAssociation.table.c.id ),
--- a/lib/galaxy/tools/__init__.py Tue Feb 01 19:56:05 2011 -0500
+++ b/lib/galaxy/tools/__init__.py Tue Feb 01 20:07:17 2011 -0500
@@ -1215,14 +1215,14 @@
raise Exception( "Unexpected parameter type" )
return args
- def execute( self, trans, incoming={}, set_output_hid=True, history=None ):
+ def execute( self, trans, incoming={}, set_output_hid=True, set_output_history=True, history=None ):
"""
Execute the tool using parameter values in `incoming`. This just
dispatches to the `ToolAction` instance specified by
`self.tool_action`. In general this will create a `Job` that
when run will build the tool's outputs, e.g. `DefaultToolAction`.
"""
- return self.tool_action.execute( self, trans, incoming=incoming, set_output_hid=set_output_hid, history=history )
+ return self.tool_action.execute( self, trans, incoming=incoming, set_output_hid=set_output_hid, set_output_history=set_output_history, history=history )
def params_to_strings( self, params, app ):
return params_to_strings( self.inputs, params, app )
--- a/lib/galaxy/tools/actions/__init__.py Tue Feb 01 19:56:05 2011 -0500
+++ b/lib/galaxy/tools/actions/__init__.py Tue Feb 01 20:07:17 2011 -0500
@@ -1,3 +1,4 @@
+from galaxy.model import LibraryDatasetDatasetAssociation
from galaxy.util.bunch import Bunch
from galaxy.util.odict import odict
from galaxy.tools.parameters import *
@@ -100,7 +101,7 @@
tool.visit_inputs( param_values, visitor )
return input_datasets
- def execute(self, tool, trans, incoming={}, return_job=False, set_output_hid=True, history=None ):
+ def execute(self, tool, trans, incoming={}, return_job=False, set_output_hid=True, set_output_history=True, history=None ):
"""
Executes a tool, creating job and tool outputs, associating them, and
submitting the job to the job queue. If history is not specified, use
@@ -166,11 +167,20 @@
input_ext = 'data'
input_dbkey = incoming.get( "dbkey", "?" )
for name, data in inp_data.items():
- if data:
- input_names.append( 'data %s' % data.hid )
- input_ext = data.ext
- else:
+ if not data:
data = NoneDataset( datatypes_registry = trans.app.datatypes_registry )
+ continue
+
+ # Convert LDDA to an HDA.
+ if isinstance(data, LibraryDatasetDatasetAssociation):
+ data = data.to_history_dataset_association( None )
+ inp_data[name] = data
+
+ else: # HDA
+ if data.hid:
+ input_names.append( 'data %s' % data.hid )
+ input_ext = data.ext
+
if data.dbkey not in [None, '?']:
input_dbkey = data.dbkey
@@ -306,11 +316,12 @@
output.actions.apply_action( data, output_action_params )
# Store all changes to database
trans.sa_session.flush()
- # Add all the top-level (non-child) datasets to the history
+ # Add all the top-level (non-child) datasets to the history unless otherwise specified
for name in out_data.keys():
if name not in child_dataset_names and name not in incoming: #don't add children; or already existing datasets, i.e. async created
data = out_data[ name ]
- history.add_dataset( data, set_hid = set_output_hid )
+ if set_output_history:
+ history.add_dataset( data, set_hid = set_output_hid )
trans.sa_session.add( data )
trans.sa_session.flush()
# Add all the children to their parents
--- a/lib/galaxy/web/base/controller.py Tue Feb 01 19:56:05 2011 -0500
+++ b/lib/galaxy/web/base/controller.py Tue Feb 01 20:07:17 2011 -0500
@@ -164,14 +164,19 @@
# Set tracks.
if 'tracks' in latest_revision.config:
- hda_query = trans.sa_session.query( trans.model.HistoryDatasetAssociation )
for t in visualization.latest_revision.config['tracks']:
dataset_id = t['dataset_id']
+ hda_ldda = t.get('hda_ldda', 'hda')
+ if hda_ldda == "hda":
+ dataset = self.get_dataset( trans, dataset_id, check_ownership=False, check_accessible=True )
+ else:
+ dataset = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id(dataset_id) )
+
try:
prefs = t['prefs']
except KeyError:
prefs = {}
- dataset = hda_query.get( dataset_id )
+
track_type, _ = dataset.datatype.get_track_type()
track_data_provider_class = get_data_provider( original_dataset=dataset )
track_data_provider = track_data_provider_class( original_dataset=dataset )
@@ -179,6 +184,7 @@
tracks.append( {
"track_type": track_type,
"name": t['name'],
+ "hda_ldda": t.get("hda_ldda", "hda"),
"dataset_id": trans.security.encode_id( dataset.id ),
"prefs": prefs,
"filters": track_data_provider.get_filters(),
--- a/lib/galaxy/web/controllers/tracks.py Tue Feb 01 19:56:05 2011 -0500
+++ b/lib/galaxy/web/controllers/tracks.py Tue Feb 01 20:07:17 2011 -0500
@@ -9,6 +9,7 @@
from galaxy import model
from galaxy.util.json import to_json_string, from_json_string
from galaxy.web.base.controller import *
+from galaxy.web.controllers.library import LibraryListGrid
from galaxy.web.framework import simplejson
from galaxy.web.framework.helpers import time_ago, grids
from galaxy.util.bunch import Bunch
@@ -36,8 +37,8 @@
# Provide link to list all datasets in history that have a given dbkey.
# Right now, only dbkey needs to be passed through, but pass through
# all for now since it's cleaner.
- d = dict( action='list_history_datasets', show_item_checkboxes=True )
- d[ "f-history" ] = history.id
+ d = dict( action=grid.datasets_action, show_item_checkboxes=True )
+ d[ grid.datasets_param ] = trans.security.encode_id( history.id )
for filter, value in grid.cur_filter_dict.iteritems():
d[ "f-" + filter ] = value
return d
@@ -56,6 +57,8 @@
model_class = model.History
template='/tracks/history_select_grid.mako'
default_sort_key = "-update_time"
+ datasets_action = 'list_history_datasets'
+ datasets_param = "f-history"
columns = [
NameColumn( "History Name", key="name", filterable="standard" ),
grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
@@ -67,6 +70,24 @@
def apply_query_filter( self, trans, query, **kwargs ):
return query.filter_by( user=trans.user, purged=False, deleted=False, importing=False )
+class LibrarySelectionGrid( LibraryListGrid ):
+ """
+ Grid enables user to select a Library, which is then used to display
+ datasets from the history.
+ """
+ title = "Add Track: Select Library"
+ template='/tracks/history_select_grid.mako'
+ model_class = model.Library
+ datasets_action = 'list_library_datasets'
+ datasets_param = "f-library"
+ columns = [
+ NameColumn( "Library Name", key="name", filterable="standard" ),
+ grids.GridColumn( "Description", key="description" )
+ ]
+ num_rows_per_page = 10
+ use_async = True
+ use_paging = True
+
class DbKeyColumn( grids.GridColumn ):
""" Column for filtering by and displaying dataset dbkey. """
def filter( self, trans, user, query, dbkey ):
@@ -78,7 +99,7 @@
class HistoryColumn( grids.GridColumn ):
""" Column for filtering by history id. """
def filter( self, trans, user, query, history_id ):
- return query.filter( model.History.id==history_id )
+ return query.filter( model.History.id==trans.security.decode_id(history_id) )
class HistoryDatasetsSelectionGrid( grids.Grid ):
# Grid definition.
@@ -95,7 +116,7 @@
grids.TextColumn( "Name", key="name", model_class=model.HistoryDatasetAssociation ),
grids.TextColumn( "Filetype", key="extension", model_class=model.HistoryDatasetAssociation ),
HistoryColumn( "History", key="history", visible=False ),
- DbKeyColumn( "Dbkey", key="dbkey", model_class=model.HistoryDatasetAssociation, visible=False )
+ DbKeyColumn( "Dbkey", key="dbkey", model_class=model.HistoryDatasetAssociation, visible=True, sortable=False )
]
columns.append(
grids.MulticolFilterColumn( "Search", cols_to_filter=[ columns[0], columns[1] ],
@@ -103,7 +124,7 @@
)
def build_initial_query( self, trans, **kwargs ):
- return trans.sa_session.query( self.model_class ).join( model.History.table).join( model.Dataset.table )
+ return trans.sa_session.query( self.model_class ).join( model.History.table ).join( model.Dataset.table )
def apply_query_filter( self, trans, query, **kwargs ):
if self.available_tracks is None:
self.available_tracks = trans.app.datatypes_registry.get_available_tracks()
@@ -111,42 +132,6 @@
.filter( model.Dataset.state == model.Dataset.states.OK ) \
.filter( model.HistoryDatasetAssociation.deleted == False ) \
.filter( model.HistoryDatasetAssociation.visible == True )
-
-# TODO: not currently used. Do we want to keep this?
-class DatasetSelectionGrid( grids.Grid ):
- """ Lists all user datasets that can be added to a visualization. """
-
- # Grid definition.
- available_tracks = None
- title = "Add Tracks"
- template = "/tracks/add_tracks.mako"
- async_template = "/page/select_items_grid_async.mako"
- model_class = model.HistoryDatasetAssociation
- default_filter = { "deleted" : "False" , "shared" : "All" }
- default_sort_key = "name"
- use_async = True
- use_paging = False
- columns = [
- grids.TextColumn( "Name", key="name", model_class=model.HistoryDatasetAssociation ),
- grids.TextColumn( "Filetype", key="extension", model_class=model.HistoryDatasetAssociation ),
- DbKeyColumn( "Dbkey", key="dbkey", model_class=model.HistoryDatasetAssociation, visible=False )
- ]
- columns.append(
- grids.MulticolFilterColumn( "Search", cols_to_filter=[ columns[0], columns[1] ],
- key="free-text-search", visible=False, filterable="standard" )
- )
-
- def build_initial_query( self, trans, **kwargs ):
- return trans.sa_session.query( self.model_class ).join( model.History.table).join( model.Dataset.table )
- def apply_query_filter( self, trans, query, **kwargs ):
- if self.available_tracks is None:
- self.available_tracks = trans.app.datatypes_registry.get_available_tracks()
- return query.filter( model.History.user == trans.user ) \
- .filter( model.HistoryDatasetAssociation.extension.in_(self.available_tracks) ) \
- .filter( model.Dataset.state == model.Dataset.states.OK ) \
- .filter( model.History.deleted == False ) \
- .filter( model.HistoryDatasetAssociation.deleted == False ) \
- .filter( model.HistoryDatasetAssociation.visible == True )
class TracksterSelectionGrid( grids.Grid ):
# Grid definition.
@@ -178,9 +163,9 @@
datasets in the current history, and display of the resulting browser.
"""
+ libraries_grid = LibrarySelectionGrid()
histories_grid = HistorySelectionGrid()
history_datasets_grid = HistoryDatasetsSelectionGrid()
- data_grid = DatasetSelectionGrid()
tracks_grid = TracksterSelectionGrid()
#
@@ -216,8 +201,13 @@
@web.json
@web.require_login()
- def add_track_async(self, trans, id):
- dataset = self.get_dataset( trans, id, check_ownership=False, check_accessible=True )
+ def add_track_async(self, trans, hda_id=None, ldda_id=None):
+ if hda_id:
+ hda_ldda = "hda"
+ dataset = self.get_dataset( trans, hda_id, check_ownership=False, check_accessible=True )
+ elif ldda_id:
+ hda_ldda = "ldda"
+ dataset = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( ldda_id ) )
track_type, _ = dataset.datatype.get_track_type()
track_data_provider_class = get_data_provider( original_dataset=dataset )
track_data_provider = track_data_provider_class( original_dataset=dataset )
@@ -225,6 +215,7 @@
track = {
"track_type": track_type,
"name": dataset.name,
+ "hda_ldda": hda_ldda,
"dataset_id": trans.security.encode_id( dataset.id ),
"prefs": {},
"filters": track_data_provider.get_filters(),
@@ -371,7 +362,7 @@
return msg
@web.json
- def converted_datasets_state( self, trans, dataset_id, chrom=None, low=None, high=None ):
+ def converted_datasets_state( self, trans, hda_ldda, dataset_id, chrom=None, low=None, high=None ):
"""
Returns state of dataset's converted datasets. If a genome window is
specified, method checks whether dataset has data in the window.
@@ -379,7 +370,10 @@
# TODO: this code is copied from data() -- should refactor.
# Dataset check.
- dataset = self.get_dataset( trans, dataset_id )
+ if hda_ldda == "hda":
+ dataset = self.get_dataset( trans, dataset_id )
+ else:
+ dataset = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( dataset_id ) )
msg = self._check_dataset_state( trans, dataset )
if msg:
return msg
@@ -402,7 +396,7 @@
return messages.DATA
@web.json
- def data( self, trans, dataset_id, chrom, low, high, **kwargs ):
+ def data( self, trans, hda_ldda, dataset_id, chrom, low, high, **kwargs ):
"""
Called by the browser to request a block of data
"""
@@ -412,7 +406,10 @@
return messages.NO_DATA
# Dataset check.
- dataset = self.get_dataset( trans, dataset_id )
+ if hda_ldda == "hda":
+ dataset = self.get_dataset( trans, dataset_id )
+ else:
+ dataset = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( dataset_id ) )
msg = self._check_dataset_state( trans, dataset )
if msg:
return msg
@@ -491,11 +488,12 @@
# Tracks from payload
tracks = []
for track in decoded_payload['tracks']:
- tracks.append( { "dataset_id": str( trans.security.decode_id( track['dataset_id']) ),
+ tracks.append( { "dataset_id": track['dataset_id'],
+ "hda_ldda": track.get('hda_ldda', "hda"),
"name": track['name'],
"track_type": track['track_type'],
"prefs": track['prefs'],
- "is_child": track['is_child']
+ "is_child": track.get('is_child', False)
} )
# Viewport from payload
if 'viewport' in decoded_payload:
@@ -511,6 +509,32 @@
return trans.security.encode_id(vis.id)
@web.expose
+ @web.require_login( "see all available libraries" )
+ def list_libraries( self, trans, **kwargs ):
+ """List all libraries that can be used for selecting datasets."""
+
+ # Render the list view
+ return self.libraries_grid( trans, **kwargs )
+
+ @web.expose
+ @web.require_login( "see a library's datasets that can added to this visualization" )
+ def list_library_datasets( self, trans, **kwargs ):
+ """List a library's datasets that can be added to a visualization."""
+
+ library = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( kwargs.get('f-library') ) )
+ return trans.fill_template( '/library/common/browse_library.mako',
+ cntrller="library",
+ use_panels=False,
+ library=library,
+ created_ldda_ids='',
+ hidden_folder_ids='',
+ show_deleted=False,
+ comptypes=[],
+ current_user_roles=trans.get_current_user_roles(),
+ message='',
+ status="done" )
+
+ @web.expose
@web.require_login( "see all available histories" )
def list_histories( self, trans, **kwargs ):
"""List all histories that can be used for selecting datasets."""
@@ -654,6 +678,12 @@
output_dataset = joda.dataset
return self.add_track_async( trans, output_dataset.id )
+
+ @web.expose
+ def woot( self, trans, ldda_id, target_type ):
+ ldda = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( ldda_id ) )
+ converted_dataset = ldda.get_converted_dataset( trans, target_type )
+ raise converted_dataset
#
# Helper methods.
--- a/static/scripts/packed/trackster.js Tue Feb 01 19:56:05 2011 -0500
+++ b/static/scripts/packed/trackster.js Tue Feb 01 20:07:17 2011 -0500
@@ -1,1 +1,1 @@
-CanvasRenderingContext2D.prototype.dashedLine=function(c,i,b,h,f){if(f==undefined){f=4}var e=b-c;var d=h-i;var g=Math.floor(Math.sqrt(e*e+d*d)/f);var k=e/g;var j=d/g;for(var a=0;a<g;a++,c+=k,i+=j){if(a%2!=0){continue}this.fillRect(c,i,f,1)}};function sortable(a,b){a.bind("drag",{handle:b,relative:true},function(h,j){var g=$(this).parent();var f=g.children();for(var c=0;c<f.length;c++){if(j.offsetY<$(f.get(c)).position().top){break}}if(c==f.length){if(this!=f.get(c-1)){g.append(this)}}else{if(this!=f.get(c)){$(this).insertBefore(f.get(c))}}})}var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DEFAULT_DATA_QUERY_WAIT=5000,CONNECTOR_COLOR="#ccc",DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_CANNOT_RUN_TOOL="Tool cannot be rerun: ",DATA_LOADING="Loading data...",DATA_OK="Ready for display",FILTERABLE_CLASS="filterable",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=5,CACHED_DATA=5,DUMMY_CANVAS=document.createElement("canvas"),RIGHT_STRAND,LEFT_STRAND;if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(DUMMY_CANVAS)}CONTEXT=DUMMY_CANVAS.getContext("2d");PX_PER_CHAR=CONTEXT.measureText("A").width;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.move_key_to_end(b,a)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},move_key_to_end:function(b,a){this.key_ary.splice(a,1);this.key_ary.push(b)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var DataCache=function(a){Cache.call(this,a)};$.extend(DataCache.prototype,Cache.prototype,{get_data:function(g,b,e){var h=this.get(this.gen_key(g,b,e));if(h){return h}var j,f,a,d,e,h;for(var c=0;c<this.key_ary.length;c++){j=this.key_ary[c];f=this.split_key(j);a=f[0];d=f[1];if(g>=a&&b<=d){h=this.obj_cache[j];if(h.dataset_type!=="summary_tree"&&h.extra_info!=="no_detail"){this.move_key_to_end(j,c);return h}}}return undefined},set_data:function(b,c,d,a){return this.set(this.gen_key(b,c,d),a)},gen_key:function(a,c,d){var b=a+"_"+c;return b},split_key:function(a){return a.split("_")}});var View=function(a,d,c,b,e){this.container=a;this.chrom=null;this.vis_id=c;this.dbkey=b;this.title=d;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(e);this.reset()};$.extend(View.prototype,{init:function(d){var c=this.container,a=this;this.top_container=$("<div/>").addClass("top-container").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(c);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(f){if(f.type==="focusout"||(f.keyCode||f.which)===13||(f.keyCode||f.which)===27){if((f.keyCode||f.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a id='zoom-out' />").click(function(){a.zoom_out();a.redraw()}).appendTo(this.chrom_form);this.zi_link=$("<a id='zoom-in' />").click(function(){a.zoom_in();a.redraw()}).appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(f){if(f.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=f.chrom_info;var j='<option value="">Select Chrom/Contig</option>';for(var h=0,e=a.chrom_data.length;h<e;h++){var g=a.chrom_data[h].chrom;j+='<option value="'+g+'">'+g+"</option>"}a.chrom_select.html(j);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())});if(d){d()}},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("click",function(f){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(f){a.zoom_in(f.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(f,g){this.current_x=g.offsetX}).bind("drag",function(f,h){var i=h.offsetX-this.current_x;this.current_x=h.offsetX;var g=Math.round(i/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-g)});this.overview_close.bind("click",function(){for(var f=0,e=a.tracks.length;f<e;f++){a.tracks[f].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("dragstart",function(f,g){g.original_low=a.low;g.current_height=f.clientY;g.current_x=g.offsetX;g.enable_pan=(f.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(h,j){if(!j.enable_pan){return}var f=$(this);var k=j.offsetX-j.current_x;var g=f.scrollTop()-(h.clientY-j.current_height);console.log(g);f.scrollTop(g);j.current_height=h.clientY;j.current_x=j.offsetX;var i=Math.round(k/a.viewport_container.width()*(a.high-a.low));a.move_delta(i)});this.top_labeltrack.bind("dragstart",function(f,g){return $("<div />").css({height:a.content_div.height()+a.top_labeltrack.height()+a.nav_labeltrack.height(),top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j,k){$(k.proxy).css({left:Math.min(j.pageX,k.startX),width:Math.abs(j.pageX-k.startX)});var g=Math.min(j.pageX,k.startX)-a.container.offset().left,f=Math.max(j.pageX,k.startX)-a.container.offset().left,i=(a.high-a.low),h=a.viewport_container.width();a.update_location(Math.round(g/h*i)+a.low,Math.round(f/h*i)+a.low)}).bind("dragend",function(k,l){var g=Math.min(k.pageX,l.startX),f=Math.max(k.pageX,l.startX),i=(a.high-a.low),h=a.viewport_container.width(),j=a.low;a.low=Math.round(g/h*i)+j;a.high=Math.round(f/h*i)+j;$(l.proxy).remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack));$(window).bind("resize",function(){a.resize_window()});$(document).bind("redraw",function(){a.redraw()});this.reset();$(window).trigger("resize")},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(e,b,g){var d=this;var f=$.grep(d.chrom_data,function(j,k){return j.chrom===e})[0];if(f===undefined){return}if(e!==d.chrom){d.chrom=e;if(!d.chrom){d.intro_div.show()}else{d.intro_div.hide()}d.chrom_select.val(d.chrom);d.max_high=f.len;d.reset();d.redraw(true);for(var h=0,a=d.tracks.length;h<a;h++){var c=d.tracks[h];if(c.init){c.init()}}}if(b!==undefined&&g!==undefined){d.low=Math.max(b,0);d.high=Math.min(g,d.max_high)}d.reset_overview();d.redraw()},go_to:function(f){var j=this,a,d,b=f.split(":"),h=b[0],i=b[1];if(i!==undefined){try{var g=i.split("-");a=parseInt(g[0].replace(/,/g,""),10);d=parseInt(g[1].replace(/,/g,""),10)}catch(c){return false}}j.change_chrom(h,a,d)},move_fraction:function(c){var a=this;var b=a.high-a.low;this.move_delta(c*b)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);sortable(a.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var e=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left:a,width:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Tool=function(a,b){this.name=a;this.params=b};$.extend(Tool.prototype,{get_param_values_dict:function(){var b={};for(var a=0;a<this.params.length;a++){var c=this.params[a];b[c.name]=c.value}return b},get_param_values:function(){var b=[];for(var a=0;a<this.params.length;a++){b[a]=this.params[a].value}return b}});var NumberToolParameter=function(c,b,e,a,d){this.name=c;this.label=b;this.min=e;this.max=a;this.value=d};var get_tool_from_dict=function(f){if(obj_length(f)==0){return undefined}var b=f.name;var l=f.params;var c=Array();for(var e=0;e<l.length;e++){var g=l[e];var a=g.name,k=g.label,h=g.type,d=g.min,j=g.max,m=g.value;c[c.length]=new NumberToolParameter(a,k,d,j,m)}return new Tool(b,c)};var Filter=function(b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.slider_min=Number.MAX_VALUE;this.slider_max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values",[this.slider_min,this.slider_max])}}});var get_filters_from_dict=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e=="int"||e=="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var Track=function(b,a,e,c,d){this.name=b;this.view=a;this.parent_element=e;this.data_url=(c?c:default_data_url);this.data_query_wait=(d?d:DEFAULT_DATA_QUERY_WAIT);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};$.extend(Track.prototype,{init:function(){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(!a.dataset_id){return}$.getJSON(this.dataset_check_url,{dataset_id:a.dataset_id,chrom:a.view.chrom,low:a.view.max_low,high:a.view.max_high},function(b){if(!b||b==="error"||b.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(b.message){var d=a.view.tracks.indexOf(a);var c=$(" <a href='javascript:void(0);'></a>").attr("id",d+"_error");c.text("View error");$("#"+d+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+b.message+"</pre>",{Close:hide_modal})});a.content_div.append(c)}}else{if(b==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(b==="no data"||(b.data!==undefined&&(b.data===null||b.data.length===0))){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(b==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},a.data_query_wait)}else{if(b==="data"){a.content_div.text(DATA_OK);if(a.view.chrom){a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;a.predraw_init();a.draw()}}}}}}})},predraw_init:function(){},restore_prefs:function(a){var b=this;$.each(a,function(c,d){if(d!==undefined){b.prefs[c]=d}})},update_name:function(a){this.old_name=this.name;this.name=a;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var TiledTrack=function(g,d,s){var o=this,j=o.view;this.filters=(g!==undefined?get_filters_from_dict(g):[]);this.tool=(d!==undefined?get_tool_from_dict(d):undefined);this.parent_track=s;this.child_tracks=[];if(o.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}this.filtering_div=$("<div/>").addClass("track-filters").hide();this.header_div.after(this.filtering_div);this.filtering_div.bind("drag",function(i){i.stopPropagation()}).bind("dblclick",function(i){i.stopPropagation()});var t=$("<table class='filters'>").appendTo(this.filtering_div);$.each(this.filters,function(w,z){var v=$("<tr>").appendTo(t);var y=$("<th class='filter-info'>").appendTo(v);var u=$("<span class='name'>").appendTo(y);u.text(z.name+" ");var i=$("<span class='values'>").appendTo(y);var x=$("<td>").appendTo(v);z.control_element=$("<div id='"+z.name+"-filter-control' style='width: 200px; position: relative'>").appendTo(x);z.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(B,C){var A=C.values;i.text("["+A[0]+"-"+A[1]+"]");z.low=A[0];z.high=A[1];o.draw(true)},change:function(A,B){z.control_element.slider("option","slide").call(z.control_element,A,B)}});z.slider=z.control_element;z.slider_label=i});if(this.tool){this.dynamic_tool_div=$("<div/>").addClass("dynamic-tool").hide();this.header_div.after(this.dynamic_tool_div);this.dynamic_tool_div.bind("drag",function(i){i.stopPropagation()}).bind("click",function(i){i.stopPropagation()}).bind("dblclick",function(i){i.stopPropagation()});var l=$("<div class='tool-name'>").appendTo(this.dynamic_tool_div).text(this.tool.name);var e=this.tool.params;var o=this;$.each(this.tool.params,function(A,v){var y=$("<div>").addClass("param-row").appendTo(o.dynamic_tool_div);var x=$("<div>").addClass("slider-label").appendTo(y);var C=$("<span class='param-name'>").text(v.label+" ").appendTo(x);var w=$("<span/>").text(v.value);var z=$("<span class='param-value'>").appendTo(x).append("[").append(w).append("]");var B=$("<div/>").addClass("slider").appendTo(y);var i=$("<div id='"+v.name+"-param-control'>").appendTo(B);var u=(v.max<=1?0.01:(v.max<=1000?1:5));i.slider({min:v.min,max:v.max,step:u,value:v.value,slide:function(D,F){var E=F.value;v.value=E;if(0<E&&E<1){E=parseFloat(E).toFixed(2)}w.text(E)},change:function(D,E){v.value=E.value}});z.click(function(){var F=w,E=F.text(),D=(v.max<=1?4:v.max.length);F.text("");$("<input type='text'/>").attr("size",D).attr("maxlength",D).attr("value",E).appendTo(F).focus().select().click(function(G){G.stopPropagation()}).blur(function(){$(this).remove();F.text(E)}).keyup(function(I){if(I.keyCode===27){$(this).trigger("blur")}else{if(I.keyCode===13){var G=$(this),H=parseFloat(G.val());if(isNaN(H)||H>v.max||H<v.min){alert("Parameter value must be in the range ["+v.min+"-"+v.max+"]");return $(this)}F.text(H);i.slider("value",H);v.value=H}}})});$("<div style='clear: both;'/>").appendTo(y)});var b=$("<div>").addClass("param-row").appendTo(this.dynamic_tool_div);var n=$("<input type='submit'>").attr("value","Run").appendTo(b);var o=this;n.click(function(){o.run_tool()})}o.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();o.container_div.append(o.child_tracks_container);if(o.display_modes!==undefined){if(o.mode_div===undefined){o.mode_div=$("<div class='right-float menubutton popup' />").appendTo(o.header_div);var m=o.display_modes[0];o.mode=m;o.mode_div.text(m);var a=function(i){o.mode_div.text(i);o.mode=i;o.tile_cache.clear();o.draw()};var f={};for(var q=0,r=o.display_modes.length;q<r;q++){var k=o.display_modes[q];f[k]=function(i){return function(){a(i)}}(k)}make_popupmenu(o.mode_div,f)}else{o.mode_div.hide()}}var h={};h["Edit configuration"]=function(){var v=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},i=function(){o.update_options(o.track_id);hide_modal();$(window).unbind("keypress.check_enter_esc")},u=function(w){if((w.keyCode||w.which)===27){v()}else{if((w.keyCode||w.which)===13){i()}}};$(window).bind("keypress.check_enter_esc",u);show_modal("Configure Track",o.gen_options(o.track_id),{Cancel:v,OK:i})};h["Set as overview"]=function(){j.overview_viewport.find("canvas").remove();o.is_overview=true;o.set_overview();for(var i in j.tracks){if(j.tracks[i]!==o){j.tracks[i].is_overview=false}}};if(o.filters.length>0){h["Show filters"]=function(){var i;if(!o.filtering_div.is(":visible")){i="Hide filters";o.filters_visible=true}else{i="Show filters";o.filters_visible=false}o.filtering_div.toggle()}}if(o.tool){h["Toggle Tool"]=function(){var i;if(!o.dynamic_tool_div.is(":visible")){i="Hide dynamic tool";o.update_name(o.name+o.tool_region_and_parameters_str())}else{i="Show dynamic tool";o.revert_name()}o.dynamic_tool_div.toggle()}}var c=j;var p=function(){$("#no-tracks").show()};if(this.parent_track){c=this.parent_track;p=function(){}}h.Remove=function(){c.remove_track(o);if(c.num_tracks===0){p()}};o.popup_menu=make_popupmenu(o.name_div,h)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(a){var m=this.view.low,g=this.view.high,j=g-m,f=this.view.resolution;var p=$("<div style='position: relative;'></div>"),q=this.content_div.width()/j;this.content_div.append(p);this.max_height=0;var b=Math.floor(m/f/DENSITY);var l={};while((b*DENSITY*f)<g){var n=this.content_div.width()+"_"+q+"_"+b;var e=this.tile_cache.get(n);if(!a&&e){var k=b*DENSITY*f;var d=(k-m)*q;if(this.left_offset){d-=this.left_offset}e.css({left:d});this.show_tile(e,p)}else{this.delayed_draw(this,n,m,g,b,f,p,q,l)}b+=1}var c=this;var o=setInterval(function(){if(obj_length(l)===0){if(c.content_div.children().length>1){c.content_div.children(":first").remove()}for(var i=0;i<c.filters.length;i++){c.filters[i].update_ui_elt()}clearInterval(o)}},50);for(var h=0;h<this.child_tracks.length;h++){this.child_tracks[h].draw(a)}},delayed_draw:function(c,h,g,e,b,d,i,j,f){var a=setTimeout(function(){if(g<=c.view.high&&e>=c.view.low){var k=c.draw_tile(d,b,i,j);if(k){if(!c.initial_canvas&&!window.G_vmlCanvasManager){c.initial_canvas=$(k).clone();var n=k.get(0).getContext("2d");var l=c.initial_canvas.get(0).getContext("2d");var m=n.getImageData(0,0,n.canvas.width,n.canvas.height);l.putImageData(m,0,0);c.set_overview()}c.tile_cache.set(h,k);c.show_tile(k,i)}}delete f[a]},50);f[a]=true},show_tile:function(a,c){var b=this;c.append(a);b.max_height=Math.max(b.max_height,a.height());b.content_div.css("height",b.max_height+"px");if(b.hidden){return}if(a.hasClass(FILTERABLE_CLASS)){show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters");if(b.filters_visible){b.filtering_div.show()}}else{show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false);b.filtering_div.hide()}},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")},run_tool:function(){var b={dataset_id:this.original_dataset_id,chrom:this.view.chrom,low:this.view.low,high:this.view.high,tool_id:this.tool.name};$.extend(b,this.tool.get_param_values_dict());var d=this,c=b.tool_id+d.tool_region_and_parameters_str(b.chrom,b.low,b.high),e;if(d.track_type=="FeatureTrack"){e=new ToolDataFeatureTrack(c,view,undefined,{},{},d)}this.add_track(e);e.content_div.text("Starting job.");view.has_changes=true;var a=function(){$.getJSON(run_tool_url,b,function(f){if(f=="no converter"){e.container_div.addClass("error");e.content_div.text(DATA_NOCONVERTER)}else{if(f.error){e.container_div.addClass("error");e.content_div.text(DATA_CANNOT_RUN_TOOL+f.message)}else{if(f=="pending"){e.container_div.addClass("pending");e.content_div.text("Converting input data so that it can be easily reused.");setTimeout(a,2000)}else{e.dataset_id=f.dataset_id;e.content_div.text("Running job.");e.init()}}}})};a()},tool_region_and_parameters_str:function(c,a,d){var b=this,e=(c!==undefined&&a!==undefined&&d!==undefined?c+":"+a+"-"+d:"all");return" - region=["+e+"], parameters=["+b.tool.get_param_values().join(", ")+"]"},add_track:function(a){a.track_id=this.track_id+"_"+this.child_tracks.length;a.container_div.attr("id","track_"+a.track_id);this.child_tracks_container.append(a.container_div);sortable(a.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(a)},remove_track:function(a){a.container_div.fadeOut("slow",function(){$(this).remove()})}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.data_queue={};this.data_cache=new DataCache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,j=f+"_"+b;var e=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(e)}e=$(e);var n=e.get(0).getContext("2d");if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o),i=Math.round(o/2);n.fillText(m[h],a+this.left_offset+i,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.min_height_px=12;this.max_height_px=400;this.height_px=80;this.dataset_id=a;this.original_dataset_id=a;this.data_cache=new DataCache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode};this.restore_prefs(c);(function(e){var h=false;var g=false;var f=$("<div class='track-resize'>");$(e.container_div).hover(function(){h=true;f.show()},function(){h=false;if(!g){f.hide()}});f.hide().bind("dragstart",function(i,j){g=true;j.original_height=$(e.content_div).height()}).bind("drag",function(j,k){var i=Math.min(Math.max(k.original_height+k.deltaY,e.min_height_px),e.max_height_px);$(e.content_div).css("height",i);e.height_px=i;e.draw(true)}).bind("dragend",function(i,j){e.tile_cache.clear();g=false;if(!h){f.hide()}}).appendTo(e.container_div)})(this)};$.extend(LineTrack.prototype,TiledTrack.prototype,{predraw_init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;$.getJSON(a.data_url,{stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");var e=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=e.min;a.prefs.max_value=e.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=e.total_frequency;a.container_div.find(".yaxislabel").remove();var f=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"24px",left:"10px"});d.prependTo(a.container_div);f.css({position:"absolute",bottom:"2px",left:"10px"});f.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:this.data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){var h=g.data;c.data_cache.set(e,h);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(o,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*o,a=DENSITY*o,x=o+"_"+r;var b=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(b)}b=$(b);if(this.data_cache.get(x)===undefined){this.get_data(o,r);return}var v=this.data_cache.get(x);if(!v){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var n=b.get(0).getContext("2d"),j=false,k=this.prefs.min_value,g=this.prefs.max_value,m=this.vertical_range,t=this.total_frequency,d=this.height_px,l=this.mode;var w=Math.round(d+k/m*d);n.beginPath();n.moveTo(0,w);n.lineTo(a*e,w);n.fillStyle="#aaa";n.stroke();n.beginPath();n.fillStyle=this.prefs.color;var u,h,f;if(v.length>1){f=Math.ceil((v[1][0]-v[0][0])*e)}else{f=10}for(var p=0,q=v.length;p<q;p++){u=Math.round((v[p][0]-s)*e);h=v[p][1];if(h===null){if(j&&l==="Filled"){n.lineTo(u,d)}j=false;continue}if(h<k){h=k}else{if(h>g){h=g}}if(l==="Histogram"){h=Math.round(h/m*d);n.fillRect(u,w,f,-h)}else{if(l==="Intensity"){h=255-Math.floor((h-k)/m*255);n.fillStyle="rgb("+h+","+h+","+h+")";n.fillRect(u,0,f,d)}else{h=Math.round(d-(h-k)/m*d);if(j){n.lineTo(u,h)}else{j=true;if(l==="Filled"){n.moveTo(u,d);n.lineTo(u,h)}else{n.moveTo(u,h)}}}}}if(l==="Filled"){if(j){n.lineTo(u,w);n.lineTo(0,w)}n.fill()}else{n.stroke()}c.append(b);return b},gen_options:function(m){var a=$("<div />").addClass("form-row");var e="track_"+m+"_color",b=$("<label />").attr("for",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+m+"_minval",l=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),k=$("<input></input>").attr("id",h).val(d),j="track_"+m+"_maxval",g=$("<label></label>").attr("for",j).text("Max value:"),i=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",j).val(i);return a.append(l).append(k).append(g).append(f).append(b).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_color").val();if(a!==this.prefs.min_value||c!==this.prefs.max_value||b!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(c);this.prefs.color=b;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(f,c,a,e,g,d,b){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,f,c,c.viewport_container);TiledTrack.call(this,g,d,b);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.original_dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new DataCache(20);this.left_offset=200;this.prefs={block_color:"#444",label_color:"black",show_counts:true};this.restore_prefs(e)};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(b.data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set_data(a,d,b.mode,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,b,p){var r=this.inc_slots[a];if(!r||(r.mode!==p)){r={};r.w_scale=a;r.mode=p;this.inc_slots[a]=r;this.s_e_by_tile[a]={}}var l=r.w_scale,x=[],y=[],j=0,n=this.view.max_low;for(var v=0,w=h.length;v<w;v++){var g=h[v],k=g[0];if(r[k]!==undefined){j=Math.max(j,r[k]);y.push(r[k])}else{x.push(v)}}var q=this.s_e_by_tile[a];var m=function(D,E){var C;for(var B=0,F;B<=MAX_FEATURE_DEPTH;B++){C=true;F=q[B];if(F!==undefined){for(var z=0,A=F.length;z<A;z++){var i=F[z];if(E>i[0]&&D<i[1]){C=false;break}}}if(C){break}}if(C){return B}else{return -1}};for(var v=0,w=x.length;v<w;v++){var g=h[x[v]],k=g[0],t=g[1],c=g[2],o=g[3],d=Math.floor((t-n)*l),f=Math.ceil((c-n)*l),u=CONTEXT.measureText(o).width,e;if(o!==undefined&&!b){if(d-u<0){f+=u;e="left"}else{d-=u;e="right"}}var s=m(d,f);if(s<0){}if(s>=0){slot=q[s];if(slot===undefined){slot=q[s]=[]}slot.push([d,f]);r[k]=s;j=Math.max(j,s)}else{console.log("WARNING: not displaying feature")}}return j},rect_or_text:function(r,l,u,b,q,j,g,f){r.textAlign="center";var d=0,s=0,p=Math.round(l/2);for(var m=0,t=j.length;m<t;m++){var k=j[m],e="MIDNSHP=X"[k[0]],n=k[1];if(e==="H"||e==="S"){d-=n}var h=q+d,x=Math.floor(Math.max(0,(h-u)*l)),i=Math.floor(Math.max(0,(h+n-u)*l));switch(e){case"H":break;case"S":case"M":case"=":var o=g.slice(s,s+n);if((this.mode==="Pack"||this.mode==="Auto")&&g!==undefined&&l>PX_PER_CHAR){r.fillStyle=this.prefs.block_color;r.fillRect(x+this.left_offset,f+1,i-x,9);r.fillStyle=CONNECTOR_COLOR;for(var v=0,a=o.length;v<a;v++){if(h+v>=u&&h+v<=b){var w=Math.floor(Math.max(0,(h+v-u)*l));r.fillText(o[v],w+this.left_offset+p,f+9)}}}else{r.fillStyle=this.prefs.block_color;r.fillRect(x+this.left_offset,f+(this.mode!="Dense"?4:5),i-x,(this.mode!="Dense"?3:1))}s+=n;break;case"N":r.fillStyle=CONNECTOR_COLOR;r.fillRect(x+this.left_offset,f+5,i-x,1);break;case"D":r.fillStyle="red";r.fillRect(x+this.left_offset,f+4,i-x,3);break;case"P":break;case"I":s+=n;break;case"X":s+=n;break}d+=n}},draw_tile:function(ad,n,r,ar){var L=n*DENSITY*ad,ai=(n+1)*DENSITY*ad,K=ai-L;var G=this.data_cache.get_data(L,ai,this.mode);if(G===undefined||G==="pending"||(this.mode!=="Auto"&&G.dataset_type==="summary_tree")){this.data_queue[[L,ai]]=true;this.get_data(L,ai);return}var a=Math.ceil(K*ar),af=this.prefs.label_color,h=this.prefs.block_color,q=this.mode,v=25,ab=(q==="Squish")||(q==="Dense")&&(q!=="Pack")||(q==="Auto"&&(G.extra_info==="no_detail")),U=this.left_offset,aq,B,at;var p=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(p)}p=$(p);if(G.dataset_type==="summary_tree"){B=this.summary_draw_height}else{if(q==="Dense"){B=v;at=10}else{at=(ab?this.vertical_nodetail_px:this.vertical_detail_px);var w=(ar<0.0001?1/this.view.zoom_res:ar);B=this.incremental_slots(w,G.data,ab,q)*at+v;aq=this.inc_slots[w]}}p.css({position:"absolute",top:0,left:(L-this.view.low)*ar-U});p.get(0).width=a+U;p.get(0).height=B;r.parent().css("height",Math.max(this.height_px,B)+"px");var H=p.get(0).getContext("2d");H.fillStyle=h;H.font=this.default_font;H.textAlign="right";this.container_div.find(".yaxislabel").remove();if(G.dataset_type=="summary_tree"){var W=G.data,J=G.max,b=Math.ceil(G.delta*ar);var o=$("<div />").addClass("yaxislabel");o.text(J);o.css({position:"absolute",top:"22px",left:"10px"});o.prependTo(this.container_div);for(var am=0,F=W.length;am<F;am++){var Y=Math.floor((W[am][0]-L)*ar);var X=W[am][1];if(!X){continue}var aj=X/J*this.summary_draw_height;H.fillStyle="black";H.fillRect(Y+U,this.summary_draw_height-aj,b,aj);if(this.prefs.show_counts&&H.measureText(X).width<b){H.fillStyle="#bbb";H.textAlign="center";H.fillText(X,Y+U+(b/2),this.summary_draw_height-5)}}r.append(p);return p}if(G.message){p.css({border:"solid red","border-width":"2px 2px 2px 0px"});H.fillStyle="red";H.textAlign="left";H.fillText(G.message,100+U,at);return p}for(var ao=0;ao<this.filters.length;ao++){if(this.filters[ao].applies_to(G.data[0])){p.addClass(FILTERABLE_CLASS);break}}var ap=G.data;var al=0;for(var am=0,F=ap.length;am<F;am++){var Q=ap[am],P=Q[0],an=Q[1],aa=Q[2],M=Q[3];if(this.mode!="Dense"&&aq[P]===undefined){continue}var Z=false;var S;for(var ao=0;ao<this.filters.length;ao++){S=this.filters[ao];S.update_attrs(Q);if(!S.keep(Q)){Z=true;break}}if(Z){continue}if(an<=ai&&aa>=L){var ac=Math.floor(Math.max(0,(an-L)*ar)),I=Math.ceil(Math.min(a,Math.max(0,(aa-L)*ar))),V=(q==="Dense"?1:(1+aq[P]))*at;var E,ag,N=null,au=null;if(G.dataset_type==="bai"){H.fillStyle=h;if(Q[5] instanceof Array){var C=Math.floor(Math.max(0,(Q[4][0]-L)*ar)),O=Math.ceil(Math.min(a,Math.max(0,(Q[4][1]-L)*ar))),A=Math.floor(Math.max(0,(Q[5][0]-L)*ar)),u=Math.ceil(Math.min(a,Math.max(0,(Q[5][1]-L)*ar)));if(Q[4][1]>=L&&Q[4][0]<=ai&&Q[4][2]){this.rect_or_text(H,ar,L,ai,Q[4][0],Q[4][2],Q[4][3],V)}if(Q[5][1]>=L&&Q[5][0]<=ai&&Q[5][2]){this.rect_or_text(H,ar,L,ai,Q[5][0],Q[5][2],Q[5][3],V)}if(A>O){H.fillStyle=CONNECTOR_COLOR;H.dashedLine(O+U,V+5,U+A,V+5)}}else{H.fillStyle=h;this.rect_or_text(H,ar,L,ai,an,Q[4],Q[5],V)}if(q!=="Dense"&&!ab&&an>L){H.fillStyle=this.prefs.label_color;if(n===0&&ac-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+U,V+8)}else{H.textAlign="right";H.fillText(M,ac-2+U,V+8)}H.fillStyle=h}}else{if(G.dataset_type==="interval_index"){if(ab){H.fillStyle=h;H.fillRect(ac+U,V+5,I-ac,1)}else{var D=Q[5],T=Q[6],ae=Q[7],g=Q[8];if(T&&ae){N=Math.floor(Math.max(0,(T-L)*ar));au=Math.ceil(Math.min(a,Math.max(0,(ae-L)*ar)))}if(q!=="Dense"&&M!==undefined&&an>L){H.fillStyle=af;if(n===0&&ac-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+U,V+8)}else{H.textAlign="right";H.fillText(M,ac-2+U,V+8)}H.fillStyle=h}if(g){if(D){if(D=="+"){H.fillStyle=RIGHT_STRAND}else{if(D=="-"){H.fillStyle=LEFT_STRAND}}H.fillRect(ac+U,V,I-ac,10);H.fillStyle=h}for(var ak=0,e=g.length;ak<e;ak++){var t=g[ak],d=Math.floor(Math.max(0,(t[0]-L)*ar)),R=Math.ceil(Math.min(a,Math.max((t[1]-L)*ar)));if(d>R){continue}E=5;ag=3;H.fillRect(d+U,V+ag,R-d,E);if(N!==undefined&&!(d>au||R<N)){E=9;ag=1;var ah=Math.max(d,N),z=Math.min(R,au);H.fillRect(ah+U,V+ag,z-ah,E)}}}else{E=9;ag=1;H.fillRect(ac+U,V+ag,I-ac,E);if(Q.strand){if(Q.strand=="+"){H.fillStyle=RIGHT_STRAND_INV}else{if(Q.strand=="-"){H.fillStyle=LEFT_STRAND_INV}}H.fillRect(ac+U,V,I-ac,10);H.fillStyle=h}}}}else{if(G.dataset_type==="vcf"){if(ab){H.fillStyle=h;H.fillRect(ac+U,V+5,I-ac,1)}else{var s=Q[4],m=Q[5],c=Q[6];E=9;ag=1;H.fillRect(ac+U,V,I-ac,E);if(q!=="Dense"&&M!==undefined&&an>L){H.fillStyle=af;if(n===0&&ac-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+U,V+8)}else{H.textAlign="right";H.fillText(M,ac-2+U,V+8)}H.fillStyle=h}var l=s+" / "+m;if(an>L&&H.measureText(l).width<(I-ac)){H.fillStyle="white";H.textAlign="center";H.fillText(l,U+ac+(I-ac)/2,V+8);H.fillStyle=h}}}}}al++}}return p},gen_options:function(i){var a=$("<div />").addClass("form-row");var e="track_"+i+"_block_color",k=$("<label />").attr("for",e).text("Block color:"),l=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),j="track_"+i+"_label_color",g=$("<label />").attr("for",j).text("Text color:"),h=$("<input />").attr("id",j).attr("name",j).val(this.prefs.label_color),f="track_"+i+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(k).append(l).append(g).append(h).append(d)},update_options:function(d){var b=$("#track_"+d+"_block_color").val(),c=$("#track_"+d+"_label_color").val(),a=$("#track_"+d+"_show_count").attr("checked");if(b!==this.prefs.block_color||c!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=c;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,c,e){FeatureTrack.call(this,d,b,a,c,e);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});var ToolDataFeatureTrack=function(e,c,a,d,f,b){FeatureTrack.call(this,e,c,a,d,f,{},b);this.track_type="ToolDataFeatureTrack";this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};$.extend(ToolDataFeatureTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{predraw_init:function(){var b=this;var a=function(){if(b.data_cache.size()==0){setTimeout(a,300)}else{b.data_url=default_data_url;b.data_query_wait=DEFAULT_DATA_QUERY_WAIT;b.dataset_state_url=converted_datasets_state_url;$.getJSON(b.dataset_state_url,{dataset_id:b.dataset_id},function(c){})}};a()}});
\ No newline at end of file
+CanvasRenderingContext2D.prototype.dashedLine=function(c,i,b,h,f){if(f==undefined){f=4}var e=b-c;var d=h-i;var g=Math.floor(Math.sqrt(e*e+d*d)/f);var k=e/g;var j=d/g;for(var a=0;a<g;a++,c+=k,i+=j){if(a%2!=0){continue}this.fillRect(c,i,f,1)}};function sortable(a,b){a.bind("drag",{handle:b,relative:true},function(h,j){var g=$(this).parent();var f=g.children();for(var c=0;c<f.length;c++){if(j.offsetY<$(f.get(c)).position().top){break}}if(c==f.length){if(this!=f.get(c-1)){g.append(this)}}else{if(this!=f.get(c)){$(this).insertBefore(f.get(c))}}})}var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=100,DEFAULT_DATA_QUERY_WAIT=5000,CONNECTOR_COLOR="#ccc",DATA_ERROR="There was an error in indexing this dataset. ",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_CANNOT_RUN_TOOL="Tool cannot be rerun: ",DATA_LOADING="Loading data...",DATA_OK="Ready for display",FILTERABLE_CLASS="filterable",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=5,CACHED_DATA=5,DUMMY_CANVAS=document.createElement("canvas"),RIGHT_STRAND,LEFT_STRAND;if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(DUMMY_CANVAS)}CONTEXT=DUMMY_CANVAS.getContext("2d");PX_PER_CHAR=CONTEXT.measureText("A").width;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPattern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.move_key_to_end(b,a)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},move_key_to_end:function(b,a){this.key_ary.splice(a,1);this.key_ary.push(b)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var DataCache=function(a){Cache.call(this,a)};$.extend(DataCache.prototype,Cache.prototype,{get_data:function(g,b,e){var h=this.get(this.gen_key(g,b,e));if(h){return h}var j,f,a,d,e,h;for(var c=0;c<this.key_ary.length;c++){j=this.key_ary[c];f=this.split_key(j);a=f[0];d=f[1];if(g>=a&&b<=d){h=this.obj_cache[j];if(h.dataset_type!=="summary_tree"&&h.extra_info!=="no_detail"){this.move_key_to_end(j,c);return h}}}return undefined},set_data:function(b,c,d,a){return this.set(this.gen_key(b,c,d),a)},gen_key:function(a,c,d){var b=a+"_"+c;return b},split_key:function(a){return a.split("_")}});var View=function(a,d,c,b,e){this.container=a;this.chrom=null;this.vis_id=c;this.dbkey=b;this.title=d;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(e);this.reset()};$.extend(View.prototype,{init:function(d){var c=this.container,a=this;this.top_container=$("<div/>").addClass("top-container").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(c);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(f){if(f.type==="focusout"||(f.keyCode||f.which)===13||(f.keyCode||f.which)===27){if((f.keyCode||f.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a id='zoom-out' />").click(function(){a.zoom_out();a.redraw()}).appendTo(this.chrom_form);this.zi_link=$("<a id='zoom-in' />").click(function(){a.zoom_in();a.redraw()}).appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(f){if(f.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=f.chrom_info;var j='<option value="">Select Chrom/Contig</option>';for(var h=0,e=a.chrom_data.length;h<e;h++){var g=a.chrom_data[h].chrom;j+='<option value="'+g+'">'+g+"</option>"}a.chrom_select.html(j);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())});if(d){d()}},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("click",function(f){$(this).find("input").trigger("blur")});this.content_div.bind("dblclick",function(f){a.zoom_in(f.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(f,g){this.current_x=g.offsetX}).bind("drag",function(f,h){var i=h.offsetX-this.current_x;this.current_x=h.offsetX;var g=Math.round(i/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-g)});this.overview_close.bind("click",function(){for(var f=0,e=a.tracks.length;f<e;f++){a.tracks[f].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("dragstart",function(f,g){g.original_low=a.low;g.current_height=f.clientY;g.current_x=g.offsetX;g.enable_pan=(f.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(h,j){if(!j.enable_pan){return}var f=$(this);var k=j.offsetX-j.current_x;var g=f.scrollTop()-(h.clientY-j.current_height);f.scrollTop(g);j.current_height=h.clientY;j.current_x=j.offsetX;var i=Math.round(k/a.viewport_container.width()*(a.high-a.low));a.move_delta(i)});this.top_labeltrack.bind("dragstart",function(f,g){return $("<div />").css({height:a.content_div.height()+a.top_labeltrack.height()+a.nav_labeltrack.height(),top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j,k){$(k.proxy).css({left:Math.min(j.pageX,k.startX),width:Math.abs(j.pageX-k.startX)});var g=Math.min(j.pageX,k.startX)-a.container.offset().left,f=Math.max(j.pageX,k.startX)-a.container.offset().left,i=(a.high-a.low),h=a.viewport_container.width();a.update_location(Math.round(g/h*i)+a.low,Math.round(f/h*i)+a.low)}).bind("dragend",function(k,l){var g=Math.min(k.pageX,l.startX),f=Math.max(k.pageX,l.startX),i=(a.high-a.low),h=a.viewport_container.width(),j=a.low;a.low=Math.round(g/h*i)+j;a.high=Math.round(f/h*i)+j;$(l.proxy).remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack));$(window).bind("resize",function(){a.resize_window()});$(document).bind("redraw",function(){a.redraw()});this.reset();$(window).trigger("resize")},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(e,b,g){var d=this;var f=$.grep(d.chrom_data,function(j,k){return j.chrom===e})[0];if(f===undefined){return}if(e!==d.chrom){d.chrom=e;if(!d.chrom){d.intro_div.show()}else{d.intro_div.hide()}d.chrom_select.val(d.chrom);d.max_high=f.len;d.reset();d.redraw(true);for(var h=0,a=d.tracks.length;h<a;h++){var c=d.tracks[h];if(c.init){c.init()}}}if(b!==undefined&&g!==undefined){d.low=Math.max(b,0);d.high=Math.min(g,d.max_high)}d.reset_overview();d.redraw()},go_to:function(f){var j=this,a,d,b=f.split(":"),h=b[0],i=b[1];if(i!==undefined){try{var g=i.split("-");a=parseInt(g[0].replace(/,/g,""),10);d=parseInt(g[1].replace(/,/g,""),10)}catch(c){return false}}j.change_chrom(h,a,d)},move_fraction:function(c){var a=this;var b=a.high-a.low;this.move_delta(c*b)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);sortable(a.container_div,".draghandle");this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var e=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left:a,width:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Tool=function(a,b){this.name=a;this.params=b};$.extend(Tool.prototype,{get_param_values_dict:function(){var b={};for(var a=0;a<this.params.length;a++){var c=this.params[a];b[c.name]=c.value}return b},get_param_values:function(){var b=[];for(var a=0;a<this.params.length;a++){b[a]=this.params[a].value}return b}});var NumberToolParameter=function(c,b,e,a,d){this.name=c;this.label=b;this.min=e;this.max=a;this.value=d};var get_tool_from_dict=function(f){if(obj_length(f)==0){return undefined}var b=f.name;var l=f.params;var c=Array();for(var e=0;e<l.length;e++){var g=l[e];var a=g.name,k=g.label,h=g.type,d=g.min,j=g.max,m=g.value;c[c.length]=new NumberToolParameter(a,k,d,j,m)}return new Tool(b,c)};var Filter=function(b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.slider_min=Number.MAX_VALUE;this.slider_max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values",[this.slider_min,this.slider_max])}}});var get_filters_from_dict=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e=="int"||e=="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var Track=function(b,a,e,c,d){this.name=b;this.view=a;this.parent_element=e;this.data_url=(c?c:default_data_url);this.data_query_wait=(d?d:DEFAULT_DATA_QUERY_WAIT);this.dataset_check_url=converted_datasets_state_url;this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)};$.extend(Track.prototype,{init:function(){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(!a.dataset_id){return}$.getJSON(this.dataset_check_url,{hda_ldda:a.hda_ldda,dataset_id:a.dataset_id,chrom:a.view.chrom,low:a.view.max_low,high:a.view.max_high},function(b){if(!b||b==="error"||b.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(b.message){var d=a.view.tracks.indexOf(a);var c=$(" <a href='javascript:void(0);'></a>").attr("id",d+"_error");c.text("View error");$("#"+d+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+b.message+"</pre>",{Close:hide_modal})});a.content_div.append(c)}}else{if(b==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(b==="no data"||(b.data!==undefined&&(b.data===null||b.data.length===0))){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(b==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},a.data_query_wait)}else{if(b==="data"){a.content_div.text(DATA_OK);if(a.view.chrom){a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;a.predraw_init();a.draw()}}}}}}})},predraw_init:function(){},restore_prefs:function(a){var b=this;$.each(a,function(c,d){if(d!==undefined){b.prefs[c]=d}})},update_name:function(a){this.old_name=this.name;this.name=a;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)}});var TiledTrack=function(g,d,s){var o=this,j=o.view;this.filters=(g!==undefined?get_filters_from_dict(g):[]);this.tool=(d!==undefined?get_tool_from_dict(d):undefined);this.parent_track=s;this.child_tracks=[];if(o.hidden){return}if(this.parent_track){this.header_div.find(".draghandle").removeClass("draghandle").addClass("child-track-icon").addClass("icon-button");this.parent_element.addClass("child-track");this.tool=undefined}this.filtering_div=$("<div/>").addClass("track-filters").hide();this.header_div.after(this.filtering_div);this.filtering_div.bind("drag",function(i){i.stopPropagation()}).bind("dblclick",function(i){i.stopPropagation()});var t=$("<table class='filters'>").appendTo(this.filtering_div);$.each(this.filters,function(w,z){var v=$("<tr>").appendTo(t);var y=$("<th class='filter-info'>").appendTo(v);var u=$("<span class='name'>").appendTo(y);u.text(z.name+" ");var i=$("<span class='values'>").appendTo(y);var x=$("<td>").appendTo(v);z.control_element=$("<div id='"+z.name+"-filter-control' style='width: 200px; position: relative'>").appendTo(x);z.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(B,C){var A=C.values;i.text("["+A[0]+"-"+A[1]+"]");z.low=A[0];z.high=A[1];o.draw(true)},change:function(A,B){z.control_element.slider("option","slide").call(z.control_element,A,B)}});z.slider=z.control_element;z.slider_label=i});if(this.tool){this.dynamic_tool_div=$("<div/>").addClass("dynamic-tool").hide();this.header_div.after(this.dynamic_tool_div);this.dynamic_tool_div.bind("drag",function(i){i.stopPropagation()}).bind("click",function(i){i.stopPropagation()}).bind("dblclick",function(i){i.stopPropagation()});var l=$("<div class='tool-name'>").appendTo(this.dynamic_tool_div).text(this.tool.name);var e=this.tool.params;var o=this;$.each(this.tool.params,function(A,v){var y=$("<div>").addClass("param-row").appendTo(o.dynamic_tool_div);var x=$("<div>").addClass("slider-label").appendTo(y);var C=$("<span class='param-name'>").text(v.label+" ").appendTo(x);var w=$("<span/>").text(v.value);var z=$("<span class='param-value'>").appendTo(x).append("[").append(w).append("]");var B=$("<div/>").addClass("slider").appendTo(y);var i=$("<div id='"+v.name+"-param-control'>").appendTo(B);var u=(v.max<=1?0.01:(v.max<=1000?1:5));i.slider({min:v.min,max:v.max,step:u,value:v.value,slide:function(D,F){var E=F.value;v.value=E;if(0<E&&E<1){E=parseFloat(E).toFixed(2)}w.text(E)},change:function(D,E){v.value=E.value}});z.click(function(){var F=w,E=F.text(),D=(v.max<=1?4:v.max.length);F.text("");$("<input type='text'/>").attr("size",D).attr("maxlength",D).attr("value",E).appendTo(F).focus().select().click(function(G){G.stopPropagation()}).blur(function(){$(this).remove();F.text(E)}).keyup(function(I){if(I.keyCode===27){$(this).trigger("blur")}else{if(I.keyCode===13){var G=$(this),H=parseFloat(G.val());if(isNaN(H)||H>v.max||H<v.min){alert("Parameter value must be in the range ["+v.min+"-"+v.max+"]");return $(this)}F.text(H);i.slider("value",H);v.value=H}}})});$("<div style='clear: both;'/>").appendTo(y)});var b=$("<div>").addClass("param-row").appendTo(this.dynamic_tool_div);var n=$("<input type='submit'>").attr("value","Run").appendTo(b);var o=this;n.click(function(){o.run_tool()})}o.child_tracks_container=$("<div/>").addClass("child-tracks-container").hide();o.container_div.append(o.child_tracks_container);if(o.display_modes!==undefined){if(o.mode_div===undefined){o.mode_div=$("<div class='right-float menubutton popup' />").appendTo(o.header_div);var m=o.display_modes[0];o.mode=m;o.mode_div.text(m);var a=function(i){o.mode_div.text(i);o.mode=i;o.tile_cache.clear();o.draw()};var f={};for(var q=0,r=o.display_modes.length;q<r;q++){var k=o.display_modes[q];f[k]=function(i){return function(){a(i)}}(k)}make_popupmenu(o.mode_div,f)}else{o.mode_div.hide()}}var h={};h["Edit configuration"]=function(){var v=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},i=function(){o.update_options(o.track_id);hide_modal();$(window).unbind("keypress.check_enter_esc")},u=function(w){if((w.keyCode||w.which)===27){v()}else{if((w.keyCode||w.which)===13){i()}}};$(window).bind("keypress.check_enter_esc",u);show_modal("Configure Track",o.gen_options(o.track_id),{Cancel:v,OK:i})};h["Set as overview"]=function(){j.overview_viewport.find("canvas").remove();o.is_overview=true;o.set_overview();for(var i in j.tracks){if(j.tracks[i]!==o){j.tracks[i].is_overview=false}}};if(o.filters.length>0){h["Show filters"]=function(){var i;if(!o.filtering_div.is(":visible")){i="Hide filters";o.filters_visible=true}else{i="Show filters";o.filters_visible=false}o.filtering_div.toggle()}}if(o.tool){h["Toggle Tool"]=function(){var i;if(!o.dynamic_tool_div.is(":visible")){i="Hide dynamic tool";o.update_name(o.name+o.tool_region_and_parameters_str())}else{i="Show dynamic tool";o.revert_name()}o.dynamic_tool_div.toggle()}}var c=j;var p=function(){$("#no-tracks").show()};if(this.parent_track){c=this.parent_track;p=function(){}}h.Remove=function(){c.remove_track(o);if(c.num_tracks===0){p()}};o.popup_menu=make_popupmenu(o.name_div,h)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(a){var m=this.view.low,g=this.view.high,j=g-m,f=this.view.resolution;var p=$("<div style='position: relative;'></div>"),q=this.content_div.width()/j;this.content_div.append(p);this.max_height=0;var b=Math.floor(m/f/DENSITY);var l={};while((b*DENSITY*f)<g){var n=this.content_div.width()+"_"+q+"_"+b;var e=this.tile_cache.get(n);if(!a&&e){var k=b*DENSITY*f;var d=(k-m)*q;if(this.left_offset){d-=this.left_offset}e.css({left:d});this.show_tile(e,p)}else{this.delayed_draw(this,n,m,g,b,f,p,q,l)}b+=1}var c=this;var o=setInterval(function(){if(obj_length(l)===0){if(c.content_div.children().length>1){c.content_div.children(":first").remove()}for(var i=0;i<c.filters.length;i++){c.filters[i].update_ui_elt()}clearInterval(o)}},50);for(var h=0;h<this.child_tracks.length;h++){this.child_tracks[h].draw(a)}},delayed_draw:function(c,h,g,e,b,d,i,j,f){var a=setTimeout(function(){if(g<=c.view.high&&e>=c.view.low){var k=c.draw_tile(d,b,i,j);if(k){if(!c.initial_canvas&&!window.G_vmlCanvasManager){c.initial_canvas=$(k).clone();var n=k.get(0).getContext("2d");var l=c.initial_canvas.get(0).getContext("2d");var m=n.getImageData(0,0,n.canvas.width,n.canvas.height);l.putImageData(m,0,0);c.set_overview()}c.tile_cache.set(h,k);c.show_tile(k,i)}}delete f[a]},50);f[a]=true},show_tile:function(a,c){var b=this;c.append(a);b.max_height=Math.max(b.max_height,a.height());b.content_div.css("height",b.max_height+"px");if(b.hidden){return}if(a.hasClass(FILTERABLE_CLASS)){show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters");if(b.filters_visible){b.filtering_div.show()}}else{show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false);b.filtering_div.hide()}},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")},run_tool:function(){var b={dataset_id:this.original_dataset_id,chrom:this.view.chrom,low:this.view.low,high:this.view.high,tool_id:this.tool.name};$.extend(b,this.tool.get_param_values_dict());var d=this,c=b.tool_id+d.tool_region_and_parameters_str(b.chrom,b.low,b.high),e;if(d.track_type=="FeatureTrack"){e=new ToolDataFeatureTrack(c,view,undefined,{},{},d)}this.add_track(e);e.content_div.text("Starting job.");view.has_changes=true;var a=function(){$.getJSON(run_tool_url,b,function(f){if(f=="no converter"){e.container_div.addClass("error");e.content_div.text(DATA_NOCONVERTER)}else{if(f.error){e.container_div.addClass("error");e.content_div.text(DATA_CANNOT_RUN_TOOL+f.message)}else{if(f=="pending"){e.container_div.addClass("pending");e.content_div.text("Converting input data so that it can be easily reused.");setTimeout(a,2000)}else{e.dataset_id=f.dataset_id;e.content_div.text("Running job.");e.init()}}}})};a()},tool_region_and_parameters_str:function(c,a,d){var b=this,e=(c!==undefined&&a!==undefined&&d!==undefined?c+":"+a+"-"+d:"all");return" - region=["+e+"], parameters=["+b.tool.get_param_values().join(", ")+"]"},add_track:function(a){a.track_id=this.track_id+"_"+this.child_tracks.length;a.container_div.attr("id","track_"+a.track_id);this.child_tracks_container.append(a.container_div);sortable(a.container_div,".child-track-icon");if(!$(this.child_tracks_container).is(":visible")){this.child_tracks_container.show()}this.child_tracks.push(a)},remove_track:function(a){a.container_div.fadeOut("slow",function(){$(this).remove()})}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.data_queue={};this.data_cache=new DataCache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,j=f+"_"+b;var e=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(e)}e=$(e);var n=e.get(0).getContext("2d");if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o),i=Math.round(o/2);n.fillText(m[h],a+this.left_offset+i,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,e,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.min_height_px=12;this.max_height_px=400;this.height_px=80;this.hda_ldda=e;this.dataset_id=a;this.original_dataset_id=a;this.data_cache=new DataCache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode};this.restore_prefs(c);(function(f){var i=false;var h=false;var g=$("<div class='track-resize'>");$(f.container_div).hover(function(){i=true;g.show()},function(){i=false;if(!h){g.hide()}});g.hide().bind("dragstart",function(j,k){h=true;k.original_height=$(f.content_div).height()}).bind("drag",function(k,l){var j=Math.min(Math.max(l.original_height+l.deltaY,f.min_height_px),f.max_height_px);$(f.content_div).css("height",j);f.height_px=j;f.draw(true)}).bind("dragend",function(j,k){f.tile_cache.clear();h=false;if(!i){g.hide()}}).appendTo(f.container_div)})(this)};$.extend(LineTrack.prototype,TiledTrack.prototype,{predraw_init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;$.getJSON(a.data_url,{stats:true,chrom:a.view.chrom,low:null,high:null,hda_ldda:a.hda_ldda,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");var e=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=e.min;a.prefs.max_value=e.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=e.total_frequency;a.container_div.find(".yaxislabel").remove();var f=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"24px",left:"10px"});d.prependTo(a.container_div);f.css({position:"absolute",bottom:"2px",left:"10px"});f.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:this.data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){var h=g.data;c.data_cache.set(e,h);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(o,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*o,a=DENSITY*o,x=o+"_"+r;var b=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(b)}b=$(b);if(this.data_cache.get(x)===undefined){this.get_data(o,r);return}var v=this.data_cache.get(x);if(!v){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var n=b.get(0).getContext("2d"),j=false,k=this.prefs.min_value,g=this.prefs.max_value,m=this.vertical_range,t=this.total_frequency,d=this.height_px,l=this.mode;var w=Math.round(d+k/m*d);n.beginPath();n.moveTo(0,w);n.lineTo(a*e,w);n.fillStyle="#aaa";n.stroke();n.beginPath();n.fillStyle=this.prefs.color;var u,h,f;if(v.length>1){f=Math.ceil((v[1][0]-v[0][0])*e)}else{f=10}for(var p=0,q=v.length;p<q;p++){u=Math.round((v[p][0]-s)*e);h=v[p][1];if(h===null){if(j&&l==="Filled"){n.lineTo(u,d)}j=false;continue}if(h<k){h=k}else{if(h>g){h=g}}if(l==="Histogram"){h=Math.round(h/m*d);n.fillRect(u,w,f,-h)}else{if(l==="Intensity"){h=255-Math.floor((h-k)/m*255);n.fillStyle="rgb("+h+","+h+","+h+")";n.fillRect(u,0,f,d)}else{h=Math.round(d-(h-k)/m*d);if(j){n.lineTo(u,h)}else{j=true;if(l==="Filled"){n.moveTo(u,d);n.lineTo(u,h)}else{n.moveTo(u,h)}}}}}if(l==="Filled"){if(j){n.lineTo(u,w);n.lineTo(0,w)}n.fill()}else{n.stroke()}c.append(b);return b},gen_options:function(m){var a=$("<div />").addClass("form-row");var e="track_"+m+"_color",b=$("<label />").attr("for",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+m+"_minval",l=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),k=$("<input></input>").attr("id",h).val(d),j="track_"+m+"_maxval",g=$("<label></label>").attr("for",j).text("Max value:"),i=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",j).val(i);return a.append(l).append(k).append(g).append(f).append(b).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_color").val();if(a!==this.prefs.min_value||c!==this.prefs.max_value||b!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(c);this.prefs.color=b;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(f,c,h,a,e,g,d,b){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,f,c,c.viewport_container);TiledTrack.call(this,g,d,b);this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=h;this.dataset_id=a;this.original_dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new DataCache(20);this.left_offset=200;this.prefs={block_color:"#444",label_color:"black",show_counts:true};this.restore_prefs(e)};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(b.data_url,{chrom:b.view.chrom,low:a,high:d,hda_ldda:b.hda_ldda,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set_data(a,d,b.mode,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,h,b,p){var r=this.inc_slots[a];if(!r||(r.mode!==p)){r={};r.w_scale=a;r.mode=p;this.inc_slots[a]=r;this.s_e_by_tile[a]={}}var l=r.w_scale,x=[],y=[],j=0,n=this.view.max_low;for(var v=0,w=h.length;v<w;v++){var g=h[v],k=g[0];if(r[k]!==undefined){j=Math.max(j,r[k]);y.push(r[k])}else{x.push(v)}}var q=this.s_e_by_tile[a];var m=function(D,E){var C;for(var B=0,F;B<=MAX_FEATURE_DEPTH;B++){C=true;F=q[B];if(F!==undefined){for(var z=0,A=F.length;z<A;z++){var i=F[z];if(E>i[0]&&D<i[1]){C=false;break}}}if(C){break}}if(C){return B}else{return -1}};for(var v=0,w=x.length;v<w;v++){var g=h[x[v]],k=g[0],t=g[1],c=g[2],o=g[3],d=Math.floor((t-n)*l),f=Math.ceil((c-n)*l),u=CONTEXT.measureText(o).width,e;if(o!==undefined&&!b){if(d-u<0){f+=u;e="left"}else{d-=u;e="right"}}var s=m(d,f);if(s<0){}if(s>=0){slot=q[s];if(slot===undefined){slot=q[s]=[]}slot.push([d,f]);r[k]=s;j=Math.max(j,s)}else{}}return j},rect_or_text:function(r,l,u,b,q,j,g,f){r.textAlign="center";var d=0,s=0,p=Math.round(l/2);for(var m=0,t=j.length;m<t;m++){var k=j[m],e="MIDNSHP=X"[k[0]],n=k[1];if(e==="H"||e==="S"){d-=n}var h=q+d,x=Math.floor(Math.max(0,(h-u)*l)),i=Math.floor(Math.max(0,(h+n-u)*l));switch(e){case"H":break;case"S":case"M":case"=":var o=g.slice(s,s+n);if((this.mode==="Pack"||this.mode==="Auto")&&g!==undefined&&l>PX_PER_CHAR){r.fillStyle=this.prefs.block_color;r.fillRect(x+this.left_offset,f+1,i-x,9);r.fillStyle=CONNECTOR_COLOR;for(var v=0,a=o.length;v<a;v++){if(h+v>=u&&h+v<=b){var w=Math.floor(Math.max(0,(h+v-u)*l));r.fillText(o[v],w+this.left_offset+p,f+9)}}}else{r.fillStyle=this.prefs.block_color;r.fillRect(x+this.left_offset,f+(this.mode!="Dense"?4:5),i-x,(this.mode!="Dense"?3:1))}s+=n;break;case"N":r.fillStyle=CONNECTOR_COLOR;r.fillRect(x+this.left_offset,f+5,i-x,1);break;case"D":r.fillStyle="red";r.fillRect(x+this.left_offset,f+4,i-x,3);break;case"P":break;case"I":s+=n;break;case"X":s+=n;break}d+=n}},draw_tile:function(ad,n,r,ar){var L=n*DENSITY*ad,ai=(n+1)*DENSITY*ad,K=ai-L;var G=this.data_cache.get_data(L,ai,this.mode);if(G===undefined||G==="pending"||(this.mode!=="Auto"&&G.dataset_type==="summary_tree")){this.data_queue[[L,ai]]=true;this.get_data(L,ai);return}var a=Math.ceil(K*ar),af=this.prefs.label_color,h=this.prefs.block_color,q=this.mode,v=25,ab=(q==="Squish")||(q==="Dense")&&(q!=="Pack")||(q==="Auto"&&(G.extra_info==="no_detail")),U=this.left_offset,aq,B,at;var p=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(p)}p=$(p);if(G.dataset_type==="summary_tree"){B=this.summary_draw_height}else{if(q==="Dense"){B=v;at=10}else{at=(ab?this.vertical_nodetail_px:this.vertical_detail_px);var w=(ar<0.0001?1/this.view.zoom_res:ar);B=this.incremental_slots(w,G.data,ab,q)*at+v;aq=this.inc_slots[w]}}p.css({position:"absolute",top:0,left:(L-this.view.low)*ar-U});p.get(0).width=a+U;p.get(0).height=B;r.parent().css("height",Math.max(this.height_px,B)+"px");var H=p.get(0).getContext("2d");H.fillStyle=h;H.font=this.default_font;H.textAlign="right";this.container_div.find(".yaxislabel").remove();if(G.dataset_type=="summary_tree"){var W=G.data,J=G.max,b=Math.ceil(G.delta*ar);var o=$("<div />").addClass("yaxislabel");o.text(J);o.css({position:"absolute",top:"22px",left:"10px"});o.prependTo(this.container_div);for(var am=0,F=W.length;am<F;am++){var Y=Math.floor((W[am][0]-L)*ar);var X=W[am][1];if(!X){continue}var aj=X/J*this.summary_draw_height;H.fillStyle="black";H.fillRect(Y+U,this.summary_draw_height-aj,b,aj);if(this.prefs.show_counts&&H.measureText(X).width<b){H.fillStyle="#bbb";H.textAlign="center";H.fillText(X,Y+U+(b/2),this.summary_draw_height-5)}}r.append(p);return p}if(G.message){p.css({border:"solid red","border-width":"2px 2px 2px 0px"});H.fillStyle="red";H.textAlign="left";H.fillText(G.message,100+U,at);return p}for(var ao=0;ao<this.filters.length;ao++){if(this.filters[ao].applies_to(G.data[0])){p.addClass(FILTERABLE_CLASS);break}}var ap=G.data;var al=0;for(var am=0,F=ap.length;am<F;am++){var Q=ap[am],P=Q[0],an=Q[1],aa=Q[2],M=Q[3];if(this.mode!="Dense"&&aq[P]===undefined){continue}var Z=false;var S;for(var ao=0;ao<this.filters.length;ao++){S=this.filters[ao];S.update_attrs(Q);if(!S.keep(Q)){Z=true;break}}if(Z){continue}if(an<=ai&&aa>=L){var ac=Math.floor(Math.max(0,(an-L)*ar)),I=Math.ceil(Math.min(a,Math.max(0,(aa-L)*ar))),V=(q==="Dense"?1:(1+aq[P]))*at;var E,ag,N=null,au=null;if(G.dataset_type==="bai"){H.fillStyle=h;if(Q[5] instanceof Array){var C=Math.floor(Math.max(0,(Q[4][0]-L)*ar)),O=Math.ceil(Math.min(a,Math.max(0,(Q[4][1]-L)*ar))),A=Math.floor(Math.max(0,(Q[5][0]-L)*ar)),u=Math.ceil(Math.min(a,Math.max(0,(Q[5][1]-L)*ar)));if(Q[4][1]>=L&&Q[4][0]<=ai&&Q[4][2]){this.rect_or_text(H,ar,L,ai,Q[4][0],Q[4][2],Q[4][3],V)}if(Q[5][1]>=L&&Q[5][0]<=ai&&Q[5][2]){this.rect_or_text(H,ar,L,ai,Q[5][0],Q[5][2],Q[5][3],V)}if(A>O){H.fillStyle=CONNECTOR_COLOR;H.dashedLine(O+U,V+5,U+A,V+5)}}else{H.fillStyle=h;this.rect_or_text(H,ar,L,ai,an,Q[4],Q[5],V)}if(q!=="Dense"&&!ab&&an>L){H.fillStyle=this.prefs.label_color;if(n===0&&ac-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+U,V+8)}else{H.textAlign="right";H.fillText(M,ac-2+U,V+8)}H.fillStyle=h}}else{if(G.dataset_type==="interval_index"){if(ab){H.fillStyle=h;H.fillRect(ac+U,V+5,I-ac,1)}else{var D=Q[5],T=Q[6],ae=Q[7],g=Q[8];if(T&&ae){N=Math.floor(Math.max(0,(T-L)*ar));au=Math.ceil(Math.min(a,Math.max(0,(ae-L)*ar)))}if(q!=="Dense"&&M!==undefined&&an>L){H.fillStyle=af;if(n===0&&ac-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+U,V+8)}else{H.textAlign="right";H.fillText(M,ac-2+U,V+8)}H.fillStyle=h}if(g){if(D){if(D=="+"){H.fillStyle=RIGHT_STRAND}else{if(D=="-"){H.fillStyle=LEFT_STRAND}}H.fillRect(ac+U,V,I-ac,10);H.fillStyle=h}for(var ak=0,e=g.length;ak<e;ak++){var t=g[ak],d=Math.floor(Math.max(0,(t[0]-L)*ar)),R=Math.ceil(Math.min(a,Math.max((t[1]-L)*ar)));if(d>R){continue}E=5;ag=3;H.fillRect(d+U,V+ag,R-d,E);if(N!==undefined&&!(d>au||R<N)){E=9;ag=1;var ah=Math.max(d,N),z=Math.min(R,au);H.fillRect(ah+U,V+ag,z-ah,E)}}}else{E=9;ag=1;H.fillRect(ac+U,V+ag,I-ac,E);if(Q.strand){if(Q.strand=="+"){H.fillStyle=RIGHT_STRAND_INV}else{if(Q.strand=="-"){H.fillStyle=LEFT_STRAND_INV}}H.fillRect(ac+U,V,I-ac,10);H.fillStyle=h}}}}else{if(G.dataset_type==="vcf"){if(ab){H.fillStyle=h;H.fillRect(ac+U,V+5,I-ac,1)}else{var s=Q[4],m=Q[5],c=Q[6];E=9;ag=1;H.fillRect(ac+U,V,I-ac,E);if(q!=="Dense"&&M!==undefined&&an>L){H.fillStyle=af;if(n===0&&ac-H.measureText(M).width<0){H.textAlign="left";H.fillText(M,I+2+U,V+8)}else{H.textAlign="right";H.fillText(M,ac-2+U,V+8)}H.fillStyle=h}var l=s+" / "+m;if(an>L&&H.measureText(l).width<(I-ac)){H.fillStyle="white";H.textAlign="center";H.fillText(l,U+ac+(I-ac)/2,V+8);H.fillStyle=h}}}}}al++}}return p},gen_options:function(i){var a=$("<div />").addClass("form-row");var e="track_"+i+"_block_color",k=$("<label />").attr("for",e).text("Block color:"),l=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),j="track_"+i+"_label_color",g=$("<label />").attr("for",j).text("Text color:"),h=$("<input />").attr("id",j).attr("name",j).val(this.prefs.label_color),f="track_"+i+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(k).append(l).append(g).append(h).append(d)},update_options:function(d){var b=$("#track_"+d+"_block_color").val(),c=$("#track_"+d+"_label_color").val(),a=$("#track_"+d+"_show_count").attr("checked");if(b!==this.prefs.block_color||c!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=c;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,f,a,c,e){FeatureTrack.call(this,d,b,f,a,c,e);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});var ToolDataFeatureTrack=function(e,c,g,a,d,f,b){FeatureTrack.call(this,e,c,g,a,d,f,{},b);this.track_type="ToolDataFeatureTrack";this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};$.extend(ToolDataFeatureTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{predraw_init:function(){var b=this;var a=function(){if(b.data_cache.size()==0){setTimeout(a,300)}else{b.data_url=default_data_url;b.data_query_wait=DEFAULT_DATA_QUERY_WAIT;b.dataset_state_url=converted_datasets_state_url;$.getJSON(b.dataset_state_url,{dataset_id:b.dataset_id},function(c){})}};a()}});
\ No newline at end of file
--- a/static/scripts/trackster.js Tue Feb 01 19:56:05 2011 -0500
+++ b/static/scripts/trackster.js Tue Feb 01 20:07:17 2011 -0500
@@ -385,7 +385,6 @@
var container = $(this);
var delta = d.offsetX - d.current_x;
var new_scroll = container.scrollTop() - (e.clientY - d.current_height);
- console.log( new_scroll );
container.scrollTop(new_scroll);
d.current_height = e.clientY;
d.current_x = d.offsetX;
@@ -843,8 +842,8 @@
// Get dataset state; if state is fine, enable and draw track. Otherwise, show message
// about track status.
- $.getJSON(this.dataset_check_url,
- {dataset_id : track.dataset_id, chrom: track.view.chrom, low: track.view.max_low, high: track.view.max_high},
+ $.getJSON(this.dataset_check_url, { hda_ldda: track.hda_ldda, dataset_id: track.dataset_id,
+ chrom: track.view.chrom, low: track.view.max_low, high: track.view.max_high},
function (result) {
if (!result || result === "error" || result.kind === "error") {
track.container_div.addClass("error");
@@ -1548,7 +1547,7 @@
}
});
-var LineTrack = function ( name, view, dataset_id, prefs ) {
+var LineTrack = function ( name, view, hda_ldda, dataset_id, prefs ) {
this.track_type = "LineTrack";
this.display_modes = ["Histogram", "Line", "Filled", "Intensity"];
this.mode = "Histogram";
@@ -1558,6 +1557,7 @@
this.min_height_px = 12;
this.max_height_px = 400;
this.height_px = 80;
+ this.hda_ldda = hda_ldda;
this.dataset_id = dataset_id;
this.original_dataset_id = dataset_id;
this.data_cache = new DataCache(CACHED_DATA);
@@ -1604,7 +1604,7 @@
track.vertical_range = undefined;
$.getJSON( track.data_url, { stats: true, chrom: track.view.chrom, low: null, high: null,
- dataset_id: track.dataset_id }, function(result) {
+ hda_ldda: track.hda_ldda, dataset_id: track.dataset_id }, function(result) {
track.container_div.addClass( "line-track" );
var data = result.data;
if ( isNaN(parseFloat(track.prefs.min_value)) || isNaN(parseFloat(track.prefs.max_value)) ) {
@@ -1646,9 +1646,8 @@
track.draw();
});*/
$.ajax({ 'url': this.data_url, 'dataType': 'json',
- 'data': { "chrom": this.view.chrom,
- "low": low, "high": high, "dataset_id": this.dataset_id,
- "resolution": this.view.resolution },
+ 'data': { chrom: this.view.chrom, low: low, high: high,
+ hda_ldda: this.hda_ldda, dataset_id: this.dataset_id, resolution: this.view.resolution },
success: function (result) {
var data = result.data;
track.data_cache.set(key, data);
@@ -1804,7 +1803,7 @@
}
});
-var FeatureTrack = function (name, view, dataset_id, prefs, filters, tool, parent_track) {
+var FeatureTrack = function (name, view, hda_ldda, dataset_id, prefs, filters, tool, parent_track) {
this.track_type = "FeatureTrack";
this.display_modes = ["Auto", "Dense", "Squish", "Pack"];
Track.call(this, name, view, view.viewport_container);
@@ -1812,6 +1811,7 @@
this.height_px = 0;
this.container_div.addClass( "feature-track" );
+ this.hda_ldda = hda_ldda;
this.dataset_id = dataset_id;
this.original_dataset_id = dataset_id;
this.zo_slots = {};
@@ -1839,7 +1839,7 @@
if (!track.data_queue[key]) {
track.data_queue[key] = true;
$.getJSON( track.data_url, { chrom: track.view.chrom,
- low: low, high: high, dataset_id: track.dataset_id,
+ low: low, high: high, hda_ldda: track.hda_ldda, dataset_id: track.dataset_id,
resolution: this.view.resolution, mode: this.mode }, function (result) {
track.data_cache.set_data(low, high, track.mode, result);
// console.log("datacache", track.data_cache.get(key));
@@ -1987,7 +1987,7 @@
else {
// TODO: remove this warning when skipped features are handled.
// Show warning for skipped feature.
- console.log("WARNING: not displaying feature"); // , feature_uid, f_start, f_end);
+ // console.log("WARNING: not displaying feature"); // , feature_uid, f_start, f_end);
}
}
@@ -2425,8 +2425,8 @@
}
});
-var ReadTrack = function (name, view, dataset_id, prefs, filters) {
- FeatureTrack.call(this, name, view, dataset_id, prefs, filters);
+var ReadTrack = function (name, view, hda_ldda, dataset_id, prefs, filters) {
+ FeatureTrack.call(this, name, view, hda_ldda, dataset_id, prefs, filters);
this.track_type = "ReadTrack";
this.vertical_detail_px = 10;
this.vertical_nodetail_px = 5;
@@ -2436,8 +2436,8 @@
/**
* Feature track that displays data generated from tool.
*/
-var ToolDataFeatureTrack = function(name, view, dataset_id, prefs, filters, parent_track) {
- FeatureTrack.call(this, name, view, dataset_id, prefs, filters, {}, parent_track);
+var ToolDataFeatureTrack = function(name, view, hda_ldda, dataset_id, prefs, filters, parent_track) {
+ FeatureTrack.call(this, name, view, hda_ldda, dataset_id, prefs, filters, {}, parent_track);
this.track_type = "ToolDataFeatureTrack";
// Set up track to fetch initial data from raw data URL when the dataset--not the converted datasets--
--- a/templates/tracks/browser.mako Tue Feb 01 19:56:05 2011 -0500
+++ b/templates/tracks/browser.mako Tue Feb 01 20:07:17 2011 -0500
@@ -156,7 +156,8 @@
track_config = tracks_config[i];
track = new addable_track_types[track_config["track_type"]](
track_config['name'],
- view,
+ view,
+ track_config['hda_ldda'],
track_config['dataset_id'],
track_config['prefs'],
track_config['filters'],
@@ -211,10 +212,10 @@
var add_async_success = function(track_data) {
var td = track_data,
new_track = new addable_track_types[track_data.track_type](
- track_data.name, view, track_data.dataset_id, track_data.prefs,
- track_data.filters, track_data.tool );
+ track_data.name, view, track_data.hda_ldda, track_data.dataset_id,
+ track_data.prefs, track_data.filters, track_data.tool );
view.add_track(new_track);
- // Should replace with live event but can't get working
+ ## Should replace with live event but can't get working
sortable( new_track.container_div, ".draghandle" );
view.has_changes = true;
$("#no-tracks").hide();
@@ -229,7 +230,7 @@
});
%endif
-
+
// Use a popup grid to add more tracks
$("#add-track").bind("click", function(e) {
$.ajax({
@@ -238,18 +239,24 @@
error: function() { alert( "Grid failed" ); },
success: function(table_html) {
show_modal(
- "Add Track — Select History, then Dataset(s)",
+ "Add Track — Select history/library, then datasets",
table_html,
{
"Cancel": function() {
hide_modal();
},
"Insert": function() {
- $('input[name=id]:checked').each(function() {
- var item_id = $(this).val();
+ $('input[name=id]:checked,input[name=ldda_ids]:checked').each(function() {
+ var data,
+ id = $(this).val();
+ if ($(this).attr("name") === "id") {
+ data = { hda_id: id };
+ } else {
+ data = { ldda_id: id};
+ }
$.ajax( {
url: "${h.url_for( action='add_track_async' )}",
- data: { id: item_id },
+ data: data,
dataType: "json",
success: add_async_success
});
@@ -286,6 +293,7 @@
tracks.push( {
"track_type": track.track_type,
"name": track.name,
+ "hda_ldda": track.hda_ldda,
"dataset_id": track.dataset_id,
"prefs": track.prefs,
"is_child": (child_id ? true : false )
--- a/templates/tracks/history_datasets_select_grid.mako Tue Feb 01 19:56:05 2011 -0500
+++ b/templates/tracks/history_datasets_select_grid.mako Tue Feb 01 20:07:17 2011 -0500
@@ -10,6 +10,7 @@
url_dict[ "f-" + filter ] = value
%>
## Use class 'label' to piggyback on URL functionality in parent template.
- <a class="label" href="${h.url_for( **url_dict )}">Back to histories</a><br/>
+ <a class="label" href="${h.url_for( **url_dict )}">Back to histories</a>
+ <br /><br />
${parent.title()}
</%def>
\ No newline at end of file
--- a/templates/tracks/history_select_grid.mako Tue Feb 01 19:56:05 2011 -0500
+++ b/templates/tracks/history_select_grid.mako Tue Feb 01 20:07:17 2011 -0500
@@ -6,7 +6,7 @@
<%namespace file="../grid_base.mako" import="*" />
## Need to define title so that it can be overridden by child templates.
-<%def name="title()"><h2>${grid.title}</h2></%def>
+<%def name="title()"></%def>
${self.title()}
${stylesheets()}
@@ -19,11 +19,11 @@
var f = function() {
$("a.label,.page-link>a").click(function() {
var parent_body = $(this).parents("div.body");
- if (parent_body.length != 0) {
+ if (parent_body.length !== 0) {
parent_body.load($(this).attr("href"));
return false;
}
- });
+ });
};
// Need to process label URLs when document loaded and when grid changes.
$(document).ready(function() {
@@ -31,5 +31,15 @@
$('#grid-table-body').bind('update', f);
});
</script>
+
+%if getattr(grid, "datasets_param", None):
+ %if grid.datasets_param == "f-history":
+ <a class="label" href="${h.url_for( action='list_libraries' )}">Show Data Libraries</a>
+ %else:
+ <a class="label" href="${h.url_for( action='list_histories' )}">Show Histories</a>
+ %endif
+ <br /><br />
+%endif
+
${render_grid_header( grid, False )}
${render_grid_table( grid, show_item_checkboxes=show_item_checkboxes )}
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: kanwei: Add migration for ldda_parent_id field to implicitly_converted_dataset_association table
by Bitbucket 01 Feb '11
by Bitbucket 01 Feb '11
01 Feb '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/32e6782161be/
changeset: r4975:32e6782161be
user: kanwei
date: 2011-02-02 01:56:05
summary: Add migration for ldda_parent_id field to implicitly_converted_dataset_association table
affected #: 1 file (0 bytes)
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 YeastMine datasource tool. Site is still under development.
by Bitbucket 01 Feb '11
by Bitbucket 01 Feb '11
01 Feb '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/d65fb6e05729/
changeset: r4974:d65fb6e05729
user: dan
date: 2011-02-01 23:29:40
summary: Add YeastMine datasource tool. Site is still under development.
affected #: 2 files (46 bytes)
--- a/tool_conf.xml.sample Tue Feb 01 13:35:46 2011 -0500
+++ b/tool_conf.xml.sample Tue Feb 01 17:29:40 2011 -0500
@@ -16,6 +16,7 @@
<tool file="data_source/flymine_test.xml" /><tool file="data_source/modmine.xml" /><tool file="data_source/ratmine.xml" />
+ <tool file="data_source/yeastmine.xml" /><tool file="data_source/worm_modencode.xml" /><tool file="data_source/wormbase.xml" /><tool file="data_source/wormbase_test.xml" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: dannon: workflows: When running a workflow, filter possible values for Input Dataset steps to datatypes that are valid for next connected steps, instead of just using 'data'.
by Bitbucket 01 Feb '11
by Bitbucket 01 Feb '11
01 Feb '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/ea364eb4375f/
changeset: r4973:ea364eb4375f
user: dannon
date: 2011-02-01 19:35:46
summary: workflows: When running a workflow, filter possible values for Input Dataset steps to datatypes that are valid for next connected steps, instead of just using 'data'.
affected #: 2 files (528 bytes)
--- a/lib/galaxy/workflow/modules.py Tue Feb 01 13:32:02 2011 -0500
+++ b/lib/galaxy/workflow/modules.py Tue Feb 01 13:35:46 2011 -0500
@@ -129,9 +129,9 @@
def update_state( self, incoming ):
self.state['name'] = incoming.get( 'name', 'Input Dataset' )
- def get_runtime_inputs( self ):
+ def get_runtime_inputs( self, filter_set=['data'] ):
label = self.state.get( "name", "Input Dataset" )
- return dict( input=DataToolParameter( None, Element( "param", name="input", label=label, type="data", format="data" ) ) )
+ return dict( input=DataToolParameter( None, Element( "param", name="input", label=label, type="data", format=', '.join(filter_set) ) ) )
def get_runtime_state( self ):
state = DefaultToolState()
state.inputs = dict( input=None )
--- a/templates/workflow/run.mako Tue Feb 01 13:32:02 2011 -0500
+++ b/templates/workflow/run.mako Tue Feb 01 13:35:46 2011 -0500
@@ -315,7 +315,17 @@
% endif
</div><div class="toolFormBody">
- ${do_inputs( module.get_runtime_inputs(), step.state.inputs, errors.get( step.id, dict() ), "", step )}
+ <%
+ # Filter possible inputs to data types that are valid for subsequent steps
+ type_filter = []
+ for oc in step.output_connections:
+ for ic in oc.input_step.module.get_data_inputs():
+ if 'extensions' in ic and ic['name'] == oc.input_name:
+ type_filter += ic['extensions']
+ if not type_filter:
+ type_filter = ['data']
+ %>
+ ${do_inputs( module.get_runtime_inputs(type_filter), step.state.inputs, errors.get( step.id, dict() ), "", step )}
</div></div>
%endif
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: Parse custom build len files using tabs rather than all whitespace; this matches the output produced by the tool 'Compute Sequence Length'
by Bitbucket 01 Feb '11
by Bitbucket 01 Feb '11
01 Feb '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/90a97c6aee95/
changeset: r4972:90a97c6aee95
user: jgoecks
date: 2011-02-01 19:32:02
summary: Parse custom build len files using tabs rather than all whitespace; this matches the output produced by the tool 'Compute Sequence Length'
affected #: 2 files (132 bytes)
--- a/lib/galaxy/web/controllers/tracks.py Tue Feb 01 13:20:18 2011 -0500
+++ b/lib/galaxy/web/controllers/tracks.py Tue Feb 01 13:32:02 2011 -0500
@@ -313,8 +313,9 @@
for line in open( len_file ):
if line.startswith("#"):
continue
- # LEN files are just whitespace separated
- fields = line.split()
+ # LEN files have format:
+ # <chrom_name><tab><chrom_length>
+ fields = line.split("\t")
manifest[fields[0]] = int(fields[1])
return manifest
--- a/lib/galaxy/web/controllers/user.py Tue Feb 01 13:20:18 2011 -0500
+++ b/lib/galaxy/web/controllers/user.py Tue Feb 01 13:32:02 2011 -0500
@@ -1275,8 +1275,10 @@
counter = 0
f = open(new_len.file_name, "w")
+ # LEN files have format:
+ # <chrom_name><tab><chrom_length>
for line in len_text.split("\n"):
- lst = line.strip().split()
+ lst = line.strip().split("\t")
if not lst or len(lst) < 2:
lines_skipped += 1
continue
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0

commit/galaxy-central: greg: Fix Manage your API keys link on the user preferences page.
by Bitbucket 01 Feb '11
by Bitbucket 01 Feb '11
01 Feb '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/7d19d6962076/
changeset: r4971:7d19d6962076
user: greg
date: 2011-02-01 19:20:18
summary: Fix Manage your API keys link on the user preferences page.
affected #: 1 file (18 bytes)
--- a/templates/user/index.mako Tue Feb 01 13:11:24 2011 -0500
+++ b/templates/user/index.mako Tue Feb 01 13:20:18 2011 -0500
@@ -13,7 +13,7 @@
<li><a href="${h.url_for( controller='user', action='show_info' )}">${_('Manage your information')}</a></li><li><a href="${h.url_for( controller='user', action='set_default_permissions' )}">${_('Change default permissions')}</a> for new histories</li>
%if trans.app.config.enable_api:
- <li><a href="${h.url_for( controller='user', action='api_keys' )}">${_('Manage your API Keys')}</a> for new histories</li>
+ <li><a href="${h.url_for( controller='user', action='api_keys' )}">${_('Manage your API keys')}</a></li>
%endif
%if trans.app.config.enable_openid:
<li><a href="${h.url_for( controller='user', action='openid_manage' )}">${ ('Manage OpenIDs')}</a> linked to your account</li>
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: Brad Chapman's patch for fixing an issue where the current user roles were not passed to a template.
by Bitbucket 01 Feb '11
by Bitbucket 01 Feb '11
01 Feb '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/5297d8f24693/
changeset: r4970:5297d8f24693
user: greg
date: 2011-02-01 19:11:24
summary: Brad Chapman's patch for fixing an issue where the current user roles were not passed to a template.
affected #: 2 files (114 bytes)
--- a/lib/galaxy/web/controllers/library.py Tue Feb 01 11:21:41 2011 -0500
+++ b/lib/galaxy/web/controllers/library.py Tue Feb 01 13:11:24 2011 -0500
@@ -110,6 +110,7 @@
search_term=search_term,
comptypes=comptypes,
lddas=lddas,
+ current_user_roles=trans.get_current_user_roles(),
show_deleted=show_deleted,
use_panels=use_panels,
message=message,
--- a/scripts/data_libraries/build_lucene_index.py Tue Feb 01 11:21:41 2011 -0500
+++ b/scripts/data_libraries/build_lucene_index.py Tue Feb 01 13:11:24 2011 -0500
@@ -61,7 +61,7 @@
fname = ""
else:
fname = ldda.dataset.get_file_name()
- yield ldda.id, fname, _get_dataset_metadata(ldda)
+ yield ldda.id, fname, _get_dataset_metadata(ldda).replace("\n", " ")
def _get_dataset_metadata(ldda):
"""Retrieve descriptions and information associated with a dataset.
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

01 Feb '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/1d4dbfe2e2ce/
changeset: r4969:1d4dbfe2e2ce
user: greg
date: 2011-02-01 17:21:41
summary: Apply patch from Brad Chapman that fixes an issue when downloading a zip archive of library datasets. Also include some miscellansous imporvements and code cleanup related to changes made in change set 4964:82107691d26e.
affected #: 10 files (5.6 KB)
--- a/lib/galaxy/util/streamball.py Tue Feb 01 11:20:02 2011 -0500
+++ b/lib/galaxy/util/streamball.py Tue Feb 01 11:21:41 2011 -0500
@@ -1,7 +1,7 @@
"""
A simple wrapper for writing tarballs as a stream.
"""
-
+import os
import logging, tarfile
log = logging.getLogger( __name__ )
@@ -26,3 +26,19 @@
tf.add( file, arcname=rel )
tf.close()
return []
+
+class ZipBall(object):
+ def __init__(self, tmpf, tmpd):
+ self._tmpf = tmpf
+ self._tmpd = tmpd
+ def stream(self, environ, start_response):
+ response_write = start_response( self.wsgi_status, self.wsgi_headeritems )
+ tmpfh = open( self._tmpf )
+ response_write(tmpfh.read())
+ tmpfh.close()
+ try:
+ os.unlink( self._tmpf )
+ os.rmdir( self._tmpd )
+ except OSError:
+ log.exception( "Unable to remove temporary library download archive and directory" )
+ return []
--- a/lib/galaxy/web/controllers/library.py Tue Feb 01 11:20:02 2011 -0500
+++ b/lib/galaxy/web/controllers/library.py Tue Feb 01 11:21:41 2011 -0500
@@ -35,7 +35,7 @@
attach_popup=False,
filterable="advanced" ),
]
- columns.append( grids.MulticolFilterColumn( "search library dataset name, info, message, dbkey",
+ columns.append( grids.MulticolFilterColumn( "search dataset name, info, message, dbkey",
cols_to_filter=[ columns[0], columns[1] ],
key="free-text-search",
visible=False,
--- a/lib/galaxy/web/controllers/library_admin.py Tue Feb 01 11:20:02 2011 -0500
+++ b/lib/galaxy/web/controllers/library_admin.py Tue Feb 01 11:21:41 2011 -0500
@@ -50,7 +50,7 @@
# Columns that are valid for filtering but are not visible.
grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
]
- columns.append( grids.MulticolFilterColumn( "search library dataset name, info, message, dbkey",
+ columns.append( grids.MulticolFilterColumn( "search dataset name, info, message, dbkey",
cols_to_filter=[ columns[0], columns[1] ],
key="free-text-search",
visible=False,
--- a/lib/galaxy/web/controllers/library_common.py Tue Feb 01 11:20:02 2011 -0500
+++ b/lib/galaxy/web/controllers/library_common.py Tue Feb 01 11:21:41 2011 -0500
@@ -1706,20 +1706,12 @@
fname = lname.replace( ' ', '_' ) + '_files'
if action == 'zip':
archive.close()
- tmpfh = open( tmpf )
- # clean up now
- try:
- os.unlink( tmpf )
- os.rmdir( tmpd )
- except OSError:
- error = True
- log.exception( "Unable to remove temporary library download archive and directory" )
- message = "Unable to create archive for download, please report this error"
- status = 'error'
- if not error:
- trans.response.set_content_type( "application/x-zip-compressed" )
- trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
- return tmpfh
+ trans.response.set_content_type( "application/x-zip-compressed" )
+ trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
+ archive = util.streamball.ZipBall(tmpf, tmpd)
+ archive.wsgi_status = trans.response.wsgi_status()
+ archive.wsgi_headeritems = trans.response.wsgi_headeritems()
+ return archive.stream
elif action == 'ngxzip':
trans.response.set_content_type( "application/zip" )
trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
@@ -1831,11 +1823,11 @@
hist_names_str = ", ".join( [ target_history.name for target_history in target_histories ] )
num_source = len( ldda_ids ) - invalid_datasets
num_target = len( target_histories )
- message = "%i %s have been imported into %i %s: %s" % ( num_source,
- inflector.cond_plural( num_source, "dataset" ),
- num_target,
- inflector.cond_plural( num_target, "history" ),
- hist_names_str )
+ message = "%i %s imported into %i %s: %s" % ( num_source,
+ inflector.cond_plural( num_source, "dataset" ),
+ num_target,
+ inflector.cond_plural( num_target, "history" ),
+ hist_names_str )
trans.sa_session.refresh( current_history )
current_user_roles = trans.get_current_user_roles()
source_lddas = []
@@ -2240,7 +2232,7 @@
# Perform search
parser = MultifieldParser( [ 'name', 'info', 'dbkey', 'message' ], schema=schema )
# Search term with wildcards may be slow...
- results = searcher.search( parser.parse( '*' + search_term + '*' ), minscore=0.1 )
+ results = searcher.search( parser.parse( '*' + search_term + '*' ), minscore=0.5 )
ldda_ids = [ result[ 'id' ] for result in results ]
lddas = []
for ldda_id in ldda_ids:
--- a/scripts/data_libraries/build_whoosh_index.py Tue Feb 01 11:20:02 2011 -0500
+++ b/scripts/data_libraries/build_whoosh_index.py Tue Feb 01 11:21:41 2011 -0500
@@ -63,7 +63,10 @@
else:
info = ''
dbkey = ldda.metadata.dbkey
- message = ldda.message
+ if ldda.message:
+ message = ldda.message
+ else:
+ message = ''
yield id, name, info, dbkey, message
def get_sa_session_and_needed_config_settings( ini_file ):
--- a/templates/library/common/browse_library.mako Tue Feb 01 11:20:02 2011 -0500
+++ b/templates/library/common/browse_library.mako Tue Feb 01 11:21:41 2011 -0500
@@ -1,6 +1,7 @@
<%namespace file="/message.mako" import="render_msg" /><%namespace file="/library/common/library_item_info.mako" import="render_library_item_info" /><%namespace file="/library/common/common.mako" import="render_actions_on_multiple_items" />
+<%namespace file="/library/common/common.mako" import="render_compression_types_help" /><%namespace file="/library/common/common.mako" import="common_javascripts" /><%!
@@ -564,34 +565,6 @@
</script><!-- running: do not change this comment, used by TwillTestCase.library_wait -->
%endif
-
- ## Help about compression types
-
- <div class="libraryItemBody">
- <p class="infomark">
- TIP: You can download individual library files by selecting "Download this dataset" from the context menu (triangle) next to the dataset's name.
- </p>
- </div>
- %if len( comptypes ) > 1:
- <div class="libraryItemBody">
- <p class="infomark">
- TIP: Multiple compression options are available for downloading library datasets:
- </p>
- <ul style="padding-left: 1em; list-style-type: disc;">
- %if 'gz' in comptypes:
- <li>gzip: Recommended for fast network connections
- %if trans.app.config.upstream_gzip:
- NOTE: The file you receive will be an uncompressed .tar file - this is because the Galaxy server compresses it and your browser decompresses it on the fly.
- %endif
- </li>
- %endif
- %if 'bz2' in comptypes:
- <li>bzip2: Recommended for slower network connections (smaller size but takes longer to compress)</li>
- %endif
- %if 'zip' in comptypes:
- <li>zip: Not recommended but is provided as an option for those who cannot open the above formats</li>
- %endif
- </ul>
- </div>
- %endif
+
+ ${render_compression_types_help( comptypes )}
</%def>
--- a/templates/library/common/common.mako Tue Feb 01 11:20:02 2011 -0500
+++ b/templates/library/common/common.mako Tue Feb 01 11:21:41 2011 -0500
@@ -43,6 +43,36 @@
</script></%def>
+<%def name="render_compression_types_help( comptypes )">
+ <div class="libraryItemBody">
+ <p class="infomark">
+ TIP: You can download individual library datasets by selecting "Download this dataset" from the context menu (triangle) next to each dataset's name.
+ </p>
+ </div>
+ %if len( comptypes ) > 1:
+ <div class="libraryItemBody">
+ <p class="infomark">
+ TIP: Several compression options are available for downloading multiple library datasets simultaneously:
+ </p>
+ <ul style="padding-left: 1em; list-style-type: disc;">
+ %if 'gz' in comptypes:
+ <li>gzip: Recommended for fast network connections
+ %if trans.app.config.upstream_gzip:
+ NOTE: The file you receive will be an uncompressed .tar file - this is because the Galaxy server compresses it and your browser decompresses it on the fly.
+ %endif
+ </li>
+ %endif
+ %if 'bz2' in comptypes:
+ <li>bzip2: Recommended for slower network connections (smaller size but takes longer to compress)</li>
+ %endif
+ %if 'zip' in comptypes:
+ <li>zip: Not recommended but is provided as an option for those who cannot open the above formats</li>
+ %endif
+ </ul>
+ </div>
+ %endif
+</%def>
+
<%def name="render_upload_form( cntrller, upload_option, action, library_id, folder_id, replace_dataset, file_formats, dbkeys, space_to_tab, link_data_only, widgets, roles_select_list, history, show_deleted )"><%
import os, os.path
--- a/templates/library/common/import_datasets_to_histories.mako Tue Feb 01 11:20:02 2011 -0500
+++ b/templates/library/common/import_datasets_to_histories.mako Tue Feb 01 11:21:41 2011 -0500
@@ -58,8 +58,14 @@
<select id="single-dest-select" name="target_history_ids"><option value=""></option>
%for i, target_history in enumerate( target_histories ):
- <% encoded_id = trans.security.encode_id( target_history.id ) %>
- <option value="${encoded_id}">${i + 1}: ${h.truncate( target_history.name, 30 )}</option>
+ <%
+ encoded_id = trans.security.encode_id( target_history.id )
+ if target_history == current_history:
+ current_history_text = " (current history)"
+ else:
+ current_history_text = ""
+ %>
+ <option value="${encoded_id}">${i + 1}: ${h.truncate( target_history.name, 30 )}${current_history_text}</option>
%endfor
</select><br/><br/>
@@ -68,12 +74,15 @@
<div id="multiple-destination" style="display: none;">
%for i, target_history in enumerate( target_histories ):
<%
- cur_history_text = ""
encoded_id = trans.security.encode_id( target_history.id )
+ if target_history == current_history:
+ current_history_text = " (current history)"
+ else:
+ current_history_text = ""
%><div class="form-row"><input type="checkbox" name="target_history_ids" id="target_history_${encoded_id}" value="${encoded_id}"/>
- <label for="target_history_${encoded_id}" style="display: inline; font-weight:normal;">${i + 1}: ${target_history.name}${cur_history_text}</label>
+ <label for="target_history_${encoded_id}" style="display: inline; font-weight:normal;">${i + 1}: ${target_history.name}${current_history_text}</label></div>
%endfor
</div>
--- a/templates/library/common/library_dataset_search_results.mako Tue Feb 01 11:20:02 2011 -0500
+++ b/templates/library/common/library_dataset_search_results.mako Tue Feb 01 11:21:41 2011 -0500
@@ -1,6 +1,7 @@
<%namespace file="/message.mako" import="render_msg" /><%namespace file="/library/common/browse_library.mako" import="render_dataset" /><%namespace file="/library/common/common.mako" import="render_actions_on_multiple_items" />
+<%namespace file="/library/common/common.mako" import="render_compression_types_help" /><%namespace file="/library/common/common.mako" import="common_javascripts" /><%!
@@ -127,35 +128,7 @@
${render_actions_on_multiple_items( actions_to_exclude=[ 'manage_permissions' ] )}
</table></form>
- ## Help about compression types
-
- <div class="libraryItemBody">
- <p class="infomark">
- TIP: You can download individual library files by selecting "Download this dataset" from the context menu (triangle) next to the dataset's name.
- </p>
- </div>
- %if len( comptypes ) > 1:
- <div class="libraryItemBody">
- <p class="infomark">
- TIP: Multiple compression options are available for downloading library datasets:
- </p>
- <ul style="padding-left: 1em; list-style-type: disc;">
- %if 'gz' in comptypes:
- <li>gzip: Recommended for fast network connections
- %if trans.app.config.upstream_gzip:
- NOTE: The file you receive will be an uncompressed .tar file - this is because the Galaxy server compresses it and your browser decompresses it on the fly.
- %endif
- </li>
- %endif
- %if 'bz2' in comptypes:
- <li>bzip2: Recommended for slower network connections (smaller size but takes longer to compress)</li>
- %endif
- %if 'zip' in comptypes:
- <li>zip: Not recommended but is provided as an option for those who cannot open the above formats</li>
- %endif
- </ul>
- </div>
- %endif
+ ${render_compression_types_help( comptypes )}
%elif status != 'error':
<p>The string "${search_term}" was not found in any of the following information components for any library datasets that you can access.</p>
${render_searched_components()}
--- a/test/functional/test_library_security.py Tue Feb 01 11:20:02 2011 -0500
+++ b/test/functional/test_library_security.py Tue Feb 01 11:21:41 2011 -0500
@@ -300,7 +300,7 @@
library_id=self.security.encode_id( library1.id ),
ldda_ids=self.security.encode_id( ldda2.id ),
new_history_name='goodbye',
- strings_displayed=[ '1 dataset have been imported into 1 history' ] )
+ strings_displayed=[ '1 dataset imported into 1 history' ] )
self.logout()
# regular_user2 should not be able to see ldda2
self.login( email=regular_user2.email )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new changesets in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/d6559b2d69fc/
changeset: r4967:d6559b2d69fc
user: jgoecks
date: 2011-02-01 17:19:40
summary: Use classes instead of ids in tool menu URLs so that search works correctly when recently used menu is visible.
affected #: 1 file (6 bytes)
--- a/templates/root/tool_menu.mako Mon Jan 31 18:25:33 2011 -0500
+++ b/templates/root/tool_menu.mako Tue Feb 01 11:19:40 2011 -0500
@@ -21,9 +21,9 @@
## ${tool.description.replace( '[[', '<a href="link" target="galaxy_main">' % $tool.id ).replace( "]]", "</a>" )
<% tool_id = re.sub( '[^a-z0-9_]', '_', tool.id.lower() ) %>
%if tool.name:
- <a id="link-${tool_id}" href="${link}" target=${tool.target} minsizehint="${tool.uihints.get( 'minwidth', -1 )}">${_(tool.name)}</a> ${tool.description}
+ <a class="link-${tool_id}" href="${link}" target=${tool.target} minsizehint="${tool.uihints.get( 'minwidth', -1 )}">${_(tool.name)}</a> ${tool.description}
%else:
- <a id="link-${tool_id}" href="${link}" target=${tool.target} minsizehint="${tool.uihints.get( 'minwidth', -1 )}">${tool.description}</a>
+ <a class="link-${tool_id}" href="${link}" target=${tool.target} minsizehint="${tool.uihints.get( 'minwidth', -1 )}">${tool.description}</a>
%endif
</div>
%endif
@@ -140,7 +140,7 @@
$(".toolSectionWrapper").find(".toolTitle").hide();
if ( data.length != 0 ) {
// Map tool ids to element ids and join them.
- var s = $.map( data, function( n, i ) { return "#link-" + n.toLowerCase().replace(/[^a-z0-9_]/g,'_'); } ).join( ", " );
+ var s = $.map( data, function( n, i ) { return ".link-" + n.toLowerCase().replace(/[^a-z0-9_]/g,'_'); } ).join( ", " );
// First pass to show matching tools and their parents.
$(s).each( function() {
http://bitbucket.org/galaxy/galaxy-central/changeset/f9770f73f784/
changeset: r4968:f9770f73f784
user: jgoecks
date: 2011-02-01 17:20:02
summary: Merge.
affected #: 0 files (0 bytes)
--- a/datatypes_conf.xml.sample Tue Feb 01 11:19:40 2011 -0500
+++ b/datatypes_conf.xml.sample Tue Feb 01 11:20:02 2011 -0500
@@ -114,6 +114,7 @@
<datatype extension="taxonomy" type="galaxy.datatypes.tabular:Taxonomy" display_in_upload="true"/><datatype extension="tabular" type="galaxy.datatypes.tabular:Tabular" display_in_upload="true"/><datatype extension="txt" type="galaxy.datatypes.data:Text" display_in_upload="true"/>
+ <datatype extension="memexml" type="galaxy.datatypes.xml:MEMEXml" display_in_upload="true"/><datatype extension="blastxml" type="galaxy.datatypes.xml:BlastXml" display_in_upload="true"/><datatype extension="vcf" type="galaxy.datatypes.tabular:Vcf" display_in_upload="true"><converter file="vcf_to_interval_index_converter.xml" target_datatype="interval_index"/>
--- a/lib/galaxy/datatypes/xml.py Tue Feb 01 11:19:40 2011 -0500
+++ b/lib/galaxy/datatypes/xml.py Tue Feb 01 11:20:02 2011 -0500
@@ -39,3 +39,18 @@
line = line.rstrip( '\n\r' )
if line != blastxml_header[ i ]:
return False
+
+class MEMEXml( data.Text ):
+ """MEME XML Output data"""
+ file_ext = "memexml"
+
+ def set_peek( self, dataset, is_multi_byte=False ):
+ """Set the peek and blurb text"""
+ if not dataset.dataset.purged:
+ dataset.peek = data.get_file_peek( dataset.file_name, is_multi_byte=is_multi_byte )
+ dataset.blurb = 'MEME XML data'
+ else:
+ dataset.peek = 'file does not exist'
+ dataset.blurb = 'file purged from disk'
+ def sniff( self, filename ):
+ return False
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/meme/meme/meme_output_html_1.html Tue Feb 01 11:20:02 2011 -0500
@@ -0,0 +1,2819 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>MEME</title>
+<style type="text/css">
+ /* The following is the content of meme.css */
+ body { background-color:white; font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif;}
+
+ div.help {
+ display: inline-block;
+ margin: 0px;
+ padding: 0px;
+ width: 12px;
+ height: 13px;
+ background-image: url("help.gif");
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAANAQMAAACn5x0BAAAAAXNSR0IArs4c6QAAAAZQTFRFAAAAnp6eqp814gAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2gMJBQgGYqhNZQAAACZJREFUCNdj+P+BoUGAoV+AYeYEEGoWYGgTYGgRAAm2gRGQ8f8DAOnhC2lYnqs6AAAAAElFTkSuQmCC");
+ }
+
+ p.spaced { line-height: 1.8em;}
+
+ p.pad { padding-left: 30px; padding-top: 5px; padding-bottom: 10px;}
+
+ td.jump { font-size: 13px; color: #ffffff; background-color: #00666a;
+ font-family: Georgia, "Times New Roman", Times, serif;}
+
+ a.jump { margin: 15px 0 0; font-style: normal; font-variant: small-caps;
+ font-weight: bolder; font-family: Georgia, "Times New Roman", Times, serif;}
+
+ h2.mainh {font-size: 1.5em; font-style: normal; margin: 15px 0 0;
+ font-variant: small-caps; font-family: Georgia, "Times New Roman", Times, serif;}
+
+ h2.line {border-bottom: 1px solid #CCCCCC; font-size: 1.5em; font-style: normal;
+ margin: 15px 0 0; padding-bottom: 3px; font-variant: small-caps;
+ font-family: Georgia, "Times New Roman", Times, serif;}
+
+ h4 {border-bottom: 1px solid #CCCCCC; font-size: 1.2em; font-style: normal;
+ margin: 10px 0 0; padding-bottom: 3px; font-family: Georgia, "Times New Roman", Times, serif;}
+
+ h5 {margin: 0px}
+
+ a.help { font-size: 9px; font-style: normal; text-transform: uppercase;
+ font-family: Georgia, "Times New Roman", Times, serif;}
+
+ div.pad { padding-left: 30px; padding-top: 5px; padding-bottom: 10px;}
+
+ div.pad1 { margin: 10px 5px;}
+
+ div.pad2 { margin: 25px 5px 5px;}
+ h2.pad2 { padding: 25px 5px 5px;}
+
+ div.pad3 { padding: 5px 0px 10px 30px;}
+
+ div.box { border: 2px solid #CCCCCC; padding:10px;}
+
+ div.bar { border-left: 7px solid #00666a; padding:5px; margin-top:25px; }
+
+ div.subsection {margin:25px 0px;}
+
+ img {border:0px none;}
+
+ th.majorth {text-align:left;}
+ th.minorth {font-weight:normal; text-align:left; width:8em; padding: 3px 0px;}
+ th.actionth {font-weight:normal; text-align:left;}
+
+ .strand_name {text-align:left;}
+ .strand_side {padding:0px 10px;}
+ .strand_start {padding:0px 10px;}
+ .strand_pvalue {text-align:center; padding:0px 10px;}
+ .strand_lflank {text-align:right; padding-right:5px; font-weight:bold; font-size:large; font-family: 'Courier New', Courier, monospace; color:gray;}
+ .strand_seq {text-align:center; font-weight:bold; font-size:large; font-family: 'Courier New', Courier, monospace;}
+ .strand_rflank {text-align:left; padding-left:5px; font-weight:bold; font-size:large; font-family: 'Courier New', Courier, monospace; color:gray;}
+
+ .block_td {height:25px;}
+ .block_container {position:relative; width:99%; height:25px; padding:0px; margin:0px;}
+ .block_motif {position:absolute; z-index:3; height:12px; top:0px; text-align:center; vertical-align:middle; background-color:cyan;}
+ .block_rule {position:absolute; z-index:2; width:100%; height:1px; top:12px; left:0px; background-color:gray;}
+ .block_plus_sym {position:absolute; z-index:4; width:12px; height:12px; top:0px; left:0px; color:gray;}
+ .block_minus_sym {position:absolute; z-index:4; width:12px; height:12px; top:13px; left:0px; color:gray;}
+
+ .tic_major {position:absolute; border-left:2px solid blue; height:0.5em; top:0em;}
+ .tic_minor {position:absolute; border-left:1px solid blue; height:0.2em; top:0em;}
+ .tic_label {position:absolute; top:0.5em; height: 1em; text-align:center; vertical-align:middle}
+
+ .explain h5 {font-size:1em; margin-left: 1em;}
+
+ div.doc {margin-left: 2em; margin-bottom: 3em;}
+
+ div.tabArea {
+ font-size: 80%;
+ font-weight: bold;
+ }
+
+ a.tab {
+ background-color: #ddddff;
+ border: 1px solid #000000;
+ border-top-width: 0px;
+ padding: 2px 1em 2px 1em;
+ text-decoration: none;
+ }
+
+ a.tab, a.tab:visited {
+ color: #808080;
+ }
+
+ a.tab:hover {
+ background-color: #d0d0d0;
+ color: #606060;
+ }
+ a.tab.activeTab, a.tab.activeTab:hover, a.tab.activeTab:visited {
+ background-color: #f0f0f0;
+ color: #000000;
+ }
+ div.tabMain {
+ border: 1px solid #000000;
+ background-color: #ffffff;
+ padding: 5px;
+ margin-right: 5px;
+ }
+ th.trainingset {
+ border-bottom: thin dashed black;
+ font-weight:normal;
+ padding:0px 10px;
+ }
+
+ </style>
+<script type="text/javascript">
+ //======================================================================
+ // start Alphabet object
+ //======================================================================
+ function Alphabet(alphabet, bg) {
+ //variable prototype
+ this.freqs = new Array();
+ this.alphabet = new Array();
+ this.letter_count = 0;
+ //method prototype
+ this.get_ic = Alphabet_get_ic;
+ this.get_size = Alphabet_get_size;
+ this.get_index = Alphabet_get_index;
+ this.get_letter = Alphabet_get_letter;
+ this.get_colour = Alphabet_get_colour;
+ this.get_bg_freq = Alphabet_get_bg_freq;
+ this.is_nucleotide = Alphabet_is_nucleotide;
+ this.is_ambig = Alphabet_is_ambig;
+ this.toString = Alphabet_to_string;
+ //construct
+ var is_letter = /^\w$/;
+ var is_prob = /^((1(\.0+)?)|(0(\.\d+)?))$/;
+ for (var pos = 0; pos < alphabet.length; pos++) {
+ var letter = alphabet.charAt(pos);
+ if (is_letter.test(letter)) {
+ this.alphabet[this.letter_count] = letter.toUpperCase();
+ this.freqs[this.letter_count] = -1;
+ this.letter_count++;
+ }
+ }
+ if (!(bg === undefined)) {
+ var parts = bg.split(/\s+/);
+ for (var i = 0, pos = 0; (i + 1) < parts.length; i += 2) {
+ var letter = parts[i];
+ var freq = parts[i+1];
+ if (is_letter.test(letter) && is_prob.test(freq)) {
+ letter = letter.toUpperCase(); //find the letter it matches
+ for (;pos < this.letter_count; pos++) {
+ if (this.alphabet[pos] == letter) break;
+ }
+ if (pos >= this.letter_count) throw "NOT_IN_ALPHABET";
+ this.freqs[pos] = (+freq);
+ }
+ }
+ }
+ }
+
+
+ function Alphabet_get_ic() {
+ if (this.is_nucleotide()) {
+ return 2;
+ } else {
+ return Math.log(20) / Math.LN2;
+ }
+ }
+
+ function Alphabet_get_size() {
+ return this.letter_count;
+ }
+
+ function Alphabet_get_letter(alph_index) {
+ if (alph_index < 0 || alph_index >= this.letter_count) {
+ throw "BAD_ALPHABET_INDEX";
+ }
+ return this.alphabet[alph_index];
+ }
+
+ function Alphabet_get_bg_freq(alph_index) {
+ if (alph_index < 0 || alph_index >= this.letter_count) {
+ throw "BAD_ALPHABET_INDEX";
+ }
+ if (this.freqs[alph_index] == -1) throw "BG_FREQ_NOT_SET";
+ return this.freqs[alph_index];
+ }
+
+ function Alphabet_get_colour(alph_index) {
+ var red = "rgb(204,0,0)";
+ var blue = "rgb(0,0,204)";
+ var orange = "rgb(255,179,0)";
+ var green = "rgb(0,128,0)";
+ var yellow = "rgb(255,255,0)";
+ var purple = "rgb(204,0,204)";
+ var magenta = "rgb(255,0,255)";
+ var pink = "rgb(255,204,204)";
+ var turquoise = "rgb(51,230,204)";
+ if (alph_index < 0 || alph_index >= this.letter_count) {
+ throw "BAD_ALPHABET_INDEX";
+ }
+ if (this.is_nucleotide()) {
+ switch (this.alphabet[alph_index]) {
+ case "A":
+ return red;
+ case "C":
+ return blue;
+ case "G":
+ return orange;
+ case "T":
+ return green;
+ }
+ } else {
+ switch (this.alphabet[alph_index]) {
+ case "A":
+ case "C":
+ case "F":
+ case "I":
+ case "L":
+ case "V":
+ case "W":
+ case "M":
+ return blue;
+ case "N":
+ case "Q":
+ case "S":
+ case "T":
+ return green;
+ case "D":
+ case "E":
+ return magenta;
+ case "K":
+ case "R":
+ return red;
+ case "H":
+ return pink;
+ case "G":
+ return orange;
+ case "P":
+ return yellow;
+ case "Y":
+ return turquoise;
+ }
+ }
+ return "black";
+ }
+
+ function Alphabet_is_ambig(alph_index) {
+ if (alph_index < 0 || alph_index >= this.letter_count) {
+ throw "BAD_ALPHABET_INDEX";
+ }
+ if (this.is_nucleotide()) {
+ return ("ACGT".indexOf(this.alphabet[alph_index]) == -1);
+ } else {
+ return ("ACDEFGHIKLMNPQRSTVWY".indexOf(this.alphabet[alph_index]) == -1);
+ }
+ }
+
+ function Alphabet_get_index(letter) {
+ for (i = 0; i < this.letter_count; i++) {
+ if (this.alphabet[i] == letter.toUpperCase()) return i;
+ }
+ throw "UNKNOWN_LETTER";
+ }
+
+ function Alphabet_is_nucleotide() {
+ //TODO basic method, make better
+ if (this.letter_count < 20) return true;
+ return false;
+ }
+
+ function Alphabet_to_string() {
+ return (this.is_nucleotide() ? "Nucleotide" : "Protein") + " Alphabet " + (this.alphabet.join(""));
+ }
+
+ //======================================================================
+ // end Alphabet object
+ //======================================================================
+
+ //======================================================================
+ // start Symbol object
+ //======================================================================
+ function Symbol(alph_index, scale, alphabet) {
+ //variable prototype
+ this.symbol = alphabet.get_letter(alph_index);
+ this.scale = scale;
+ this.colour = alphabet.get_colour(alph_index);
+ //function prototype
+ this.get_symbol = Symbol_get_symbol;
+ this.get_scale = Symbol_get_scale;
+ this.get_colour = Symbol_get_colour;
+ this.toString = Symbol_to_string;
+ }
+
+ function Symbol_get_symbol() {
+ return this.symbol;
+ }
+
+ function Symbol_get_scale() {
+ return this.scale;
+ }
+
+ function Symbol_get_colour() {
+ return this.colour;
+ }
+
+ function Symbol_to_string() {
+ return this.symbol + " " + (Math.round(this.scale*1000)/10) + "%";
+ }
+
+ function compare_symbol(sym1, sym2) {
+ if (sym1.get_scale() < sym2.get_scale()) {
+ return -1;
+ } else if (sym1.get_scale() > sym2.get_scale()) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ //======================================================================
+ // end Symbol object
+ //======================================================================
+
+ //======================================================================
+ // start Pspm object
+ //======================================================================
+ function Pspm(pssm, name) {
+ //variable prototype
+ this.alph_length = 0;
+ this.motif_length = 0;
+ this.pspm = new Array();
+ this.name = (typeof name == "string" ? name : "");
+ this.nsites = 0;
+ this.evalue = 0;
+ //function prototype
+ this.copy = Pspm_copy;
+ this.reverse_complement = Pspm_reverse_complement;
+ this.get_stack = Pspm_get_stack;
+ this.get_stack_ic = Pspm_get_stack_ic;
+ this.get_motif_length = Pspm_get_motif_length;
+ this.get_alph_length = Pspm_get_alph_length;
+ this.toString = Pspm_to_string;
+ //construct
+ var pspm_header = /letter-probability matrix:\s+alength=\s+(\d+)\s+w=\s+(\d+)(\s+nsites=\s+(\S+))?(\s+E=\s+(\S+))?\s*/;
+ var is_prob = /^((1(\.0+)?)|(0(\.\d+)?))$/;
+ var is_empty = /^\s*$/;
+ var lines = pssm.split(/\s*\n\s*/);
+ var read_pssm = false;
+ var line_num = 0;
+ var col_num = 0;
+ for (line_index in lines) {
+ //exclude inherited properties and undefined properties
+ if (!lines.hasOwnProperty(line_index) || lines[line_index] === undefined) continue;
+
+ var line = lines[line_index];
+ if (is_empty.test(line)) {
+ continue;
+ }
+ if (!read_pssm) {
+ var header_match = pspm_header.exec(line);
+ if (header_match != null) {
+ read_pssm = true;
+ this.alph_length = (+header_match[1]);
+ this.motif_length = (+header_match[2]);
+ if (header_match[4]) this.nsites = parseFloat(header_match[4]);//not always an integer
+ if (header_match[6]) this.evalue = parseFloat(header_match[6]);
+ this.pspm = new Array(this.motif_length);
+ }
+ continue;
+ }
+ if (line_num >= this.motif_length) {
+ throw "TOO_MANY_ROWS";
+ }
+ this.pspm[line_num] = new Array(this.alph_length);
+ col_num = 0;
+ var parts = line.split(/\s+/);
+ for (part_index in parts) {
+ //exclude inherited properties and undefined properties
+ if (!parts.hasOwnProperty(part_index) || parts[part_index] === undefined) continue;
+
+ var prob = parts[part_index];
+ if (!is_prob.test(prob)) continue;
+ if (col_num >= this.alph_length) {
+ throw "TOO_MANY_COLS";
+ }
+ this.pspm[line_num][col_num] = (+prob);
+ col_num++;
+ }
+ if (col_num != this.alph_length) {
+ throw "TOO_FEW_COLS";
+ }
+ line_num++;
+ }
+ if (line_num != this.motif_length) {
+ throw "TOO_FEW_ROWS";
+ }
+ }
+
+ function Clone() {}
+
+ function Pspm_copy() {
+ Clone.prototype = this;
+ var clone = new Clone();
+ //so far only a shallow copy, need to copy everything
+ clone.alph_length = (0+this.alph_length);
+ clone.motif_length = (0+this.motif_length);
+ clone.pspm = new Array(this.motif_length);
+ for (row = 0; row < this.motif_length; row++) {
+ clone.pspm[row] = new Array(this.alph_length);
+ for (col = 0; col < this.alph_length; col++) {
+ clone.pspm[row][col] = (0+this.pspm[row][col]);
+ }
+ }
+ return clone;
+ }
+
+ function Pspm_reverse_complement(alphabet) {
+ if (this.alph_length != alphabet.get_size()) {
+ throw "ALPHABET_MISMATCH";
+ }
+ if (!alphabet.is_nucleotide()) {
+ throw "NO_PROTEIN_RC";
+ }
+ //reverse
+ var x = 0;
+ var y = this.motif_length-1;
+ while (x < y) {
+ var temp = this.pspm[x];
+ this.pspm[x] = this.pspm[y];
+ this.pspm[y] = temp;
+ x++;
+ y--;
+ }
+ //complement
+ var a_index = alphabet.get_index("A");
+ var c_index = alphabet.get_index("C");
+ var g_index = alphabet.get_index("G");
+ var t_index = alphabet.get_index("T");
+ for (i = 0; i < this.motif_length; i++) {
+ var row = this.pspm[i];
+ //swap A and T
+ var temp = row[a_index];
+ row[a_index] = row[t_index];
+ row[t_index] = temp;
+ //swap C and G
+ temp = row[c_index];
+ row[c_index] = row[g_index];
+ row[g_index] = temp;
+ }
+ //note that ambigs are ignored because they don't effect motifs
+ return this; //allow function chaining...
+ }
+
+ function Pspm_get_stack(position, alphabet) {
+ if (this.alph_length != alphabet.get_size()) {
+ throw "ALPHABET_MISMATCH";
+ }
+ var row = this.pspm[position];
+ var stack_ic = this.get_stack_ic(position, alphabet);
+ var alphabet_ic = alphabet.get_ic();
+ var stack = new Array();
+ for (i = 0; i < this.alph_length; i++) {
+ if (alphabet.is_ambig(i)) continue;
+ var sym = new Symbol(i, row[i]*stack_ic/alphabet_ic, alphabet);
+ if (sym.get_scale() <= 0) continue;
+ stack.push(sym);
+ }
+ stack.sort(compare_symbol);
+ return stack;
+ }
+
+ function Pspm_get_stack_ic(position, alphabet) {
+ if (this.alph_length != alphabet.get_size()) {
+ throw "ALPHABET_MISMATCH";
+ }
+ var row = this.pspm[position];
+ var H = 0;
+ for (var i = 0; i < this.alph_length; i++) {
+ if (alphabet.is_ambig(i)) continue;
+ if (row[i] == 0) continue;
+ H -= (row[i] * (Math.log(row[i]) / Math.LN2));
+ }
+ return alphabet.get_ic() - H;
+ }
+
+ function Pspm_get_error(alphabet) {
+ var asize;
+ if (this.nsites == 0) return 0;
+ if (alphabet.is_nucleotide()) {
+ asize = 4;
+ } else {
+ asize = 20;
+ }
+ return (asize-1) / (2 * Math.log(2)*this.nsites);
+ }
+
+ function Pspm_get_motif_length() {
+ return this.motif_length;
+ }
+
+ function Pspm_get_alph_length() {
+ return this.alph_length;
+ }
+
+ function Pspm_to_string() {
+ var str = "";
+ for (row_index in this.pspm) {
+ //exclude inherited properties and undefined properties
+ if (!this.pspm.hasOwnProperty(row_index) || this.pspm[row_index] === undefined) continue;
+
+ var row = this.pspm[row_index];
+ str += row.join("\t") + "\n";
+ }
+ return str;
+ }
+ //======================================================================
+ // end Pspm object
+ //======================================================================
+
+ //======================================================================
+ // start Logo object
+ //======================================================================
+ function Logo(alphabet, fine_text) {
+ this.alphabet = alphabet;
+ this.fine_text = fine_text;
+ this.pspm_list = [];
+ this.pspm_column = [];
+ this.rows = 0;
+ this.columns = 0;
+
+ //functions
+ this.add_pspm = Logo_add_pspm;
+ this.get_columns = Logo_get_columns;
+ this.get_rows = Logo_get_rows;
+ this.get_pspm = Logo_get_pspm;
+ this.get_offset = Logo_get_offset;
+ }
+
+ function Logo_add_pspm(pspm, column) {
+ if (column === undefined) column = 0;
+ else if (column < 0) throw "COLUMN_OUT_OF_BOUNDS";
+ this.pspm_list[this.rows] = pspm;
+ this.pspm_column[this.rows] = column;
+ this.rows++;
+ var col = column + pspm.get_motif_length();
+ if (col > this.columns) this.columns = col;
+ }
+
+ function Logo_get_columns() {
+ return this.columns;
+ }
+
+ function Logo_get_rows() {
+ return this.rows;
+ }
+
+ function Logo_get_pspm(row_index) {
+ if (row_index < 0 || row_index >= this.rows) throw "INDEX_OUT_OF_BOUNDS";
+ return this.pspm_list[row_index];
+ }
+
+ function Logo_get_offset(row_index) {
+ if (row_index < 0 || row_index >= this.rows) throw "INDEX_OUT_OF_BOUNDS";
+ return this.pspm_column[row_index];
+ }
+
+ //======================================================================
+ // end Logo object
+ //======================================================================
+
+ //======================================================================
+ // start RasterizedAlphabet
+ //======================================================================
+
+ // Rasterize Alphabet
+ // 1) Measure width of text at default font for all symbols in alphabet
+ // 2) sort in width ascending
+ // 3) Drop the top and bottom 10% (designed to ignore outliers like 'W' and 'I')
+ // 4) Calculate the average as the maximum scaling factor (designed to stop I becoming a rectangular blob).
+ // 5) Assume scale of zero would result in width of zero, interpolate scale required to make perfect width font
+ // 6) Draw text onto temp canvas at calculated scale
+ // 7) Find bounds of drawn text
+ // 8) Paint on to another canvas at the desired height (but only scaling width to fit if larger).
+ function RasterizedAlphabet(alphabet, font, target_width) {
+ //variable prototypes
+ this.lookup = []; //a map of letter to index
+ this.rasters = []; //a list of rasters
+ this.dimensions = []; //a list of dimensions
+
+ //function prototypes
+ this.draw = RasterizedAlphabet_draw;
+
+ //construct
+ var default_size = 60; // size of square to assume as the default width
+ var safety_pad = 20; // pixels to pad around so we don't miss the edges
+ // create a canvas to do our rasterizing on
+ var canvas = document.createElement("canvas");
+ // assume the default font would fit in a canvas of 100 by 100
+ canvas.width = default_size + 2 * safety_pad;
+ canvas.height = default_size + 2 * safety_pad;
+ // check for canvas support before attempting anything
+ if (!canvas.getContext) throw "NO_CANVAS_SUPPORT";
+ var ctx = canvas.getContext('2d');
+ // check for html5 text drawing support
+ if (!supports_text(ctx)) throw "NO_CANVAS_TEXT_SUPPORT";
+ // calculate the middle
+ var middle = Math.round(canvas.width / 2);
+ // calculate the baseline
+ var baseline = Math.round(canvas.height - safety_pad);
+ // list of widths
+ var widths = [];
+ var count = 0;
+ var letters = [];
+ //now measure each letter in the alphabet
+ for (var i = 0; i < alphabet.get_size(); ++i) {
+ if (alphabet.is_ambig(i)) continue; //skip ambigs as they're never rendered
+ var letter = alphabet.get_letter(i);
+ letters.push(letter);
+ var pos = count++;
+ this.lookup[letter] = pos;
+ //clear the canvas
+ canvas.width = canvas.width;
+ // get the context and prepare to draw our width test
+ var ctx = canvas.getContext('2d');
+ ctx.font = font;
+ ctx.fillStyle = alphabet.get_colour(i);
+ ctx.textAlign = "center";
+ ctx.translate(middle, baseline);
+ // draw the test text
+ ctx.fillText(letter, 0, 0);
+ //measure
+ var size = RasterizedAlphabet_measure(ctx, canvas.width, canvas.height);
+ if (size.width == 0) throw "INVISIBLE_LETTER"; //maybe the fill was white on white?
+ widths.push(size.width);
+ this.dimensions[pos] = size;
+ }
+ //sort the widths
+ widths.sort(function(a,b) {return a - b;});
+ //drop 10% of the items off each end
+ var tenpercent = Math.floor(widths.length / 10);
+ for (var i = 0; i < tenpercent; ++i) {
+ widths.pop();
+ widths.shift();
+ }
+ //calculate average width
+ var avg_width = 0;
+ for (var i = 0; i < widths.length; ++i) avg_width += widths[i];
+ avg_width /= widths.length;
+ // calculate scales
+ for (var i = 0; i < this.dimensions.length; ++i) {
+ var size = this.dimensions[i];
+ // calculate scale
+ var scale = target_width / Math.max(avg_width, size.width);
+ // estimate scaled height
+ var target_height = size.height * scale;
+ // create an approprately sized canvas
+ var raster = document.createElement("canvas");
+ raster.width = target_width; // if it goes over the edge too bad...
+ raster.height = target_height + safety_pad * 2;
+ // calculate the middle
+ middle = Math.round(raster.width / 2);
+ // calculate the baseline
+ baseline = Math.round(raster.height - safety_pad);
+ // get the context and prepare to draw the rasterized text
+ ctx = raster.getContext('2d');
+ ctx.font = font;
+ ctx.fillStyle = alphabet.get_colour(i);
+ ctx.textAlign = "center";
+ ctx.translate(middle, baseline);
+ ctx.save();
+ ctx.scale(scale, scale);
+ // draw the rasterized text
+ ctx.fillText(letters[i], 0, 0);
+ ctx.restore();
+ this.rasters[i] = raster;
+ this.dimensions[i] = RasterizedAlphabet_measure(ctx, raster.width, raster.height);
+ }
+ }
+
+ function RasterizedAlphabet_measure(ctx, cwidth, cheight) {
+ var data = ctx.getImageData(0, 0, cwidth, cheight).data;
+ var r = 0, c = 0;// r: row, c: column
+ var top_line = -1, bottom_line = -1, left_line = -1, right_line = -1;
+ var txt_width = 0, txt_height = 0;
+ // Find the top-most line with a non-white pixel
+ for (r = 0; r < cheight; r++) {
+ for (c = 0; c < cwidth; c++) {
+ if (data[r * cwidth * 4 + c * 4 + 3]) {
+ top_line = r;
+ break;
+ }
+ }
+ if (top_line != -1) break;
+ }
+
+ //find the last line with a non-white pixel
+ if (top_line != -1) {
+ for (r = cheight-1; r >= top_line; r--) {
+ for(c = 0; c < cwidth; c++) {
+ if(data[r * cwidth * 4 + c * 4 + 3]) {
+ bottom_line = r;
+ break;
+ }
+ }
+ if (bottom_line != -1) break;
+ }
+ txt_height = bottom_line - top_line + 1;
+ }
+
+ // Find the left-most line with a non-white pixel
+ for (c = 0; c < cwidth; c++) {
+ for (r = 0; r < cheight; r++) {
+ if (data[r * cwidth * 4 + c * 4 + 3]) {
+ left_line = c;
+ break;
+ }
+ }
+ if (left_line != -1) break;
+ }
+
+ //find the right most line with a non-white pixel
+ if (left_line != -1) {
+ for (c = cwidth-1; c >= left_line; c--) {
+ for(r = 0; r < cheight; r++) {
+ if(data[r * cwidth * 4 + c * 4 + 3]) {
+ right_line = c;
+ break;
+ }
+ }
+ if (right_line != -1) break;
+ }
+ txt_width = right_line - left_line + 1;
+ }
+
+ //return the bounds
+ return {bound_top: top_line, bound_bottom: bottom_line, bound_left: left_line, bound_right: right_line, width: txt_width, height: txt_height};
+ }
+
+ function RasterizedAlphabet_draw(ctx, letter, dx, dy, dWidth, dHeight) {
+ var index = this.lookup[letter];
+ var raster = this.rasters[index];
+ var size = this.dimensions[index];
+ ctx.drawImage(raster, 0, size.bound_top -1, raster.width, size.height+1, dx, dy, dWidth, dHeight);
+ }
+
+ //======================================================================
+ // end RasterizedAlphabet
+ //======================================================================
+
+ //======================================================================
+ // start LogoMetrics object
+ //======================================================================
+
+ function LogoMetrics(ctx, canvas_width, canvas_height, logo_columns, logo_rows, allow_space_for_names) {
+ if (allow_space_for_names === undefined) allow_space_for_names = false;
+ //variable prototypes
+ this.canvas_width = canvas_width;
+ this.canvas_height = canvas_height;
+ this.scale_x = 1;
+ this.scale_y = 1;
+ this.pad_top = 5;
+ this.pad_left = 10;
+ this.pad_right = 5;
+ this.pad_bottom = 0;
+ this.pad_middle = 20;
+ this.name_height = 14;
+ this.name_font = "bold " + this.name_height + "px Times, sans-serif";
+ this.name_spacer = 0;
+ this.y_label = "bits"
+ this.y_label_height = 12;
+ this.y_label_font = "bold " + this.y_label_height + "px Helvetica, sans-serif";
+ this.y_label_spacer = 3;
+ this.y_num_height = 12;
+ this.y_num_width = 0;
+ this.y_num_font = "bold " + this.y_num_height + "px Helvetica, sans-serif";
+ this.y_tic_width = 5;
+ this.stack_pad_left = 0;
+ this.stack_font = "bold 25px Helvetica, sans-serif";
+ this.stack_height = 90;
+ this.stack_width = 26;
+ this.stacks_pad_right = 5;
+ this.x_num_above = 2;
+ this.x_num_height = 12;
+ this.x_num_width = 0;
+ this.x_num_font = "bold " + this.x_num_height + "px Helvetica, sans-serif";
+ this.fine_txt_height = 6;
+ this.fine_txt_above = 2;
+ this.fine_txt_font = "normal " + this.fine_txt_height + "px Helvetica, sans-serif";
+ this.letter_metrics = new Array();
+ this.summed_width = 0;
+ this.summed_height = 0;
+ //function prototypes
+ //none
+ //calculate the width of the y axis numbers
+ ctx.font = this.y_num_font;
+ for (var i = 0; i <= 2; i++) {
+ this.y_num_width = Math.max(this.y_num_width, ctx.measureText("" + i).width);
+ }
+ //calculate the width of the x axis numbers (but they are rotated so it becomes height)
+ ctx.font = this.x_num_font;
+ for (var i = 1; i <= logo_columns; i++) {
+ this.x_num_width = Math.max(this.x_num_width, ctx.measureText("" + i).width);
+ }
+
+ //calculate how much vertical space we want to draw this
+ //first we add the padding at the top and bottom since that's always there
+ this.summed_height += this.pad_top + this.pad_bottom;
+ //all except the last row have the same amount of space allocated to them
+ if (logo_rows > 1) {
+ var row_height = this.stack_height + this.pad_middle;
+ if (allow_space_for_names) {
+ row_height += this.name_height;
+ //the label is allowed to overlap into the spacer
+ row_height += Math.max(this.y_num_height/2, this.name_spacer);
+ //the label is allowed to overlap the space used by the other label
+ row_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above);
+ } else {
+ row_height += this.y_num_height/2;
+ //the label is allowed to overlap the space used by the other label
+ row_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above);
+ }
+ this.summed_height += row_height * (logo_rows - 1);
+ }
+ //the last row has the name and fine text below it but no padding
+ this.summed_height += this.stack_height + this.y_num_height/2;
+ if (allow_space_for_names) {
+ this.summed_height += this.fine_txt_height + this.fine_txt_above + this.name_height;
+ this.summed_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above + this.name_spacer);
+ } else {
+ this.summed_height += Math.max(this.y_num_height/2, this.x_num_height + this.x_num_above + this.fine_txt_height + this.fine_txt_above);
+ }
+
+ //calculate how much horizontal space we want to draw this
+ //first add the padding at the left and right since that's always there
+ this.summed_width += this.pad_left + this.pad_right;
+ //add on the space for the y-axis label
+ this.summed_width += this.y_label_height + this.y_label_spacer;
+ //add on the space for the y-axis
+ this.summed_width += this.y_num_width + this.y_tic_width;
+ //add on the space for the stacks
+ this.summed_width += (this.stack_pad_left + this.stack_width) * logo_columns;
+ //add on the padding after the stacks (an offset from the fine text)
+ this.summed_width += this.stacks_pad_right;
+
+ //calculate scaling factors
+ this.scale_y = this.canvas_height / this.summed_height;
+ this.scale_x = this.canvas_width / this.summed_width;
+
+ //maintain aspect ratio
+ if (this.scale_y > this.scale_x) {
+ this.scale_y = this.scale_x;
+ } else {
+ this.scale_x = this.scale_y;
+ }
+
+
+ }
+
+ //======================================================================
+ // end LogoMetrics object
+ //======================================================================
+
+
+ //found this trick at http://talideon.com/weblog/2005/02/detecting-broken-images-js.cfm
+ function image_ok(img) {
+ // During the onload event, IE correctly identifies any images that
+ // weren't downloaded as not complete. Others should too. Gecko-based
+ // browsers act like NS4 in that they report this incorrectly.
+ if (!img.complete) {
+ return false;
+ }
+ // However, they do have two very useful properties: naturalWidth and
+ // naturalHeight. These give the true size of the image. If it failed
+ // to load, either of these should be zero.
+ if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
+ return false;
+ }
+ // No other way of checking: assume it's ok.
+ return true;
+ }
+
+ function supports_text(ctx) {
+ if (!ctx.fillText) return false;
+ if (!ctx.measureText) return false;
+ return true;
+ }
+
+ //draws the scale, returns the width
+ function draw_scale(ctx, metrics, alphabet_ic) {
+ var tic_height = metrics.stack_height / alphabet_ic;
+ ctx.save();
+ ctx.lineWidth = 1.5;
+ ctx.translate(metrics.y_label_height, metrics.y_num_height/2);
+ //draw the axis label
+ ctx.save();
+ ctx.font = metrics.y_label_font;
+ ctx.translate(0, metrics.stack_height/2);
+ ctx.save();
+ ctx.rotate(-(Math.PI / 2));
+ ctx.textAlign = "center";
+ ctx.fillText("bits", 0, 0);
+ ctx.restore();
+ ctx.restore();
+
+ ctx.translate(metrics.y_label_spacer + metrics.y_num_width, 0);
+
+ //draw the axis tics
+ ctx.save();
+ ctx.translate(0, metrics.stack_height);
+ ctx.font = metrics.y_num_font;
+ ctx.textAlign = "right";
+ ctx.textBaseline = "middle";
+ for (var i = 0; i <= alphabet_ic; i++) {
+ //draw the number
+ ctx.fillText("" + i, 0, 0);
+ //draw the tic
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(metrics.y_tic_width, 0);
+ ctx.stroke();
+ //prepare for next tic
+ ctx.translate(0, -tic_height);
+ }
+ ctx.restore();
+
+ ctx.translate(metrics.y_tic_width, 0);
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, metrics.stack_height);
+ ctx.stroke();
+
+ ctx.restore();
+ }
+
+ function draw_stack_num(ctx, metrics, row_index) {
+ ctx.save();
+ ctx.font = metrics.x_num_font;
+ ctx.translate(metrics.stack_width / 2, metrics.stack_height + metrics.x_num_above);
+ ctx.save();
+ ctx.rotate(-(Math.PI / 2));
+ ctx.textBaseline = "middle"
+ ctx.textAlign = "right"
+ ctx.fillText("" + (row_index + 1), 0, 0);
+ ctx.restore();
+ ctx.restore();
+ }
+
+ function draw_stack(ctx, metrics, symbols, raster) {
+ var preferred_pad = 0;
+ var sym_min = 5;
+
+ ctx.save();//1
+ ctx.translate(0, metrics.stack_height);
+ for (var i in symbols) {
+ //exclude inherited properties and undefined properties
+ if (!symbols.hasOwnProperty(i) || symbols[i] === undefined) continue;
+
+ var sym = symbols[i];
+ var sym_height = metrics.stack_height * sym.get_scale();
+
+ var pad = preferred_pad;
+ if (sym_height - pad < sym_min) {
+ pad = Math.min(pad, Math.max(0, sym_height - sym_min));
+ }
+ sym_height -= pad;
+
+ //translate to the correct position
+ ctx.translate(0, -(pad/2 + sym_height));
+ //draw
+ raster.draw(ctx, sym.get_symbol(), 0, 0, metrics.stack_width, sym_height);
+ //translate past the padding
+ ctx.translate(0, -(pad/2));
+ }
+ ctx.restore();//1
+ }
+
+ //draws a stack of symbols
+ function draw_stack_old(ctx, metrics, symbols) {
+ var lpad = 2;
+ var sym_min = 5;
+ var pos = metrics.stack_height;
+ for (var i in symbols) {
+ //exclude inherited properties and undefined properties
+ if (!symbols.hasOwnProperty(i) || symbols[i] === undefined) continue;
+
+ var sym = symbols[i];
+ var sym_height = metrics.stack_height*sym.get_scale();
+ var letter = metrics.get_letter_metrics(sym.get_symbol());
+ //attempting to draw something smaller than a pixel causes display corruption
+ if (sym_height >= 1) {
+ //it's better to see the letter than to pad it
+ var pad = lpad;
+ if (sym_height - pad < sym_min) {
+ pad = Math.min(pad, Math.max(0, sym_height - sym_min));
+ }
+ //move to the correct drawing position
+ ctx.save();//s1
+ ctx.translate(0, pos);
+ //create a clipping rectangle to ensure the letter doesn't overlap when it's distorted
+ ctx.save();//s2
+ //ctx.beginPath(); //disabled clipping because after the improvements in the text metrics it looks better without
+ //ctx.moveTo(-metrics.stack_width/2,0);
+ //ctx.lineTo(metrics.stack_width/2, 0);
+ //ctx.lineTo(metrics.stack_width/2, -sym_height);
+ //ctx.lineTo(-metrics.stack_width/2, -sym_height);
+ //ctx.lineTo(-metrics.stack_width/2,0);
+ //ctx.clip();
+ //now draw
+ ctx.translate(0, -(pad/2));
+ ctx.translate(0, -letter.get_descent(sym_height - pad));
+ ctx.fillStyle = sym.get_colour();
+ ctx.textAlign = "center";
+ ctx.save();//s3
+ ctx.scale(letter.wscale, letter.get_hscale(sym_height - pad));
+ ctx.fillText(sym.get_symbol(), 0, 0);
+ ctx.restore();//s3
+
+ ctx.restore();//s2
+ ctx.restore();//s1
+ }
+
+ pos = pos - sym_height;
+ }
+ }
+
+ function draw_logo_on_canvas(logo, canvas, show_names, scale) {
+ var draw_name = (typeof show_names == "boolean" ? show_names : (logo.get_rows() > 1));
+ var cwidth = canvas.width;
+ var cheight = canvas.height;
+ //need a minimum 46 x 120 canvas to draw the font size checks on
+ if (canvas.width < 46) canvas.width = 46;
+ if (canvas.height < 120) canvas.height = 120;
+ var ctx = canvas.getContext('2d');
+ //assume that the user wants the canvas scaled equally so calculate what the best width for this image should be
+ var metrics = new LogoMetrics(ctx, canvas.width, canvas.height, logo.get_columns(), logo.get_rows(), draw_name);
+ ctx.save();//s1
+ if (typeof scale == "number") {
+ //resize the canvas to fit the scaled logo
+ cwidth = metrics.summed_width * scale;
+ cheight = metrics.summed_height * scale;
+ } else {
+ if (cwidth == 0 || cheight == 0 || scale == 0) {
+ throw "CANVAS_MUST_HAVE_DIMENSIONS";
+ }
+ scale = Math.min(cwidth / metrics.summed_width, cheight / metrics.summed_height);
+ }
+ var raster = new RasterizedAlphabet(logo.alphabet, metrics.stack_font, metrics.stack_width * scale * 2);
+ if (cwidth != canvas.width || cheight != canvas.height) {
+ canvas.width = cwidth;
+ canvas.height = cheight;
+ //as the canvas has been resized the context is now out of date
+ ctx = canvas.getContext('2d');
+ }
+ ctx.scale(scale, scale);
+ ctx.save();//s2
+ ctx.save();//s7
+ //create margin
+ ctx.translate(metrics.pad_left, metrics.pad_top);
+ for (var pspm_i = 0; pspm_i < logo.get_rows(); ++pspm_i) {
+ var pspm = logo.get_pspm(pspm_i);
+ var offset = logo.get_offset(pspm_i);
+ //optionally draw name if this isn't the last row or is the only row
+ if (draw_name && (logo.get_rows() == 1 || pspm_i != (logo.get_rows()-1))) {
+ ctx.save();//s4
+ ctx.translate(metrics.summed_width/2, metrics.name_height);
+ ctx.font = metrics.name_font;
+ ctx.textAlign = "center";
+ ctx.fillText(pspm.name, 0, 0);
+ ctx.restore();//s4
+ ctx.translate(0, metrics.name_height + Math.min(0, metrics.name_spacer - metrics.y_num_height/2));
+ }
+ //draw scale
+ draw_scale(ctx, metrics, logo.alphabet.get_ic());
+ ctx.save();//s5
+ //translate across past the scale
+ ctx.translate(metrics.y_label_height + metrics.y_label_spacer +
+ metrics.y_num_width + metrics.y_tic_width, 0);
+ //draw letters
+ ctx.translate(0, metrics.y_num_height / 2);
+ for (var col_index = 0; col_index < logo.get_columns(); col_index++) {
+ ctx.translate(metrics.stack_pad_left,0);
+ if (col_index >= offset && col_index < (offset + pspm.get_motif_length())) {
+ var motif_position = col_index - offset;
+ draw_stack_num(ctx, metrics, motif_position);
+ draw_stack(ctx, metrics, pspm.get_stack(motif_position, logo.alphabet), raster);
+ }
+ ctx.translate(metrics.stack_width, 0);
+ }
+ ctx.restore();//s5
+ ////optionally draw name if this is the last row but isn't the only row
+ if (draw_name && (logo.get_rows() != 1 && pspm_i == (logo.get_rows()-1))) {
+ //translate vertically past the stack and axis's
+ ctx.translate(0, metrics.y_num_height/2 + metrics.stack_height +
+ Math.max(metrics.y_num_height/2, metrics.x_num_above + metrics.x_num_width + metrics.name_spacer));
+
+ ctx.save();//s6
+ ctx.translate(metrics.summed_width/2, metrics.name_height);
+ ctx.font = metrics.name_font;
+ ctx.textAlign = "center";
+ ctx.fillText(pspm.name, 0, 0);
+ ctx.restore();//s6
+ ctx.translate(0, metrics.name_height);
+ } else {
+ //translate vertically past the stack and axis's
+ ctx.translate(0, metrics.y_num_height/2 + metrics.stack_height + Math.max(metrics.y_num_height/2, metrics.x_num_above + metrics.x_num_width));
+ }
+ //if not the last row then add middle padding
+ if (pspm_i != (logo.get_rows() -1)) {
+ ctx.translate(0, metrics.pad_middle);
+ }
+ }
+ ctx.restore();//s7
+ ctx.translate(metrics.summed_width - metrics.pad_right, metrics.summed_height - metrics.pad_bottom);
+ ctx.font = metrics.fine_txt_font;
+ ctx.textAlign = "right";
+ ctx.fillText(logo.fine_text, 0,0);
+ ctx.restore();//s2
+ ctx.restore();//s1
+ }
+
+ function create_canvas(c_width, c_height, c_id, c_title, c_display) {
+ var canvas = document.createElement("canvas");
+ //check for canvas support before attempting anything
+ if (!canvas.getContext) return null;
+ var ctx = canvas.getContext('2d');
+ //check for html5 text drawing support
+ if (!supports_text(ctx)) return null;
+ //size the canvas
+ canvas.width = c_width;
+ canvas.height = c_height;
+ canvas.id = c_id;
+ canvas.title = c_title;
+ canvas.style.display = c_display;
+ return canvas;
+ }
+
+ function logo_1(alphabet, fine_text, pspm) {
+ var logo = new Logo(alphabet, fine_text);
+ logo.add_pspm(pspm);
+ return logo;
+ }
+
+ function logo_2(alphabet, fine_text, target, query, query_offset) {
+ var logo = new Logo(alphabet, fine_text);
+ if (query_offset < 0) {
+ logo.add_pspm(target, -query_offset);
+ logo.add_pspm(query);
+ } else {
+ logo.add_pspm(target);
+ logo.add_pspm(query, query_offset);
+ }
+ return logo;
+ }
+
+ /*
+ * Specifies an alternate source for an image.
+ * If the image with the image_id specified has
+ * not loaded then a generated logo will be used
+ * to replace it.
+ *
+ * Note that the image must either have dimensions
+ * or a scale must be set.
+ */
+ function alternate_logo(logo, image_id, scale) {
+ var image = document.getElementById(image_id);
+ if (!image) {
+ alert("Can't find specified image id (" + image_id + ")");
+ return;
+ }
+ //if the image has loaded then there is no reason to use the canvas
+ if (image_ok(image)) return;
+ //the image has failed to load so replace it with a canvas if we can.
+ var canvas = create_canvas(image.width, image.height, image_id, image.title, image.style.display);
+ if (canvas == null) return;
+ //draw the logo on the canvas
+ draw_logo_on_canvas(logo, canvas, undefined, scale);
+ //replace the image with the canvas
+ image.parentNode.replaceChild(canvas, image);
+ }
+
+ /*
+ * Specifes that the element with the specified id
+ * should be replaced with a generated logo.
+ */
+ function replace_logo(logo, replace_id, scale, title_txt, display_style) {
+ var element = document.getElementById(replace_id);
+ if (!replace_id) {
+ alert("Can't find specified id (" + replace_id + ")");
+ return;
+ }
+ //found the element!
+ var canvas = create_canvas(50, 120, replace_id, title_txt, display_style);
+ if (canvas == null) return;
+ //draw the logo on the canvas
+ draw_logo_on_canvas(logo, canvas, undefined, scale);
+ //replace the element with the canvas
+ element.parentNode.replaceChild(canvas, element);
+ }
+
+ //example code for creating a logo
+ //function do_load() {
+ // var alphabet = new Alphabet(document.getElementById("alphabet").value, document.getElementById("bgfreq").value);
+ // var pspm = new Pspm(document.getElementById("pspm1").value);
+ // var pspm_rc = pspm.copy().reverse_complement(alphabet);
+ // draw_logo(pspm, alphabet, "Motif 1", "logo1");
+ // draw_logo(pspm_rc, alphabet, "Motif 1 Reverse Complement", "logo_rc1");
+ //}
+
+
+ function setup() {
+ var motif_count = 1;
+ //create canvas logos
+ var alphabet = new Alphabet(document.getElementById("alphabet").value, document.getElementById("bgfreq").value);
+ for (var i = 1; i <= motif_count; i++) {
+ var pspm = new Pspm(document.getElementById("pspm" + i).value);
+ var logo = logo_1(alphabet, "MEME", pspm);
+ alternate_logo(logo, "thumbnail_logo_" + i, 0.5);
+ alternate_logo(logo, "logo_img_" + i, 1);
+
+ }
+
+ //ensure radio buttons have data generated for them by fireing events
+ var allInputs = document.getElementsByTagName("input");
+ for (var i = 0; i < allInputs.length; i++) {
+ var input = allInputs[i];
+ if (input.type == "radio" && input.checked) {
+ var evt = document.createEvent("MouseEvents");
+ evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ input.dispatchEvent(evt);
+ }
+ }
+
+ for (var i = 1; i <= motif_count; i++) {
+ tbl = document.getElementById("tbl_sites_" + i);
+ wireUpTable(tbl, false);
+ tbl = document.getElementById("tbl_blocks_" + i);
+ wireUpTable(tbl, true);
+ }
+ }
+ function showDesc(source, targetid) {
+ document.getElementById(targetid).childNodes[0].nodeValue = source.title;
+ }
+ function hideDesc(targetid) {
+ document.getElementById(targetid).childNodes[0].nodeValue = "Mouse-over buttons for more information.";
+ }
+ function showEmbededFormat(motifnum, format) {
+ var source = document.getElementById(format + motifnum);
+ var txtarea = document.getElementById("format_display_area_" + motifnum);
+ txtarea.value = source.value;
+ txtarea.style.display = 'block';
+ }
+ function hideFormat(motifnum) {
+ var txtarea = document.getElementById("format_display_area_" + motifnum);
+ txtarea.style.display = 'none';
+ }
+ function block2raw(block) {
+ var raw = "";
+ var endpat = /\/\//;
+ var wordpat = /\S+/gi;
+ var lines = block.split("\n");
+ for (i = 2; i < lines.length; ++i) {
+ if (lines[i].match(endpat) != null) break;
+ var words = lines[i].match(wordpat);
+ raw += words[3] + "\n";
+ }
+ return raw;
+ }
+ function block2fasta(block) {
+ var fasta = "";
+ var endpat = /\/\//;
+ var wordpat = /\S+/gi;
+ var lines = block.split("\n");
+ for (i = 2; i < lines.length; ++i) {
+ if (lines[i].match(endpat) != null) break;
+ var words = lines[i].match(wordpat);
+ var start = words[2].substring(0, words[2].length - 1);
+ fasta += ">" + words[0] + " ( start= " + start + " )\n" + words[3] + "\n";
+ }
+ return fasta;
+ }
+ function showRaw(motifnum) {
+ var source = document.getElementById('blocks' + motifnum);
+ var txtarea = document.getElementById("format_display_area_" + motifnum);
+ txtarea.value = block2raw(source.value);
+ txtarea.style.display = 'block';
+ }
+ function showFasta(motifnum) {
+ var source = document.getElementById('blocks' + motifnum);
+ var txtarea = document.getElementById("format_display_area_" + motifnum);
+ txtarea.value = block2fasta(source.value);
+ txtarea.style.display = 'block';
+ }
+ function showHidden(prefix) {
+ document.getElementById(prefix + '_activator').style.display = 'none';
+ document.getElementById(prefix + '_deactivator').style.display = 'block';
+ document.getElementById(prefix + '_data').style.display = 'block';
+ }
+ function hideShown(prefix) {
+ document.getElementById(prefix + '_activator').style.display = 'block';
+ document.getElementById(prefix + '_deactivator').style.display = 'none';
+ document.getElementById(prefix + '_data').style.display = 'none';
+ }
+ function wireUpTable(table, skiplast) {
+ if (table && table.rows) {
+ var nRows = table.rows.length;
+ if (skiplast) {nRows--;}
+ for (var i = 1; i < nRows; i++) {
+ var row = table.rows[i];
+ row.style.cursor = 'pointer';
+ row.onclick = function()
+ {
+ processHighlight(this);
+ }
+ }
+ } else {
+ alert(table);
+ }
+ }
+ function processHighlight(sourceRow) {
+ var name = sourceRow.cells[0].firstChild.nodeValue;
+
+ for (var i = 1; i <= 1; i++) {
+ tbl = document.getElementById("tbl_sites_" + i);
+ highlightTable(name, tbl);
+ tbl = document.getElementById("tbl_blocks_" + i);
+ highlightTable(name, tbl);
+ }
+ }
+ function highlightTable(name, table) {
+ if (table == null) return;
+ nRows = table.rows.length;
+ for (var i = 0; i < nRows; i++) {
+ var row = table.rows[i];
+ if(row.cells[0].firstChild.nodeValue == name) {
+ row.style.backgroundColor = "#aaffaa";
+ } else {
+ row.style.backgroundColor = "white";
+ }
+ }
+ }
+ function warnExternal() {
+ if (confirm("Using BLOCKS requires the data to be sent to an external webservice even if you have setup your own meme installation. Continue?")) {
+ return true;
+ }
+ return false;
+ }
+ function clickLogoTab(is_rc, num) {
+ var stdTab = document.getElementById("logo_tab_std_" + num);
+ var rcTab = document.getElementById("logo_tab_rc_" + num);
+ var logoImg = document.getElementById("logo_img_" + num);
+ var logoRcImg = document.getElementById("logo_rc_img_" + num);
+ if (is_rc) {
+ logoImg.style.display = 'none';
+ logoRcImg.style.display = 'block';
+ rcTab.setAttribute("class", "tab activeTab");
+ stdTab.setAttribute("class", "tab");
+ } else {
+ logoRcImg.style.display = 'none';
+ logoImg.style.display = 'block';
+ rcTab.setAttribute("class", "tab");
+ stdTab.setAttribute("class", "tab activeTab");
+ }
+ }
+ </script>
+</head>
+<body onload="javascript:setup()"><form enctype="application/x-www-form-urlencoded" method="post" target="_new" action="http://dan/meme_request.cgi">
+<!--+++++++++++++++++++++++START DATA+++++++++++++++++++++++++++++++++++++-->
+<input type="hidden" name="version" value="MEME version 4.5.0">
+<input type="hidden" name="alphabet" id="alphabet" value="ACDEFGHIKLMNPQRSTVWY">
+<input type="hidden" name="strands" value="none">
+<input type="hidden" name="bgfreq" id="bgfreq" value="A 0.291 C 0.229 D 0.001 E 0.001 F 0.001 G 0.255 H 0.001 I 0.001 K 0.001
+L 0.001 M 0.001 N 0.001 P 0.001 Q 0.001 R 0.001 S 0.001 T 0.215 V 0.001
+W 0.001 Y 0.001">
+<input type="hidden" name="name" value="dan.dat">
+<input type="hidden" name="combinedblock" value="
+chr21_19617074_19617124_+ 1.22e-03 1 50 1 39 3.06e-05
+chr21_26934381_26934431_+ 2.21e-03 1 50 1 27 5.52e-05
+chr21_28217753_28217803_- 7.29e-01 0 50
+chr21_31710037_31710087_- 2.37e-03 1 50 1 14 5.94e-05
+chr21_31744582_31744632_- 1.22e-03 1 50 1 12 3.06e-05
+chr21_31768316_31768366_+ 1.53e-03 1 50 1 0 3.82e-05
+chr21_31914206_31914256_- 6.70e-04 1 50 1 15 1.68e-05
+chr21_31933633_31933683_- 1.81e-03 1 50 1 4 4.54e-05
+chr21_31962741_31962791_- 1.61e-02 0 50
+chr21_31964683_31964733_+ 1.36e-04 1 50 1 13 3.41e-06
+chr21_31973364_31973414_+ 1.99e-01 0 50
+chr21_31992870_31992920_+ 3.47e-04 1 50 1 16 8.67e-06
+chr21_32185595_32185645_- 3.47e-04 1 50 1 18 8.67e-06
+chr21_32202076_32202126_- 2.01e-04 1 50 1 13 5.01e-06
+chr21_32253899_32253949_- 8.11e-04 1 50 1 19 2.03e-05
+chr21_32410820_32410870_- 3.47e-04 1 50 1 21 8.67e-06
+chr21_36411748_36411798_- 2.71e-03 1 50 1 22 6.78e-05
+chr21_37838750_37838800_- 8.23e-02 0 50
+chr21_45705687_45705737_+ 1.53e-03 1 50 1 37 3.82e-05
+chr21_45971413_45971463_- 1.36e-04 1 50 1 9 3.41e-06
+chr21_45978668_45978718_- 6.37e-04 1 50 1 4 1.59e-05
+chr21_45993530_45993580_+ 1.60e-04 1 50 1 7 4.00e-06
+chr21_46020421_46020471_+ 4.83e-04 1 50 1 2 1.21e-05
+chr21_46031920_46031970_+ 2.43e-04 1 50 1 15 6.06e-06
+chr21_46046964_46047014_+ 4.26e-05 1 50 1 12 1.06e-06
+chr21_46057197_46057247_+ 1.36e-04 1 50 1 36 3.41e-06
+chr21_46086869_46086919_- 4.30e-02 0 50
+chr21_46102103_46102153_- 4.30e-02 0 50
+chr21_47517957_47518007_+ 6.37e-04 1 50 1 32 1.59e-05
+chr21_47575506_47575556_- 1.61e-03 1 50 1 30 4.02e-05
+">
+<input type="hidden" name="nmotifs" value="1">
+<!--data for motif 1-->
+<input type="hidden" id="motifblock1" name="motifblock1" value="
+BL MOTIF 1 width=11 seqs=25
+">
+<input type="hidden" id="pssm1" name="pssm1" value="
+log-odds matrix: alength= 20 w= 11 n= 25 bayes= 5.33554 E= 2.4e-011
+-32 -680 91 77 7 138 -20 55 64 107 11 150 142 72 87 396 -148 221 -140 -36
+-11 -680 89 76 7 137 -21 55 63 107 10 149 141 71 87 396 -239 220 -140 -36
+-79 41 4 21 -7 44 -62 42 -5 99 0 99 138 52 42 399 -46 223 -173 -68
+11 -677 48 47 -2 127 -43 46 27 101 3 124 138 60 62 397 -235 220 -160 -55
+-596 -820 12 -21 -53 -267 -74 37 16 44 -37 98 31 9 19 319 212 127 -193 -95
+165 -261 70 110 77 -521 -4 147 95 201 90 121 124 91 107 425 -527 314 -95 8
+-838 -990 -89 -149 -151 -841 -161 -117 -113 -66 -209 -68 -69 -129 -91 111 221 -55 -255 -173
+176 -858 -79 -103 -115 -717 -148 -95 -108 -17 -162 -61 -12 -95 -69 193 -737 52 -240 -153
+134 -686 0 16 -12 -553 -68 44 -8 96 -9 88 124 41 36 384 11 216 -177 -71
+165 -261 70 110 77 -521 -4 147 95 201 90 121 124 91 107 425 -527 314 -95 8
+147 -614 89 129 93 -121 12 160 113 217 108 144 144 111 125 447 -241 332 -81 22
+
+">
+<input type="hidden" id="pspm1" name="pspm1" value="
+letter-probability matrix: alength= 20 w= 11 nsites= 25 E= 2.4e-011
+0.240000 0.000000 0.000000 0.000000 0.000000 0.680000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.080000 0.000000 0.000000 0.000000
+0.280000 0.000000 0.000000 0.000000 0.000000 0.680000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000
+0.160000 0.320000 0.000000 0.000000 0.000000 0.360000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.160000 0.000000 0.000000 0.000000
+0.320000 0.000000 0.000000 0.000000 0.000000 0.640000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000
+0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.960000 0.000000 0.000000 0.000000
+0.960000 0.040000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000
+1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+0.760000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.240000 0.000000 0.000000 0.000000
+0.960000 0.040000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+0.840000 0.000000 0.000000 0.000000 0.000000 0.120000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000
+
+">
+<input type="hidden" id="blocks1" name="BLOCKS1" value="
+BL MOTIF 1 width=11 seqs=25
+chr21_46046964_46047014_+ ( 12) GGGGTATAAAA 1
+chr21_46057197_46057247_+ ( 36) GGCATATAAAA 1
+chr21_45971413_45971463_- ( 9) GGCATATAAAA 1
+chr21_31964683_31964733_+ ( 13) GGCATATAAAA 1
+chr21_45993530_45993580_+ ( 7) GGAGTATAAAA 1
+chr21_32202076_32202126_- ( 13) GAGGTATAAAA 1
+chr21_46031920_46031970_+ ( 15) AGGGTATAAAA 1
+chr21_32410820_32410870_- ( 21) GATGTATAAAA 1
+chr21_32185595_32185645_- ( 18) GGGATATATAA 1
+chr21_31992870_31992920_+ ( 16) GATGTATAAAA 1
+chr21_46020421_46020471_+ ( 2) GACATATAAAA 1
+chr21_47517957_47518007_+ ( 32) GGGGTATAAAG 1
+chr21_45978668_45978718_- ( 4) GGGGTATAAAG 1
+chr21_31914206_31914256_- ( 15) AGAGTATAAAA 1
+chr21_32253899_32253949_- ( 19) GATATATAAAA 1
+chr21_31744582_31744632_- ( 12) AGCATATATAA 1
+chr21_19617074_19617124_+ ( 39) TGGGTATATAA 1
+chr21_45705687_45705737_+ ( 37) GGGGTATAACA 1
+chr21_31768316_31768366_+ ( 0) AACGTATATAA 1
+chr21_47575506_47575556_- ( 30) AGCGTATAAAG 1
+chr21_26934381_26934431_+ ( 27) GAGTTATAAAA 1
+chr21_31710037_31710087_- ( 14) TGAGTATATAA 1
+chr21_36411748_36411798_- ( 22) GGCATCTAAAA 1
+chr21_31933633_31933683_- ( 2) AGAGTATATAT 1
+chr21_31962741_31962791_- ( 13) GTTGGATAAAA 1
+//
+
+">
+<!--++++++++++++++++++++++++++++FINISHED DATA++++++++++++++++++++++++++++++++-->
+<a name="top_buttons"></a><div class="pad1">
+<h1><img src="http://meme.nbcr.net/meme/images/meme.png" alt="MEME"></h1>
+<p class="spaced">
+ For further information on how to interpret these results or to get a
+ copy of the MEME software please access
+ <a href="http://meme.nbcr.net/">http://meme.nbcr.net</a>.
+ </p>
+</div>
+<div class="pad2">
+<a class="jump" href="#overview">Discovered Motifs</a>
+ Â Â |Â Â
+ <a class="jump" href="#combined">Block diagrams of Motifs</a>
+ Â Â |Â Â
+ <a class="jump" href="#version">Program information</a>
+ Â Â |Â Â
+ <a class="jump" href="#explanation">Explanation</a>
+</div>
+<a name="overview"></a><h2 class="mainh pad2">Discovered Motifs</h2>
+<div class="box">
+<h4>Motif Overview</h4>
+<div class="pad"><table>
+<col style="text-align: center">
+<col style="text-align: right">
+<col style="text-align: right">
+<col>
+<tbody><tr>
+<td><a href="#motif_1">Motif 1</a></td>
+<td style="padding-left:20px"><ul>
+<li>2.4e-011</li>
+<li>25 sites</li>
+</ul></td>
+<td style="padding-left:20px"></td>
+<td style="padding-left:20px;"><a href="#motif_1"><img style="display:block; height:75px" src="logo1.png" id="thumbnail_logo_1" alt="Motif 1 Logo"></a></td>
+</tr></tbody>
+</table></div>
+<h4>Further Analysis</h4>
+<div class="pad">
+ Submit all motifs to
+ <input name="do_MAST_all" value="MAST" type="submit" title="Search sequence databases for the best combined matches with these motifs using MAST." onmouseover="javascript:showDesc(this, 'overview_action_desc')" onmouseout="javascript:hideDesc('overview_action_desc')">Â
+ <a href="#MAST_doc" title="Click for more information on MAST." class="help"><div class="help"></div></a>
+ Â Â Â Â
+ <input name="do_FIMO_all" value="FIMO" type="submit" title="Search sequence databases for all matches with these motifs using FIMO." onmouseover="javascript:showDesc(this, 'overview_action_desc')" onmouseout="javascript:hideDesc('overview_action_desc')">Â
+ <a href="#FIMO_doc" title="Click for more information on FIMO." class="help"><div class="help"></div></a>
+ Â Â Â Â
+ <input name="do_BLOCKS_all" value="BLOCKS" type="submit" title="Submit these motifs to BLOCKS multiple alignment processor." onclick="return warnExternal()" onmouseover="javascript:showDesc(this, 'overview_action_desc')" onmouseout="javascript:hideDesc('overview_action_desc')">Â
+ <a href="#BLOCKS_doc" title="Click for more information on BLOCKS." class="help"><div class="help"></div></a>
+ Â <span id="overview_action_desc">Mouse-over buttons for more information.</span>
+</div>
+</div>
+<a name="motif_1"></a><table width="100%" border="0" cellspacing="1" cellpadding="4" bgcolor="#FFFFFF"><tr>
+<td><h2 class="mainh">Motif 1</h2></td>
+<td align="right" valign="bottom"><a href="#top_buttons">Top</a></td>
+</tr></table>
+<div class="box">
+<table style="width:100%; background-color:#ddddff">
+<tr>
+<th class="majorth"><h4>Summary <a href="#summary_doc"><div class="help"></div></a>
+</h4></th>
+<th class="majorth"><h4>Sequence Logo <a href="#logo_doc"><div class="help"></div></a>
+</h4></th>
+</tr>
+<tr>
+<td style="width:15em; vertical-align:text-top;">
+<table style="width:100%; " cellspacing="0">
+<col>
+<col style="text-align:left;">
+<tr>
+<th class="minorth">E-value</th>
+<td>2.4e-011</td>
+</tr>
+<tr>
+<th class="minorth">Width</th>
+<td>11</td>
+</tr>
+<tr>
+<th class="minorth">Sites</th>
+<td>25</td>
+</tr>
+</table>
+<a href="javascript:showHidden('summary_extra_1')" id="summary_extra_1_activator">show more</a><div id="summary_extra_1_data" style="display:none"><table style="width:100%;" cellspacing="0">
+<tr><th colspan="2" class="minorth">Log Likelihood Ratio <a href="#llr_doc"><div class="help"></div></a>
+</th></tr>
+<tr>
+<td style="width:8em;">Â </td>
+<td>239</td>
+</tr>
+<tr><th colspan="2" class="minorth">Information Content <a href="#ic_doc"><div class="help"></div></a>
+</th></tr>
+<tr>
+<td>Â </td>
+<td>40.0Â (bits)</td>
+</tr>
+<tr><th colspan="2" class="minorth">Relative Entropy <a href="#re_doc"><div class="help"></div></a>
+</th></tr>
+<tr>
+<td>Â </td>
+<td>13.8Â (bits)</td>
+</tr>
+</table></div>
+<a href="javascript:hideShown('summary_extra_1')" id="summary_extra_1_deactivator" style="display:none;">show less</a>
+</td>
+<td>
+<div class="tabMain"><img src="logo1.png" style="display:block;" id="logo_img_1" height="140" width="260" alt="PNG LOGOS require CONVERT from ImageMagick; see MEME installation guide"></div>
+<div class="tabArea"><a id="logo_tab_std_1" href="javascript:clickLogoTab(false,1)" class="tab activeTab">Standard</a></div>
+<br>
+ Download LOGO <a href="#download_doc" class="help"><div class="help"></div></a>
+ Â Â
+ Orientation:
+ <select name="logorc_1"><option value="false">standard</option>
+<option value="true" disabled>reverse complement</option></select>
+ Â Â
+ SSC:
+ <select name="logossc_1"><option value="false">off</option>
+<option value="true">on</option></select>
+ Â Â
+ Format:
+ <select name="logoformat_1"><option value="png">web (png)</option>
+<option value="eps">publication (eps)</option></select>
+ Â Â
+ Width:
+ <input type="text" size="2" maxlength="5" value="11" title="Width of logo in cm." name="logowidth_1"> cm
+ Â Â
+ Height:
+ <input type="text" size="2" maxlength="5" value="7.5" title="Height of logo in cm." name="logoheight_1"> cm
+ Â Â
+ <input type="submit" value="Download" title="Download a logo" name="do_LOGO_1">
+</td>
+</tr>
+</table>
+<h4>Regular expression <a href="#regular_expression_doc" class="help"><div class="help"></div></a>
+</h4>
+<p class="pad">
+[GA][GA][GC][GA]TATA[AT]AA
+</p>
+<h4>Further Analysis <a href="#further_analysis_doc" class="help"><div class="help"></div></a>
+</h4>
+<div class="pad">
+ Submit this motif to
+ <input type="submit" name="do_MAST_1" value="MAST" title="Scan sequence databases for the best match in each sequence using MAST." onmouseover="javascript:showDesc(this, 'motif1_action_desc')" onmouseout="javascript:hideDesc('motif1_action_desc')">Â
+ <a href="#MAST_doc" title="Click for more information on MAST." class="help"><div class="help"></div></a>
+ Â Â Â Â
+ <input type="submit" name="do_FIMO_1" value="FIMO" title="Scan sequence databases for all matches with this motif using FIMO." onmouseover="javascript:showDesc(this, 'motif1_action_desc')" onmouseout="javascript:hideDesc('motif1_action_desc')">Â
+ <a href="#FIMO_doc" title="Click for more information on FIMO." class="help"><div class="help"></div></a>
+ Â Â Â Â
+ <input type="submit" name="do_BLOCKS_1" value="BLOCKS" title="Submit this motif to BLOCKS multiple alignment processor." onclick="return warnExternal()" onmouseover="javascript:showDesc(this, 'motif1_action_desc')" onmouseout="javascript:hideDesc('motif1_action_desc')">Â
+ <a href="#BLOCKS_doc" title="Click for more information on BLOCKS." class="help"><div class="help"></div></a>
+ Â <span id="motif1_action_desc">Mouse-over buttons for more information.</span>
+</div>
+<h4>Data Formats <a href="#formats_doc" class="help"><div class="help"></div></a>
+</h4>
+<div class="pad">
+ View the motif in
+ <input name="format_display_1" type="radio" onclick="javascript:showEmbededFormat(1, 'pspm')">PSPM FormatÂ
+ <a href="#format_PSPM_doc" title="Click for more information on PSPMs." class="help"><div class="help"></div></a>
+ Â Â Â Â
+ <input name="format_display_1" type="radio" onclick="javascript:showEmbededFormat(1, 'pssm')">PSSM FormatÂ
+ <a href="#format_PSSM_doc" title="Click for more information on PSSMs." class="help"><div class="help"></div></a>
+ Â Â Â Â
+ <input name="format_display_1" type="radio" onclick="javascript:showEmbededFormat(1, 'blocks')">BLOCKS FormatÂ
+ <a href="#format_BLOCKS_doc" title="Click for more information on BLOCKS format." class="help"><div class="help"></div></a>
+ Â Â Â Â
+ <input name="format_display_1" type="radio" onclick="javascript:showFasta(1)">FASTA FormatÂ
+ <a href="#format_FASTA_doc" title="Click for more information on FASTA format." class="help"><div class="help"></div></a>
+ Â Â Â Â
+ <input name="format_display_1" type="radio" onclick="javascript:showRaw(1)">Raw FormatÂ
+ <a href="#format_raw_doc" title="Click for more information on raw format." class="help"><div class="help"></div></a>
+ Â Â Â Â
+ or
+ <input name="format_display_1" type="radio" onclick="javascript:hideFormat(1)" checked>Hide<br><textarea id="format_display_area_1" rows="20" style="display:none; width:100%;" readonly></textarea><noscript>This feature requires javascript.</noscript>
+</div>
+<h4>Sites <a href="#sites_doc" class="help"><div class="help"></div></a>
+</h4>
+<div class="pad">
+<p>Click on any row to highlight sequence in all motifs.</p>
+<table id="tbl_sites_1" cellpadding="0.5cm">
+<col style="">
+<col style="">
+<col style="">
+<col style="">
+<col style="">
+<col style="">
+<thead><tr>
+<th>Name <a name="sites1"></a>
+</th>
+<th>Start</th>
+<th>
+<i>p</i>-value</th>
+<th colspan="3">Sites <a href="#sites_doc" class="help"><div class="help"></div></a>
+</th>
+</tr></thead>
+<tbody>
+<tr>
+<td class="strand_name">chr21_46046964_46047014_+</td>
+<td class="strand_start">12</td>
+<td class="strand_pvalue">1.06e-06</td>
+<td class="strand_lflank">AAGGCCAGGA</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GCCTGAGAGC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_46057197_46057247_+</td>
+<td class="strand_start">36</td>
+<td class="strand_pvalue">3.41e-06</td>
+<td class="strand_lflank">ACAGGCCCTG</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:blue;">C</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GCC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_45971413_45971463_-</td>
+<td class="strand_start">9</td>
+<td class="strand_pvalue">3.41e-06</td>
+<td class="strand_lflank">CAGGCCCTG</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:blue;">C</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GCCCCAGCAG</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_31964683_31964733_+</td>
+<td class="strand_start">13</td>
+<td class="strand_pvalue">3.41e-06</td>
+<td class="strand_lflank">GATTCACTGA</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:blue;">C</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GGCCCTCTGC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_45993530_45993580_+</td>
+<td class="strand_start">7</td>
+<td class="strand_pvalue">4.00e-06</td>
+<td class="strand_lflank">CCAAGGA</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GCCCCACAAA</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_32202076_32202126_-</td>
+<td class="strand_start">13</td>
+<td class="strand_pvalue">5.01e-06</td>
+<td class="strand_lflank">CCACCAGCTT</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">AGCCCTGTAC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_46031920_46031970_+</td>
+<td class="strand_start">15</td>
+<td class="strand_pvalue">6.06e-06</td>
+<td class="strand_lflank">ATACCCAGGG</td>
+<td class="strand_seq">
+<span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">CCTCAGCAGC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_32410820_32410870_-</td>
+<td class="strand_start">21</td>
+<td class="strand_pvalue">8.67e-06</td>
+<td class="strand_lflank">AATCACTGAG</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GTCCCAGGGA</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_32185595_32185645_-</td>
+<td class="strand_start">18</td>
+<td class="strand_pvalue">8.67e-06</td>
+<td class="strand_lflank">CACCAGAGCT</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">AGAAGGTTCT</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_31992870_31992920_+</td>
+<td class="strand_start">16</td>
+<td class="strand_pvalue">8.67e-06</td>
+<td class="strand_lflank">CACTATTGAA</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">TTTCATTTGC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_46020421_46020471_+</td>
+<td class="strand_start">2</td>
+<td class="strand_pvalue">1.21e-05</td>
+<td class="strand_lflank">GA</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:blue;">C</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GCCAACATCC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_47517957_47518007_+</td>
+<td class="strand_start">32</td>
+<td class="strand_pvalue">1.59e-05</td>
+<td class="strand_lflank">CCGGCGGGGC</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:orange;">G</span>
+</td>
+<td class="strand_rflank">GGGGCGG</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_45978668_45978718_-</td>
+<td class="strand_start">4</td>
+<td class="strand_pvalue">1.59e-05</td>
+<td class="strand_lflank">CAGA</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:orange;">G</span>
+</td>
+<td class="strand_rflank">GTTCCGACCA</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_31914206_31914256_-</td>
+<td class="strand_start">15</td>
+<td class="strand_pvalue">1.68e-05</td>
+<td class="strand_lflank">CCCACTACTT</td>
+<td class="strand_seq">
+<span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">TCATTCTGAG</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_32253899_32253949_-</td>
+<td class="strand_start">19</td>
+<td class="strand_pvalue">2.03e-05</td>
+<td class="strand_lflank">CACCAGCAAG</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GCTCAGGAGT</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_31744582_31744632_-</td>
+<td class="strand_start">12</td>
+<td class="strand_pvalue">3.06e-05</td>
+<td class="strand_lflank">CAGGTCTAAG</td>
+<td class="strand_seq">
+<span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:blue;">C</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">CTTGGAGTCC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_19617074_19617124_+</td>
+<td class="strand_start">39</td>
+<td class="strand_pvalue">3.06e-05</td>
+<td class="strand_lflank">CCTCGGGACG</td>
+<td class="strand_seq">
+<span style="color:green;">T</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank"></td>
+</tr>
+<tr>
+<td class="strand_name">chr21_45705687_45705737_+</td>
+<td class="strand_start">37</td>
+<td class="strand_pvalue">3.82e-05</td>
+<td class="strand_lflank">CGTGGTCGCG</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">C</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_31768316_31768366_+</td>
+<td class="strand_start">0</td>
+<td class="strand_pvalue">3.82e-05</td>
+<td class="strand_lflank"></td>
+<td class="strand_seq">
+<span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">C</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">ATGGTCCTGT</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_47575506_47575556_-</td>
+<td class="strand_start">30</td>
+<td class="strand_pvalue">4.02e-05</td>
+<td class="strand_lflank">GCTGCCGGTG</td>
+<td class="strand_seq">
+<span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:blue;">C</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:orange;">G</span>
+</td>
+<td class="strand_rflank">GCCCTGGCG</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_26934381_26934431_+</td>
+<td class="strand_start">27</td>
+<td class="strand_pvalue">5.52e-05</td>
+<td class="strand_lflank">AGTCACAAGT</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">GGGTCGCACG</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_31710037_31710087_-</td>
+<td class="strand_start">14</td>
+<td class="strand_pvalue">5.94e-05</td>
+<td class="strand_lflank">CCCAGGTTTC</td>
+<td class="strand_seq">
+<span style="color:green;">T</span><span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">TCGCCGCACC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_36411748_36411798_-</td>
+<td class="strand_start">22</td>
+<td class="strand_pvalue">6.78e-05</td>
+<td class="strand_lflank">AGTTTCAGTT</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:blue;">C</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">C</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">ATTATATAAC</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_31933633_31933683_-</td>
+<td class="strand_start">2</td>
+<td class="strand_pvalue">2.08e-04</td>
+<td class="strand_lflank">TC</td>
+<td class="strand_seq">
+<span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:green;">T</span>
+</td>
+<td class="strand_rflank">AAATGTTCCT</td>
+</tr>
+<tr>
+<td class="strand_name">chr21_31962741_31962791_-</td>
+<td class="strand_start">13</td>
+<td class="strand_pvalue">4.05e-04</td>
+<td class="strand_lflank">TATAACTCAG</td>
+<td class="strand_seq">
+<span style="color:orange;">G</span><span style="color:green;">T</span><span style="color:green;">T</span><span style="color:orange;">G</span><span style="color:orange;">G</span><span style="color:blue;">A</span><span style="color:green;">T</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span><span style="color:blue;">A</span>
+</td>
+<td class="strand_rflank">TAATTTGTAC</td>
+</tr>
+</tbody>
+</table>
+</div>
+<h4>Block Diagrams <a href="#diagrams_doc" class="help"><div class="help"></div></a>
+</h4>
+<div class="pad">
+<p>
+ The height of the motif "block" is proportional to -log(p-value), truncated at the height for a motif with a p-value of 1e-10.<br>
+ Click on any row to highlight sequence in all motifs. Mouse over the center of the motif blocks to see more information.
+ </p>
+<table id="tbl_blocks_1" style="width:100%;" border="0">
+<col style="width:10em;">
+<col style="width:5em;">
+<col>
+<thead><tr>
+<th>Name</th>
+<th>Lowest <i>p</i>-value</th>
+<th>Motif Location</th>
+</tr></thead>
+<tbody>
+<tr>
+<td>chr21_19617074_19617124_+</td>
+<td>3.06e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:78%; top:5.6px; width:22%; height:5.4px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 3.06e-05 starts: 40 ends: 50 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_26934381_26934431_+</td>
+<td>5.52e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:54%; top:5.9px; width:22%; height:5.1px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 5.52e-05 starts: 28 ends: 38 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_31710037_31710087_-</td>
+<td>5.94e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:28%; top:5.9px; width:22%; height:5.1px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 5.94e-05 starts: 15 ends: 25 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_31744582_31744632_-</td>
+<td>3.06e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:24%; top:5.6px; width:22%; height:5.4px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 3.06e-05 starts: 13 ends: 23 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_31768316_31768366_+</td>
+<td>3.82e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:0%; top:5.7px; width:22%; height:5.3px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 3.82e-05 starts: 1 ends: 11 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_31914206_31914256_-</td>
+<td>1.68e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:30%; top:5.3px; width:22%; height:5.7px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 1.68e-05 starts: 16 ends: 26 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_31933633_31933683_-</td>
+<td>2.08e-04</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:4%; top:6.6px; width:22%; height:4.4px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 2.08e-04 starts: 3 ends: 13 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_31962741_31962791_-</td>
+<td>4.05e-04</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:26%; top:6.9px; width:22%; height:4.1px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 4.05e-04 starts: 14 ends: 24 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_31964683_31964733_+</td>
+<td>3.41e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:26%; top:4.4px; width:22%; height:6.6px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 3.41e-06 starts: 14 ends: 24 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_31992870_31992920_+</td>
+<td>8.67e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:32%; top:4.9px; width:22%; height:6.1px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 8.67e-06 starts: 17 ends: 27 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_32185595_32185645_-</td>
+<td>8.67e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:36%; top:4.9px; width:22%; height:6.1px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 8.67e-06 starts: 19 ends: 29 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_32202076_32202126_-</td>
+<td>5.01e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:26%; top:4.6px; width:22%; height:6.4px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 5.01e-06 starts: 14 ends: 24 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_32253899_32253949_-</td>
+<td>2.03e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:38%; top:5.4px; width:22%; height:5.6px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 2.03e-05 starts: 20 ends: 30 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_32410820_32410870_-</td>
+<td>8.67e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:42%; top:4.9px; width:22%; height:6.1px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 8.67e-06 starts: 22 ends: 32 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_36411748_36411798_-</td>
+<td>6.78e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:44%; top:6px; width:22%; height:5px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 6.78e-05 starts: 23 ends: 33 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_45705687_45705737_+</td>
+<td>3.82e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:74%; top:5.7px; width:22%; height:5.3px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 3.82e-05 starts: 38 ends: 48 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_45971413_45971463_-</td>
+<td>3.41e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:18%; top:4.4px; width:22%; height:6.6px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 3.41e-06 starts: 10 ends: 20 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_45978668_45978718_-</td>
+<td>1.59e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:8%; top:5.2px; width:22%; height:5.8px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 1.59e-05 starts: 5 ends: 15 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_45993530_45993580_+</td>
+<td>4.00e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:14%; top:4.5px; width:22%; height:6.5px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 4.00e-06 starts: 8 ends: 18 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_46020421_46020471_+</td>
+<td>1.21e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:4%; top:5.1px; width:22%; height:5.9px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 1.21e-05 starts: 3 ends: 13 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_46031920_46031970_+</td>
+<td>6.06e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:30%; top:4.7px; width:22%; height:6.3px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 6.06e-06 starts: 16 ends: 26 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_46046964_46047014_+</td>
+<td>1.06e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:24%; top:3.8px; width:22%; height:7.2px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 1.06e-06 starts: 13 ends: 23 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_46057197_46057247_+</td>
+<td>3.41e-06</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:72%; top:4.4px; width:22%; height:6.6px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 3.41e-06 starts: 37 ends: 47 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_47517957_47518007_+</td>
+<td>1.59e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:64%; top:5.2px; width:22%; height:5.8px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 1.59e-05 starts: 33 ends: 43 "></div>
+</div></td>
+</tr>
+<tr>
+<td>chr21_47575506_47575556_-</td>
+<td>4.02e-05</td>
+<td class="block_td"><div class="block_container">
+<div class="block_rule" style="width:100%"></div>
+<div class="block_motif" style="left:60%; top:5.7px; width:22%; height:5.3px; background-color:aqua; border: 1px solid black;" title="Motif 1 p-value: 4.02e-05 starts: 31 ends: 41 "></div>
+</div></td>
+</tr>
+<tr>
+<td colspan="2">Â </td>
+<td class="block_td" style="color: blue;"><div class="block_container">
+<div class="tic_major" style="left:0%"><div class="tic_label" style="left:-0.5em; width:1em;">0</div></div>
+<div class="tic_minor" style="left:4%;"></div>
+<div class="tic_minor" style="left:8%;"></div>
+<div class="tic_minor" style="left:12%;"></div>
+<div class="tic_minor" style="left:16%;"></div>
+<div class="tic_major" style="left:20%"><div class="tic_label" style="left:-1em; width:2em;">10</div></div>
+<div class="tic_minor" style="left:24%;"></div>
+<div class="tic_minor" style="left:28%;"></div>
+<div class="tic_minor" style="left:32%;"></div>
+<div class="tic_minor" style="left:36%;"></div>
+<div class="tic_major" style="left:40%"><div class="tic_label" style="left:-1em; width:2em;">20</div></div>
+<div class="tic_minor" style="left:44%;"></div>
+<div class="tic_minor" style="left:48%;"></div>
+<div class="tic_minor" style="left:52%;"></div>
+<div class="tic_minor" style="left:56%;"></div>
+<div class="tic_major" style="left:60%"><div class="tic_label" style="left:-1em; width:2em;">30</div></div>
+<div class="tic_minor" style="left:64%;"></div>
+<div class="tic_minor" style="left:68%;"></div>
+<div class="tic_minor" style="left:72%;"></div>
+<div class="tic_minor" style="left:76%;"></div>
+<div class="tic_major" style="left:80%"><div class="tic_label" style="left:-1em; width:2em;">40</div></div>
+<div class="tic_minor" style="left:84%;"></div>
+<div class="tic_minor" style="left:88%;"></div>
+<div class="tic_minor" style="left:92%;"></div>
+<div class="tic_minor" style="left:96%;"></div>
+<div class="tic_major" style="left:100%"><div class="tic_label" style="left:-1em; width:2em;">50</div></div>
+</div></td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>Time 1.6 secs.</p>
+</div>
+<div class="bar">
+<div style="text-align:right;"><a href="#top_buttons">Top</a></div>
+<div class="subsection">
+<a name="version"></a><h5>MEME version</h5>4.5.0 (Release date: Thu Oct 14 08:44:28 EST 2010)
+ </div>
+<div class="subsection">
+<a name="reference"></a><h5>Reference</h5>
+ Timothy L. Bailey and Charles Elkan,
+ "Fitting a mixture model by expectation maximization to discover
+ motifs in biopolymers", Proceedings of the Second International
+ Conference on Intelligent Systems for Molecular Biology, pp. 28-36,
+ AAAI Press, Menlo Park, California, 1994.
+ </div>
+<a name="sequences"></a><a href="javascript:showHidden('trainingseq')" id="trainingseq_activator">show training set...</a><div class="subsection" id="trainingseq_data" style="display:none;">
+<h5>Training set:</h5>
+ Datafile = dan.dat<br>
+ Alphabet = ACDEFGHIKLMNPQRSTVWY<br><table>
+<col>
+<col>
+<col>
+<tr style="vertical-align:top;">
+<td><table class="trainingset">
+<col>
+<col>
+<col>
+<tr>
+<th>Sequence name</th>
+<th>Weighting</th>
+<th>Length</th>
+</tr>
+<tr>
+<td>chr21_19617074_19617124_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_31710037_31710087_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_31914206_31914256_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_31964683_31964733_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_32185595_32185645_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_32410820_32410870_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_45705687_45705737_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_45993530_45993580_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_46046964_46047014_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_46102103_46102153_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+</table></td>
+<td><table class="trainingset">
+<col>
+<col>
+<col>
+<tr>
+<th>Sequence name</th>
+<th>Weighting</th>
+<th>Length</th>
+</tr>
+<tr>
+<td>chr21_26934381_26934431_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_31744582_31744632_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_31933633_31933683_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_31973364_31973414_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_32202076_32202126_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_36411748_36411798_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_45971413_45971463_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_46020421_46020471_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_46057197_46057247_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_47517957_47518007_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+</table></td>
+<td><table class="trainingset">
+<col>
+<col>
+<col>
+<tr>
+<th>Sequence name</th>
+<th>Weighting</th>
+<th>Length</th>
+</tr>
+<tr>
+<td>chr21_28217753_28217803_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_31768316_31768366_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_31962741_31962791_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_31992870_31992920_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_32253899_32253949_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_37838750_37838800_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_45978668_45978718_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_46031920_46031970_+</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_46086869_46086919_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+<tr>
+<td>chr21_47575506_47575556_-</td>
+<td>1.000000</td>
+<td>50</td>
+</tr>
+</table></td>
+</tr>
+</table>
+</div>
+<a href="javascript:hideShown('trainingseq')" style="display:none;" id="trainingseq_deactivator">hide training set...</a><div class="subsection">
+<a name="command"></a><h5>Command line summary</h5>
+<textarea rows="1" style="width:100%;" readonly>meme dan.dat -o /dataset_dan_files -nostatus </textarea><br>
+ Letter frequencies in dataset<br><div style="margin-left:25px;">A:Â 0.294Â Â Â C:Â 0.231Â Â Â D:Â 0.000Â Â Â E:Â 0.000Â Â Â F:Â 0.000Â Â Â G:Â 0.257Â Â Â H:Â 0.000Â Â Â I:Â 0.000Â Â Â K:Â 0.000Â Â Â L:Â 0.000Â Â Â M:Â 0.000Â Â Â N:Â 0.000Â Â Â P:Â 0.000Â Â Â Q:Â 0.000Â Â Â R:Â 0.000Â Â Â S:Â 0.000Â Â Â T:Â 0.217Â Â Â V:Â 0.000Â Â Â W:Â 0.000Â Â Â Y:Â 0.000</div>
+<br>
+ Background letter frequencies (from dataset with add-one prior applied):<br><div style="margin-left:25px;">A:Â 0.291Â Â Â C:Â 0.229Â Â Â D:Â 0.001Â Â Â E:Â 0.001Â Â Â F:Â 0.001Â Â Â G:Â 0.255Â Â Â H:Â 0.001Â Â Â I:Â 0.001Â Â Â K:Â 0.001Â Â Â L:Â 0.001Â Â Â M:Â 0.001Â Â Â N:Â 0.001Â Â Â P:Â 0.001Â Â Â Q:Â 0.001Â Â Â R:Â 0.001Â Â Â S:Â 0.001Â Â Â T:Â 0.215Â Â Â V:Â 0.001Â Â Â W:Â 0.001Â Â Â Y:Â 0.001</div>
+<br>
+</div>
+<div class="subsection">
+<a name="stopped"></a><h5>Stopping Reason</h5>Stopped because nmotifs = 1 reached. Program ran on <i>dan</i>.
+ </div>
+<a href="javascript:showHidden('model')" id="model_activator">show model parameters...</a><div class="subsection" id="model_data" style="display:none;">
+<h5>Model parameters</h5>
+<textarea style="width:100%;" rows="28" readonly>
+host = dan
+type = zoops
+nmotifs = 1
+evalue_threshold = inf
+object_function = E-value of product of p-values
+min_width = 8
+max_width = 50
+minic = 0.00
+wg = 11
+ws = 1
+endgaps = yes
+minsites = 2
+maxsites = 30
+wnsites = 0.8
+prob = 1
+spmap = pam
+spfuzz = 120
+prior = megap
+beta = 7500
+maxiter = 50
+distance = 1e-05
+num_sequences = 30
+num_positions = 1500
+seed = 0
+seqfrac = 1
+strands = none
+priors_file = prior30.plib
+reason_for_stopping = Stopped because nmotifs = 1 reached.
+</textarea>
+</div>
+<a href="javascript:hideShown('model')" style="display:none;" id="model_deactivator">hide model parameters...</a>
+</div>
+<span class="explain"><a name="explanation"></a><table width="100%" border="0" cellspacing="1" cellpadding="4" bgcolor="#FFFFFF"><tr>
+<td><h2 class="mainh">Explanation of MEME Results</h2></td>
+<td align="right" valign="bottom"><a href="#top_buttons">Top</a></td>
+</tr></table>
+<div class="box">
+<h4>The MEME results consist of</h4>
+<ul>
+<li>The <a href="#overview"><b>overview</b></a> of all discovered motifs.</li>
+<li>Information on each of the <a href="#motifs"><b>motifs</b></a> MEME discovered, including:
+ <ol>
+<li>
+ A <a href="#summary_doc"><b>summary table</b></a> showing the width, number of contributing sites, log likelihood ratio,
+ statistical significance, information content and relative entropy of the motif.
+ </li>
+<li>A <a href="#logo_doc"><b>sequence LOGO</b></a>.</li>
+<li>Downloadable <a href="#download"><b>LOGO files</b></a> suitable for publication.</li>
+<li>A <a href="#regular_expression_doc"><b>regular expression</b></a> describing the motif.</li>
+<li>Some <a href="#further_analysis_doc"><b>further analysis</b></a> that can be performed on the motif.</li>
+<li>A list of <a href="#formats_doc"><b>data formats</b></a> describing the motif.</li>
+<li>The <a href="#sites_doc"><b>contributing sites</b></a> of the motif sorted by <i>p</i>-value and aligned with each other.</li>
+<li>
+ The <a href="#diagrams_doc"><b>block diagrams</b></a> of the contributing sites of the motif within each sequence in the training set.
+ </li>
+</ol>
+</li>
+<li>A <a href="#combined"><b>combined block diagram</b></a> showing an optimized (non-overlapping)
+ tiling of all of the motifs onto each of the sequences in the training set.
+ </li>
+<li>The <a href="#version"><b>version</b></a> of MEME and the date it was released.</li>
+<li>The <a href="#reference"><b>reference</b></a> to cite if you use MEME in your research.</li>
+<li>
+ A description of the <a href="#sequences"><b>sequences</b></a> you submitted (the "training set") showing the name,
+ "weight" and length of each sequence.
+ </li>
+<li>The <a href="#command"><b>command line summary</b></a> detailing the parameters with which you ran MEME.</li>
+<li>The reason why MEME <a href="#stopped"><b>stopped</b></a> and the name of the CPU on which it ran.</li>
+<li>This <b>explanation</b> of how to interpret MEME results.</li>
+</ul>
+<a name="motifs"></a><h4>Motifs</h4>
+<p>
+ For each motif that it discovers in the training set,
+ MEME prints the following information:
+ </p>
+<a name="summary_doc"></a><h5>Summary Table</h5>
+<div class="doc">
+<p>
+ This summary table gives the main attributes of the motif.
+ </p>
+<dl>
+<dt>
+<i>E</i>-value</dt>
+<dd>
+ The statistical significance of the motif. MEME usually finds the most statistically significant (low <i>E</i>-value) motifs first.
+ The <i>E</i>-value of a motif is based on its log likelihood ratio, width, sites, the background letter frequencies (given in the
+ <a href="#command">command line summary</a>), and the size of the training set. The <i>E</i>-value is an estimate of the expected
+ number of motifs with the given log likelihood ratio (or higher), and with the same width and site count, that one would find in
+ a similarly sized set of random sequences. (In random sequences each position is independent with letters chosen according to
+ the background letter frequencies.)
+ </dd>
+<dt>Width</dt>
+<dd>The width of the motif. Each motif describes a pattern of a fixed with as no gaps are allowed in MEME motifs.</dd>
+<dt>Sites</dt>
+<dd>The number of sites contributing to the construction of the motif.</dd>
+<dt>
+<a name="llr_doc"></a>Log Likelihood Ratio</dt>
+<dd>
+ The log likelihood ratio of the motif.The log likelihood ratio is the logarithm of the ratio of the probability of the occurrences
+ of the motif given the motif model (likelihood given the motif) versus their probability given the background model
+ (likelihood given the null model). (Normally the background model is a 0-order Markov model using the background letter
+ frequencies, but higher order Markov models may be specified via the <b>-bfile</b> option to MEME.)
+ </dd>
+<dt>
+<a name="ic_doc"></a>Information Content</dt>
+<dd>
+ The information content of the motif in bits. It is equal to the sum of the <b>uncorrected</b> information content, <tt>R()</tt>,
+ in the columns of the <a href="#logo_doc">LOGO</a>. This is equal relative entropy of the motif relative to a uniform background frequency
+ model.
+ </dd>
+<dt>
+<a name="re_doc"></a>Relative Entropy</dt>
+<dd>
+ The relative entropy of the motif, computed in bits and relative to the background letter frequencies given in the
+ <a href="#command">command line summary</a>. It is equal to the log-likelihood ratio (llr) divided by the
+ number of contributing sites of the motif times <tt>1/ln(2)</tt>,<br><br><tt>re = llr / (sites * ln(2))</tt>.
+ </dd>
+</dl>
+</div>
+<a name="logo_doc"></a><h5 class="doc">Sequence LOGO</h5>
+<div class="doc">
+<p>
+ MEME motifs are represented by position-specific probability matrices
+ that specify the probability of each possible letter appearing at each
+ possible position in an occurrence of the motif. These are displayed
+ as "sequence LOGOS", containing stacks of letters at each position
+ in the motif. The total height of the stack is the "information
+ content" of that position in the motif in bits. The height of the
+ individual letters in a stack is the probability of the letter at that
+ position multiplied by the total information content of the stack.
+ </p>
+<p>
+ Note: The MEME LOGO differs from those produced by the
+ <a href="http://weblogo.berkeley.edu">Weblogo</a> program
+ because a <b>small-sample correction is NOT applied</b>.
+ However, MEME LOGOs in PNG and encapsulated postscript (EPS) formats
+ <b>with small-sample correction (SSC)</b> are available by clicking
+ on the download button with "SSC" set to "on" under
+ <a href="#download_doc">Download LOGO</a>.
+ The MEME LOGOs without small sample correction are similarly available.
+ Error bars are included in the LOGOs with small-sample correction.
+ </p>
+<p>
+ Modern web browsers supporting the canvas element and it's text manipulation functions as described in the
+ html 5 standard, can render the sequence LOGOs without needing the images. The browsers which work with this
+ feature are:
+ </p>
+<ul>
+<li>Firefox 3.5 and above</li>
+<li>Safari 4 and above</li>
+<li>Google Chrome 4 and above</li>
+</ul>
+<p>
+ Unfortunately Internet Explorer 8 does not support any html 5 features.
+ </p>
+<p>
+ The information content of each motif position is computed as described in the paper by Schneider and Stephens,
+ "Sequence Logos: A New Way to Display Consensus Sequences" but
+ <b>the small-sample correction, <tt>e(n)</tt>, is set to zero for the LOGO displayed in the MEME output.</b>
+ The corrected information content of position <tt>i</tt> is given by
+ </p>
+<pre>
+ R(i) for amino acids = log2(20) - (H(i) + e(n)) (1a)
+ R(i) for nucleic acids = 2 - (H(i) + e(n)) (1b)
+ </pre>
+<p>where H(i) is the entropy of position <tt>i</tt>,</p>
+<pre>
+ H(l) = - (Sum f(a,i) * log2[ f(a,i) ]). (2)
+ </pre>
+<p>
+ Here, f(a,i) is the frequency of base or amino acid <tt>a</tt> at position <tt>i</tt>, and <tt>e(n)</tt> is the small-sample correction
+ for an alignment of <tt>n</tt> letters. The height of letter <tt>a</tt> in column <tt>i</tt> is given by
+ </p>
+<pre>
+ height = f(a,i) * R(i) (3)
+ </pre>
+<p>The approximation for the small-sample correction, <tt>e(n)</tt>, is given by:</p>
+<pre>
+ e(n) = (s-1) / (2 * ln(2) * n), (4)
+ </pre>
+<p>where <tt>s</tt> is 4 for nucleotides, 20 for amino acids, and <tt>n</tt> is the number of sequences in the alignment.</p>
+<p>
+ The letters in the logos are colored as follows.<br>
+ For DNA sequences, the letter categories contain one letter each.
+ </p>
+<table border="1">
+<thead><tr>
+<th>NUCLEIC ACIDS</th>
+<th>COLOR</th>
+</tr></thead>
+<tbody>
+<tr>
+<td>A</td>
+<td style="color:red;">RED</td>
+</tr>
+<tr>
+<td>C</td>
+<td style="color:blue;">BLUE</td>
+</tr>
+<tr>
+<td>G</td>
+<td style="color:orange;">ORANGE</td>
+</tr>
+<tr>
+<td>T</td>
+<td style="color:green;">GREEN</td>
+</tr>
+</tbody>
+</table>
+<p>For proteins, the categories are based on the biochemical properties of the various amino acids.</p>
+<table border="1">
+<thead><tr>
+<th>AMINO ACIDS</th>
+<th>COLOR</th>
+<th>PROPERTIES</th>
+</tr></thead>
+<tbody>
+<tr>
+<td>A, C, F, I, L, V, W and M</td>
+<td style="color:blue;">BLUE</td>
+<td>Most hydrophobic[Kyte and Doolittle, 1982]</td>
+</tr>
+<tr>
+<td>NQST</td>
+<td style="color:green;">GREEN</td>
+<td>Polar, non-charged, non-aliphatic residues</td>
+</tr>
+<tr>
+<td>DE</td>
+<td style="color:magenta;">MAGENTA</td>
+<td>Acidic</td>
+</tr>
+<tr>
+<td>KR</td>
+<td style="color:red;">RED</td>
+<td>Positively charged</td>
+</tr>
+<tr>
+<td>H</td>
+<td style="color:pink;">PINK</td>
+<td>Â </td>
+</tr>
+<tr>
+<td>G</td>
+<td style="color:orange;">ORANGE</td>
+<td>Â </td>
+</tr>
+<tr>
+<td>P</td>
+<td style="color:yellow;">YELLOW</td>
+<td>Â </td>
+</tr>
+<tr>
+<td>Y</td>
+<td style="color:turquoise;">TURQUOISE</td>
+<td>Â </td>
+</tr>
+</tbody>
+</table>
+<p>
+ J. Kyte and R. Doolittle, 1982. "A Simple Method for Displaying the Hydropathic Character of a Protein",
+ J. Mol Biol. 157, 105-132.
+ </p>
+<p><b>Note:</b> the "text" output format of MEME preserves the historical MEME format where LOGOS are replaced by a simplified probability
+ matrix, a relative entropy plot, and a multi-level consensus sequence.
+ </p>
+</div>
+<a name="download_doc"></a><h5 class="doc">Download LOGO</h5>
+<div class="doc"><p>
+ Logos can be generated on the fly by the meme webservice and you may specify a number of options to customize them to your needs.
+ The options are:
+ <dl>
+<dt>Orientation</dt>
+<dd>Only valid for nucleotide motifs. Generate the standard view or the reverse complemented view of the motif.</dd>
+<dt>SSC</dt>
+<dd>Use small sample correction and show errorbars on the image.
+ Small sample correction is used by the <a href="http://weblogo.berkeley.edu">Weblogo</a> program.</dd>
+<dt>Format</dt>
+<dd>The format of the generated image.
+ If the image is to be used on the web then png is recommend.
+ If the image is to be published then eps is recommended.
+ </dd>
+<dt>Width</dt>
+<dd>The width of the generated image in centimetres.</dd>
+<dt>Height</dt>
+<dd>The height of the generated image in centimetres.</dd>
+</dl></p></div>
+<a name="regular_expression_doc"></a><h5>Regular Expression</h5>
+<div class="doc"><p>
+ This is a regular expression (RE) describing the motif. In each column, all letters with observed frequencies greater than 0.2 are shown;
+ less-frequent letters are not included in the RE. MEME regular expressions are interpreted as follows: single letters match that letter;
+ groups of letters in square brackets match any of the letters in the group. Regular expressions can be used for searching for the motif
+ in sequences (using, for example, <a href="http://nar.oxfordjournals.org/cgi/content/full/33/suppl_2/W262">PatMatch</a>) but the search
+ accuracy will usually be better with the PSSM (using, for example <a href="http://meme.nbcr.net/meme/mast-intro.html">MAST</a>.)
+ </p></div>
+<a name="further_analysis_doc"></a><h5>Further Analysis</h5>
+<div class="doc">
+<p>Either as a group or individually the motifs have a number of options for further analysis.</p>
+<dl>
+<dt>
+<a name="MAST_doc"></a>MAST</dt>
+<dd>
+ Finds the best matching positions for a set of motifs in each sequence provided to it, ranked by the combined score of each sequence.
+ For more information about MAST please read the <a href="http://meme.nbcr.net/meme/mast-intro.html">introduction</a>.
+ </dd>
+<dt>
+<a name="FIMO_doc"></a>FIMO</dt>
+<dd>
+ Finds all matches for a motif.
+ For more information about FIMO please read the <a href="http://meme.nbcr.net/meme/fimo-intro.html">introduction</a>.
+ </dd>
+<dt>
+<a name="TOMTOM_doc"></a>TOMTOM</dt>
+<dd>
+ Compares a single motif to a database of motifs.
+ For more information about TOMTOM please read the <a href="http://meme.nbcr.net/meme/tomtom-intro.html">introduction</a>.
+ </dd>
+<dt>
+<a name="GOMO_doc"></a>GOMO</dt>
+<dd>
+ Identifies possible roles of DNA binding motifs.
+ For more information about GOMO please read the <a href="http://meme.nbcr.net/meme/gomo-intro.html">introduction</a>.
+ </dd>
+<dt>
+<a name="BLOCKS_doc"></a>BLOCKS</dt>
+<dd>
+ Submit to Blocks Multiple Alignment Processor where you can do several things like create phylogeny trees and search the blocks
+ against a database of other blocks (protein only). For more information about BLOCKS Multiple Alignment Processor please visit the
+ <a href="http://blocks.fhcrc.org/blocks/process_blocks.html">website</a>.
+ </dd>
+</dl>
+</div>
+<a name="formats_doc"></a><h5>Data Formats</h5>
+<div class="doc">
+<p>The extracted data is avaliable in the following formats.</p>
+<dl>
+<dt>
+<a name="format_PSPM_doc"></a>PSPM Format</dt>
+<dd>
+ The motif itself is a position-specific probability matrix giving, for each position in the pattern, the observed frequency ("probability")
+ of each possible letter. The probability matrix is printed "sideways"--columns correspond to the letters in the alphabet (in the same order
+ as shown in the simplified motif) and rows corresponding to the positions of the motif, position one first. The motif is preceded by a line
+ starting with "letter-probability matrix:" and containing the length of the alphabet, width of the motif, number of occurrences of the motif,
+ and the <i>E</i>-value of the motif.<br><b>Note:</b> Earlier versions of MEME gave the posterior probabilities--the probability after applying a prior on letter frequencies--rather
+ than the observed frequencies. These versions of MEME also gave the number of <i>possible</i> positions for the motif rather than the actual
+ number of occurrences. The output from these earlier versions of MEME can be distinguished by "n=" rather than "nsites=" in the line
+ preceding the matrix.
+ </dd>
+<dt>
+<a name="format_PSSM_doc"></a>PSSM Format</dt>
+<dd>
+ The position-specific scoring matrix corresponding to the motif is printed for use by database search programs such as MAST.
+ This matrix is a log-odds matrix calculated by taking 100 times the log (base 2) of the ratio <i>p/f</i> at each position in
+ the motif where <i>p</i> is the probability of a particular letter at that position in the motif, and <i>f</i> is the background
+ frequency of the letter (given in the <a href="#command">command line summary</a> section.) This is the same matrix that is used
+ above in computing the <i>p</i>-values of the occurrences of the motif in the <a href="#sites_doc">Sites</a>
+ and <a href="#diagrams_doc">Block Diagrams</a> sections. The scoring matrix is printed "sideways"--columns
+ correspond to the letters in the alphabet (in the same order as shown in the simplified motif) and rows corresponding to the
+ positions of the motif, position one first. The scoring matrix is preceded by a line starting with "log-odds matrix:" and
+ containing the length of the alphabet, width of the motif, number of characters in the training set, the scoring threshold
+ (obsolete) and the motif <i>E</i>-value.<br><b>Note:</b> The probability <i>p</i> used to compute the PSSM is <i>not</i> exactly the same as the corresponding value in the
+ Position Specific Probability Matrix (PSPM). The values of <i>p</i> used to compute the PSSM take into account the motif prior,
+ whereas the values in the PSPM are just the <i>observed</i> frequencies of letters in the motif sites.
+ </dd>
+<dt>
+<a name="format_BLOCKS_doc"></a>BLOCKS Format</dt>
+<dd>
+ For use with <a href="http://blocks.fhcrc.org/blocks">BLOCKS tools</a>.
+ </dd>
+<dt>
+<a name="format_FASTA_doc"></a>FASTA Format</dt>
+<dd>
+ The FASTA format as described <a href="http://meme.nbcr.net/meme/doc/fasta-format.html">here</a>.
+ </dd>
+<dt>
+<a name="format_raw_doc"></a>Raw Format</dt>
+<dd>
+ Just the sites of the sequences that contributed to the motif. One site per line.
+ </dd>
+</dl>
+</div>
+<a name="sites_doc"></a><h5 class="doc">Sites</h5>
+<div class="doc"><p>
+ MEME displays the occurrences (sites) of the motif in the training set. The sites are shown aligned with each other, and the ten sequence
+ positions preceding and following each site are also shown. Each site is identified by the name of the sequence where it occurs,
+ the strand (if both strands of DNA sequences are being used), and the position in the sequence where the site begins. When the DNA strand
+ is specified, '+' means the sequence in the training set, and '-' means the reverse complement of the training set sequence.
+ (For '-' strands, the 'start' position is actually the position on the <b>positive</b> strand where the site ends.) The sites are <b>listed
+ in order of increasing statistical significance</b> (<i>p</i>-value). The <i>p</i>-value of a site is computed from the the match score of
+ the site with the <a href="#format_PSSM_doc">position specific scoring matrix</a> for the motif. The <i>p</i>-value gives the probability of a
+ random string (generated from the background letter frequencies) having the same match score or higher. (This is referred to as the
+ <b>position <i>p</i>-value</b> by the MAST algorithm.)
+ </p></div>
+<a name="diagrams_doc"></a><h5 class="doc">Block Diagrams</h5>
+<div class="doc"><p>
+ The occurrences of the motif in the training set sequences are shown as coloured blocks on a line. One diagram is printed for each
+ sequence showing all the sites contributating to that motif in that sequence. The sequences are <b>listed in the same order as in the input</b>
+ to make it easier to compare multiple block diagrams. Additionally the best <i>p</i>-value for the sequence/motif combination is
+ listed though this may not be in ascending order as with the sites. The <i>p</i>-value of an occurrence is the probability of a single
+ random subsequence the length of the motif, generated according to the 0-order background model, having a score at least as high as
+ the score of the occurrence. When the DNA strand is specified '+', it means the motif appears from left to right on the sequence, and '-'
+ means the motif appears from right to left on the complementary strand. A sequence position scale is shown at the end of each table of
+ block diagrams.
+ </p></div>
+<a name="combined_doc"></a><h5>Combined Block Diagrams</h5>
+<div class="doc">
+<p>
+ The motif occurrences shown in the motif summary <b>may not be exactly the same as those reported in each motif section</b> because
+ only motifs with a position <em>p</em>-value of 0.0001 that don't overlap other, more significant motif occurrences are shown.
+ </p>
+<p>
+ See the documentation for <a href="http://meme.nbcr.net/meme/mast-output.html">MAST output</a> for the definition of position and
+ combined <em>p</em>-values.
+ </p>
+</div>
+</div></span><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
+</form></body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/meme/meme/meme_output_txt_1.txt Tue Feb 01 11:20:02 2011 -0500
@@ -0,0 +1,325 @@
+********************************************************************************
+MEME - Motif discovery tool
+********************************************************************************
+MEME version 4.5.0 (Release date: Thu Oct 14 08:44:28 EST 2010)
+
+For further information on how to interpret these results or to get
+a copy of the MEME software please access http://meme.nbcr.net.
+
+This file may be used as input to the MAST algorithm for searching
+sequence databases for matches to groups of motifs. MAST is available
+for interactive use and downloading at http://meme.nbcr.net.
+********************************************************************************
+
+
+********************************************************************************
+REFERENCE
+********************************************************************************
+If you use this program in your research, please cite:
+
+Timothy L. Bailey and Charles Elkan,
+"Fitting a mixture model by expectation maximization to discover
+motifs in biopolymers", Proceedings of the Second International
+Conference on Intelligent Systems for Molecular Biology, pp. 28-36,
+AAAI Press, Menlo Park, California, 1994.
+********************************************************************************
+
+
+********************************************************************************
+TRAINING SET
+********************************************************************************
+DATAFILE= dan.dat
+ALPHABET= ACDEFGHIKLMNPQRSTVWY
+Sequence name Weight Length Sequence name Weight Length
+------------- ------ ------ ------------- ------ ------
+chr21_19617074_19617124_ 1.0000 50 chr21_26934381_26934431_ 1.0000 50
+chr21_28217753_28217803_ 1.0000 50 chr21_31710037_31710087_ 1.0000 50
+chr21_31744582_31744632_ 1.0000 50 chr21_31768316_31768366_ 1.0000 50
+chr21_31914206_31914256_ 1.0000 50 chr21_31933633_31933683_ 1.0000 50
+chr21_31962741_31962791_ 1.0000 50 chr21_31964683_31964733_ 1.0000 50
+chr21_31973364_31973414_ 1.0000 50 chr21_31992870_31992920_ 1.0000 50
+chr21_32185595_32185645_ 1.0000 50 chr21_32202076_32202126_ 1.0000 50
+chr21_32253899_32253949_ 1.0000 50 chr21_32410820_32410870_ 1.0000 50
+chr21_36411748_36411798_ 1.0000 50 chr21_37838750_37838800_ 1.0000 50
+chr21_45705687_45705737_ 1.0000 50 chr21_45971413_45971463_ 1.0000 50
+chr21_45978668_45978718_ 1.0000 50 chr21_45993530_45993580_ 1.0000 50
+chr21_46020421_46020471_ 1.0000 50 chr21_46031920_46031970_ 1.0000 50
+chr21_46046964_46047014_ 1.0000 50 chr21_46057197_46057247_ 1.0000 50
+chr21_46086869_46086919_ 1.0000 50 chr21_46102103_46102153_ 1.0000 50
+chr21_47517957_47518007_ 1.0000 50 chr21_47575506_47575556_ 1.0000 50
+********************************************************************************
+
+********************************************************************************
+COMMAND LINE SUMMARY
+********************************************************************************
+This information can also be useful in the event you wish to report a
+problem with the MEME software.
+
+command: meme dan.dat -o dan/dataset_dan_files -nostatus
+
+model: mod= zoops nmotifs= 1 evt= inf
+object function= E-value of product of p-values
+width: minw= 8 maxw= 50 minic= 0.00
+width: wg= 11 ws= 1 endgaps= yes
+nsites: minsites= 2 maxsites= 30 wnsites= 0.8
+theta: prob= 1 spmap= pam spfuzz= 120
+global: substring= yes branching= no wbranch= no
+em: prior= megap b= 7500 maxiter= 50
+ distance= 1e-05
+data: n= 1500 N= 30
+
+sample: seed= 0 seqfrac= 1
+Dirichlet mixture priors file: prior30.plib
+Letter frequencies in dataset:
+A 0.294 C 0.231 D 0.000 E 0.000 F 0.000 G 0.257 H 0.000 I 0.000 K 0.000
+L 0.000 M 0.000 N 0.000 P 0.000 Q 0.000 R 0.000 S 0.000 T 0.217 V 0.000
+W 0.000 Y 0.000
+Background letter frequencies (from dataset with add-one prior applied):
+A 0.291 C 0.229 D 0.001 E 0.001 F 0.001 G 0.255 H 0.001 I 0.001 K 0.001
+L 0.001 M 0.001 N 0.001 P 0.001 Q 0.001 R 0.001 S 0.001 T 0.215 V 0.001
+W 0.001 Y 0.001
+********************************************************************************
+
+
+********************************************************************************
+MOTIF 1 width = 11 sites = 25 llr = 239 E-value = 2.4e-011
+********************************************************************************
+--------------------------------------------------------------------------------
+ Motif 1 Description
+--------------------------------------------------------------------------------
+Simplified A 2323:a:a8a8
+pos.-specific C ::3::::::::
+probability D :::::::::::
+matrix E :::::::::::
+ F :::::::::::
+ G 7746::::::1
+ H :::::::::::
+ I :::::::::::
+ K :::::::::::
+ L :::::::::::
+ M :::::::::::
+ N :::::::::::
+ P :::::::::::
+ Q :::::::::::
+ R :::::::::::
+ S :::::::::::
+ T 1:2:a:a:2::
+ V :::::::::::
+ W :::::::::::
+ Y :::::::::::
+
+ bits 10.6
+ 9.5
+ 8.5
+ 7.4
+Relative 6.3
+Entropy 5.3
+(13.8 bits) 4.2
+ 3.2
+ 2.1 * **
+ 1.1 ** ********
+ 0.0 -----------
+
+Multilevel GGGGTATAAAA
+consensus AACA T
+sequence
+
+
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ Motif 1 sites sorted by position p-value
+--------------------------------------------------------------------------------
+Sequence name Start P-value Site
+------------- ----- --------- -----------
+chr21_46046964_46047014_ 13 1.06e-06 AAGGCCAGGA GGGGTATAAAA GCCTGAGAGC
+chr21_46057197_46057247_ 37 3.41e-06 ACAGGCCCTG GGCATATAAAA GCC
+chr21_45971413_45971463_ 10 3.41e-06 CAGGCCCTG GGCATATAAAA GCCCCAGCAG
+chr21_31964683_31964733_ 14 3.41e-06 GATTCACTGA GGCATATAAAA GGCCCTCTGC
+chr21_45993530_45993580_ 8 4.00e-06 CCAAGGA GGAGTATAAAA GCCCCACAAA
+chr21_32202076_32202126_ 14 5.01e-06 CCACCAGCTT GAGGTATAAAA AGCCCTGTAC
+chr21_46031920_46031970_ 16 6.06e-06 ATACCCAGGG AGGGTATAAAA CCTCAGCAGC
+chr21_32410820_32410870_ 22 8.67e-06 AATCACTGAG GATGTATAAAA GTCCCAGGGA
+chr21_32185595_32185645_ 19 8.67e-06 CACCAGAGCT GGGATATATAA AGAAGGTTCT
+chr21_31992870_31992920_ 17 8.67e-06 CACTATTGAA GATGTATAAAA TTTCATTTGC
+chr21_46020421_46020471_ 3 1.21e-05 GA GACATATAAAA GCCAACATCC
+chr21_47517957_47518007_ 33 1.59e-05 CCGGCGGGGC GGGGTATAAAG GGGGCGG
+chr21_45978668_45978718_ 5 1.59e-05 CAGA GGGGTATAAAG GTTCCGACCA
+chr21_31914206_31914256_ 16 1.68e-05 CCCACTACTT AGAGTATAAAA TCATTCTGAG
+chr21_32253899_32253949_ 20 2.03e-05 CACCAGCAAG GATATATAAAA GCTCAGGAGT
+chr21_31744582_31744632_ 13 3.06e-05 CAGGTCTAAG AGCATATATAA CTTGGAGTCC
+chr21_19617074_19617124_ 40 3.06e-05 CCTCGGGACG TGGGTATATAA
+chr21_45705687_45705737_ 38 3.82e-05 CGTGGTCGCG GGGGTATAACA GC
+chr21_31768316_31768366_ 1 3.82e-05 . AACGTATATAA ATGGTCCTGT
+chr21_47575506_47575556_ 31 4.02e-05 GCTGCCGGTG AGCGTATAAAG GCCCTGGCG
+chr21_26934381_26934431_ 28 5.52e-05 AGTCACAAGT GAGTTATAAAA GGGTCGCACG
+chr21_31710037_31710087_ 15 5.94e-05 CCCAGGTTTC TGAGTATATAA TCGCCGCACC
+chr21_36411748_36411798_ 23 6.78e-05 AGTTTCAGTT GGCATCTAAAA ATTATATAAC
+chr21_31933633_31933683_ 3 2.08e-04 TC AGAGTATATAT AAATGTTCCT
+chr21_31962741_31962791_ 14 4.05e-04 TATAACTCAG GTTGGATAAAA TAATTTGTAC
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ Motif 1 block diagrams
+--------------------------------------------------------------------------------
+SEQUENCE NAME POSITION P-VALUE MOTIF DIAGRAM
+------------- ---------------- -------------
+chr21_46046964_46047014_ 1.1e-06 12_[1]_27
+chr21_46057197_46057247_ 3.4e-06 36_[1]_3
+chr21_45971413_45971463_ 3.4e-06 9_[1]_30
+chr21_31964683_31964733_ 3.4e-06 13_[1]_26
+chr21_45993530_45993580_ 4e-06 7_[1]_32
+chr21_32202076_32202126_ 5e-06 13_[1]_26
+chr21_46031920_46031970_ 6.1e-06 15_[1]_24
+chr21_32410820_32410870_ 8.7e-06 21_[1]_18
+chr21_32185595_32185645_ 8.7e-06 18_[1]_21
+chr21_31992870_31992920_ 8.7e-06 16_[1]_23
+chr21_46020421_46020471_ 1.2e-05 2_[1]_37
+chr21_47517957_47518007_ 1.6e-05 32_[1]_7
+chr21_45978668_45978718_ 1.6e-05 4_[1]_35
+chr21_31914206_31914256_ 1.7e-05 15_[1]_24
+chr21_32253899_32253949_ 2e-05 19_[1]_20
+chr21_31744582_31744632_ 3.1e-05 12_[1]_27
+chr21_19617074_19617124_ 3.1e-05 39_[1]
+chr21_45705687_45705737_ 3.8e-05 37_[1]_2
+chr21_31768316_31768366_ 3.8e-05 [1]_39
+chr21_47575506_47575556_ 4e-05 30_[1]_9
+chr21_26934381_26934431_ 5.5e-05 27_[1]_12
+chr21_31710037_31710087_ 5.9e-05 14_[1]_25
+chr21_36411748_36411798_ 6.8e-05 22_[1]_17
+chr21_31933633_31933683_ 0.00021 2_[1]_37
+chr21_31962741_31962791_ 0.0004 13_[1]_26
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ Motif 1 in BLOCKS format
+--------------------------------------------------------------------------------
+BL MOTIF 1 width=11 seqs=25
+chr21_46046964_46047014_ ( 13) GGGGTATAAAA 1
+chr21_46057197_46057247_ ( 37) GGCATATAAAA 1
+chr21_45971413_45971463_ ( 10) GGCATATAAAA 1
+chr21_31964683_31964733_ ( 14) GGCATATAAAA 1
+chr21_45993530_45993580_ ( 8) GGAGTATAAAA 1
+chr21_32202076_32202126_ ( 14) GAGGTATAAAA 1
+chr21_46031920_46031970_ ( 16) AGGGTATAAAA 1
+chr21_32410820_32410870_ ( 22) GATGTATAAAA 1
+chr21_32185595_32185645_ ( 19) GGGATATATAA 1
+chr21_31992870_31992920_ ( 17) GATGTATAAAA 1
+chr21_46020421_46020471_ ( 3) GACATATAAAA 1
+chr21_47517957_47518007_ ( 33) GGGGTATAAAG 1
+chr21_45978668_45978718_ ( 5) GGGGTATAAAG 1
+chr21_31914206_31914256_ ( 16) AGAGTATAAAA 1
+chr21_32253899_32253949_ ( 20) GATATATAAAA 1
+chr21_31744582_31744632_ ( 13) AGCATATATAA 1
+chr21_19617074_19617124_ ( 40) TGGGTATATAA 1
+chr21_45705687_45705737_ ( 38) GGGGTATAACA 1
+chr21_31768316_31768366_ ( 1) AACGTATATAA 1
+chr21_47575506_47575556_ ( 31) AGCGTATAAAG 1
+chr21_26934381_26934431_ ( 28) GAGTTATAAAA 1
+chr21_31710037_31710087_ ( 15) TGAGTATATAA 1
+chr21_36411748_36411798_ ( 23) GGCATCTAAAA 1
+chr21_31933633_31933683_ ( 3) AGAGTATATAT 1
+chr21_31962741_31962791_ ( 14) GTTGGATAAAA 1
+//
+
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ Motif 1 position-specific scoring matrix
+--------------------------------------------------------------------------------
+log-odds matrix: alength= 20 w= 11 n= 1200 bayes= 5.33554 E= 2.4e-011
+ -32 -680 91 77 7 138 -20 55 64 107 11 150 142 72 87 396 -148 221 -140 -36
+ -11 -680 89 76 7 137 -21 55 63 107 10 149 141 71 87 396 -239 220 -140 -36
+ -79 41 4 21 -7 44 -62 42 -5 99 0 99 138 52 42 399 -46 223 -173 -68
+ 11 -677 48 47 -2 127 -43 46 27 101 3 124 138 60 62 397 -235 220 -160 -55
+ -596 -820 12 -21 -53 -267 -74 37 16 44 -37 98 31 9 19 319 212 127 -193 -95
+ 165 -261 70 110 77 -521 -4 147 95 201 90 121 124 91 107 425 -527 314 -95 8
+ -838 -990 -89 -149 -151 -841 -161 -117 -113 -66 -209 -68 -69 -129 -91 111 221 -55 -255 -173
+ 176 -858 -79 -103 -115 -717 -148 -95 -108 -17 -162 -61 -12 -95 -69 193 -737 52 -240 -153
+ 134 -686 0 16 -12 -553 -68 44 -8 96 -9 88 124 41 36 384 11 216 -177 -71
+ 165 -261 70 110 77 -521 -4 147 95 201 90 121 124 91 107 425 -527 314 -95 8
+ 147 -614 89 129 93 -121 12 160 113 217 108 144 144 111 125 447 -241 332 -81 22
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ Motif 1 position-specific probability matrix
+--------------------------------------------------------------------------------
+letter-probability matrix: alength= 20 w= 11 nsites= 25 E= 2.4e-011
+ 0.240000 0.000000 0.000000 0.000000 0.000000 0.680000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.080000 0.000000 0.000000 0.000000
+ 0.280000 0.000000 0.000000 0.000000 0.000000 0.680000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000
+ 0.160000 0.320000 0.000000 0.000000 0.000000 0.360000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.160000 0.000000 0.000000 0.000000
+ 0.320000 0.000000 0.000000 0.000000 0.000000 0.640000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000
+ 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.960000 0.000000 0.000000 0.000000
+ 0.960000 0.040000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+ 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000
+ 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+ 0.760000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.240000 0.000000 0.000000 0.000000
+ 0.960000 0.040000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+ 0.840000 0.000000 0.000000 0.000000 0.000000 0.120000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.040000 0.000000 0.000000 0.000000
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ Motif 1 regular expression
+--------------------------------------------------------------------------------
+[GA][GA][GC][GA]TATA[AT]AA
+--------------------------------------------------------------------------------
+
+
+
+
+Time 1.56 secs.
+
+********************************************************************************
+
+
+********************************************************************************
+SUMMARY OF MOTIFS
+********************************************************************************
+
+--------------------------------------------------------------------------------
+ Combined block diagrams: non-overlapping sites with p-value < 0.0001
+--------------------------------------------------------------------------------
+SEQUENCE NAME COMBINED P-VALUE MOTIF DIAGRAM
+------------- ---------------- -------------
+chr21_19617074_19617124_ 1.22e-03 39_[1(3.06e-05)]
+chr21_26934381_26934431_ 2.21e-03 27_[1(5.52e-05)]_12
+chr21_28217753_28217803_ 7.29e-01 50
+chr21_31710037_31710087_ 2.37e-03 14_[1(5.94e-05)]_25
+chr21_31744582_31744632_ 1.22e-03 12_[1(3.06e-05)]_27
+chr21_31768316_31768366_ 1.53e-03 [1(3.82e-05)]_39
+chr21_31914206_31914256_ 6.70e-04 15_[1(1.68e-05)]_24
+chr21_31933633_31933683_ 1.81e-03 4_[1(4.54e-05)]_35
+chr21_31962741_31962791_ 1.61e-02 50
+chr21_31964683_31964733_ 1.36e-04 13_[1(3.41e-06)]_26
+chr21_31973364_31973414_ 1.99e-01 50
+chr21_31992870_31992920_ 3.47e-04 16_[1(8.67e-06)]_23
+chr21_32185595_32185645_ 3.47e-04 18_[1(8.67e-06)]_21
+chr21_32202076_32202126_ 2.01e-04 13_[1(5.01e-06)]_26
+chr21_32253899_32253949_ 8.11e-04 19_[1(2.03e-05)]_20
+chr21_32410820_32410870_ 3.47e-04 21_[1(8.67e-06)]_18
+chr21_36411748_36411798_ 2.71e-03 22_[1(6.78e-05)]_17
+chr21_37838750_37838800_ 8.23e-02 50
+chr21_45705687_45705737_ 1.53e-03 37_[1(3.82e-05)]_2
+chr21_45971413_45971463_ 1.36e-04 9_[1(3.41e-06)]_30
+chr21_45978668_45978718_ 6.37e-04 4_[1(1.59e-05)]_35
+chr21_45993530_45993580_ 1.60e-04 7_[1(4.00e-06)]_32
+chr21_46020421_46020471_ 4.83e-04 2_[1(1.21e-05)]_37
+chr21_46031920_46031970_ 2.43e-04 15_[1(6.06e-06)]_24
+chr21_46046964_46047014_ 4.26e-05 12_[1(1.06e-06)]_27
+chr21_46057197_46057247_ 1.36e-04 36_[1(3.41e-06)]_3
+chr21_46086869_46086919_ 4.30e-02 50
+chr21_46102103_46102153_ 4.30e-02 50
+chr21_47517957_47518007_ 6.37e-04 32_[1(1.59e-05)]_7
+chr21_47575506_47575556_ 1.61e-03 30_[1(4.02e-05)]_9
+--------------------------------------------------------------------------------
+
+********************************************************************************
+
+
+********************************************************************************
+Stopped because nmotifs = 1 reached.
+********************************************************************************
+
+CPU: dan
+
+********************************************************************************
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/meme/meme/meme_output_xml_1.xml Tue Feb 01 11:20:02 2011 -0500
@@ -0,0 +1,1284 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
+<!-- Document definition -->
+<!DOCTYPE MEME[
+<!ELEMENT MEME (
+ training_set,
+ model,
+ motifs,
+ scanned_sites_summary?
+)>
+<!ATTLIST MEME
+ version CDATA #REQUIRED
+ release CDATA #REQUIRED
+>
+<!-- Training-set elements -->
+<!ELEMENT training_set (alphabet, ambigs, sequence+, letter_frequencies)>
+<!ATTLIST training_set datafile CDATA #REQUIRED length CDATA #REQUIRED>
+<!ELEMENT alphabet (letter+)>
+<!ATTLIST alphabet id (amino-acid|nucleotide) #REQUIRED
+ length CDATA #REQUIRED>
+<!ELEMENT ambigs (letter+)>
+<!ELEMENT letter EMPTY>
+<!ATTLIST letter id ID #REQUIRED>
+<!ATTLIST letter symbol CDATA #REQUIRED>
+<!ELEMENT sequence EMPTY>
+<!ATTLIST sequence id ID #REQUIRED
+ name CDATA #REQUIRED
+ length CDATA #REQUIRED
+ weight CDATA #REQUIRED
+>
+<!ELEMENT letter_frequencies (alphabet_array)>
+
+<!-- Model elements -->
+<!ELEMENT model (
+ command_line,
+ host,
+ type,
+ nmotifs,
+ evalue_threshold,
+ object_function,
+ min_width,
+ max_width,
+ minic,
+ wg,
+ ws,
+ endgaps,
+ minsites,
+ maxsites,
+ wnsites,
+ prob,
+ spmap,
+ spfuzz,
+ prior,
+ beta,
+ maxiter,
+ distance,
+ num_sequences,
+ num_positions,
+ seed,
+ seqfrac,
+ strands,
+ priors_file,
+ reason_for_stopping,
+ background_frequencies
+)>
+<!ELEMENT command_line (#PCDATA)*>
+<!ELEMENT host (#PCDATA)*>
+<!ELEMENT type (#PCDATA)*>
+<!ELEMENT nmotifs (#PCDATA)*>
+<!ELEMENT evalue_threshold (#PCDATA)*>
+<!ELEMENT object_function (#PCDATA)*>
+<!ELEMENT min_width (#PCDATA)*>
+<!ELEMENT max_width (#PCDATA)*>
+<!ELEMENT minic (#PCDATA)*>
+<!ELEMENT wg (#PCDATA)*>
+<!ELEMENT ws (#PCDATA)*>
+<!ELEMENT endgaps (#PCDATA)*>
+<!ELEMENT minsites (#PCDATA)*>
+<!ELEMENT maxsites (#PCDATA)*>
+<!ELEMENT wnsites (#PCDATA)*>
+<!ELEMENT prob (#PCDATA)*>
+<!ELEMENT spmap (#PCDATA)*>
+<!ELEMENT spfuzz (#PCDATA)*>
+<!ELEMENT prior (#PCDATA)*>
+<!ELEMENT beta (#PCDATA)*>
+<!ELEMENT maxiter (#PCDATA)*>
+<!ELEMENT distance (#PCDATA)*>
+<!ELEMENT num_sequences (#PCDATA)*>
+<!ELEMENT num_positions (#PCDATA)*>
+<!ELEMENT seed (#PCDATA)*>
+<!ELEMENT seqfrac (#PCDATA)*>
+<!ELEMENT strands (#PCDATA)*>
+<!ELEMENT priors_file (#PCDATA)*>
+<!ELEMENT reason_for_stopping (#PCDATA)*>
+<!ELEMENT background_frequencies (alphabet_array)>
+<!ATTLIST background_frequencies source CDATA #REQUIRED>
+
+<!-- Motif elements -->
+<!ELEMENT motifs (motif+)>
+<!ELEMENT motif (scores, probabilities, regular_expression?, contributing_sites)>
+<!ATTLIST motif id ID #REQUIRED
+ name CDATA #REQUIRED
+ width CDATA #REQUIRED
+ sites CDATA #REQUIRED
+ llr CDATA #REQUIRED
+ ic CDATA #REQUIRED
+ re CDATA #REQUIRED
+ bayes_threshold CDATA #REQUIRED
+ e_value CDATA #REQUIRED
+ elapsed_time CDATA #REQUIRED
+ url CDATA ""
+>
+<!ELEMENT scores (alphabet_matrix)>
+<!ELEMENT probabilities (alphabet_matrix)>
+<!ELEMENT regular_expression (#PCDATA)*>
+
+<!-- Contributing site elements -->
+<!-- Contributing sites are motif occurences found during the motif discovery phase -->
+<!ELEMENT contributing_sites (contributing_site+)>
+<!ELEMENT contributing_site (left_flank, site, right_flank)>
+<!ATTLIST contributing_site sequence_id IDREF #REQUIRED
+ position CDATA #REQUIRED
+ strand (plus|minus|none) 'none'
+ pvalue CDATA #REQUIRED
+>
+<!-- The left_flank contains the sequence for 10 bases to the left of the motif start -->
+<!ELEMENT left_flank (#PCDATA)>
+<!-- The site contains the sequence for the motif instance -->
+<!ELEMENT site (letter_ref+)>
+<!-- The right_flank contains the sequence for 10 bases to the right of the motif end -->
+<!ELEMENT right_flank (#PCDATA)>
+
+<!-- Scanned site elements -->
+<!-- Scanned sites are motif occurences found during the sequence scan phase -->
+<!ELEMENT scanned_sites_summary (scanned_sites+)>
+<!ATTLIST scanned_sites_summary p_thresh CDATA #REQUIRED>
+<!ELEMENT scanned_sites (scanned_site*)>
+<!ATTLIST scanned_sites sequence_id IDREF #REQUIRED
+ pvalue CDATA #REQUIRED
+ num_sites CDATA #REQUIRED>
+<!ELEMENT scanned_site EMPTY>
+<!ATTLIST scanned_site motif_id IDREF #REQUIRED
+ strand (plus|minus|none) 'none'
+ position CDATA #REQUIRED
+ pvalue CDATA #REQUIRED>
+
+<!-- Utility elements -->
+<!-- A reference to a letter in the alphabet -->
+<!ELEMENT letter_ref EMPTY>
+<!ATTLIST letter_ref letter_id IDREF #REQUIRED>
+<!-- A alphabet-array contains one floating point value for each letter in an alphabet -->
+<!ELEMENT alphabet_array (value+)>
+<!ELEMENT value (#PCDATA)>
+<!ATTLIST value letter_id IDREF #REQUIRED>
+
+<!-- A alphabet_matrix contains one alphabet_array for each position in a motif -->
+<!ELEMENT alphabet_matrix (alphabet_array+)>
+
+]>
+<!-- Begin document body -->
+<MEME version="4.5.0" release="Thu Oct 14 08:44:28 EST 2010">
+<training_set datafile="/dan_110.dat" length="30">
+<alphabet id="amino-acid" length="20">
+<letter id="letter_A" symbol="A"/>
+<letter id="letter_C" symbol="C"/>
+<letter id="letter_D" symbol="D"/>
+<letter id="letter_E" symbol="E"/>
+<letter id="letter_F" symbol="F"/>
+<letter id="letter_G" symbol="G"/>
+<letter id="letter_H" symbol="H"/>
+<letter id="letter_I" symbol="I"/>
+<letter id="letter_K" symbol="K"/>
+<letter id="letter_L" symbol="L"/>
+<letter id="letter_M" symbol="M"/>
+<letter id="letter_N" symbol="N"/>
+<letter id="letter_P" symbol="P"/>
+<letter id="letter_Q" symbol="Q"/>
+<letter id="letter_R" symbol="R"/>
+<letter id="letter_S" symbol="S"/>
+<letter id="letter_T" symbol="T"/>
+<letter id="letter_V" symbol="V"/>
+<letter id="letter_W" symbol="W"/>
+<letter id="letter_Y" symbol="Y"/>
+</alphabet>
+<ambigs>
+<letter id="letter_B" symbol="B"/>
+<letter id="letter_U" symbol="U"/>
+<letter id="letter_X" symbol="X"/>
+<letter id="letter_Z" symbol="Z"/>
+<letter id="letter_star" symbol="*"/>
+<letter id="letter_-" symbol="-"/>
+</ambigs>
+<sequence id="sequence_0" name="chr21_19617074_19617124_+" length="50" weight="1.000000" />
+<sequence id="sequence_1" name="chr21_26934381_26934431_+" length="50" weight="1.000000" />
+<sequence id="sequence_2" name="chr21_28217753_28217803_-" length="50" weight="1.000000" />
+<sequence id="sequence_3" name="chr21_31710037_31710087_-" length="50" weight="1.000000" />
+<sequence id="sequence_4" name="chr21_31744582_31744632_-" length="50" weight="1.000000" />
+<sequence id="sequence_5" name="chr21_31768316_31768366_+" length="50" weight="1.000000" />
+<sequence id="sequence_6" name="chr21_31914206_31914256_-" length="50" weight="1.000000" />
+<sequence id="sequence_7" name="chr21_31933633_31933683_-" length="50" weight="1.000000" />
+<sequence id="sequence_8" name="chr21_31962741_31962791_-" length="50" weight="1.000000" />
+<sequence id="sequence_9" name="chr21_31964683_31964733_+" length="50" weight="1.000000" />
+<sequence id="sequence_10" name="chr21_31973364_31973414_+" length="50" weight="1.000000" />
+<sequence id="sequence_11" name="chr21_31992870_31992920_+" length="50" weight="1.000000" />
+<sequence id="sequence_12" name="chr21_32185595_32185645_-" length="50" weight="1.000000" />
+<sequence id="sequence_13" name="chr21_32202076_32202126_-" length="50" weight="1.000000" />
+<sequence id="sequence_14" name="chr21_32253899_32253949_-" length="50" weight="1.000000" />
+<sequence id="sequence_15" name="chr21_32410820_32410870_-" length="50" weight="1.000000" />
+<sequence id="sequence_16" name="chr21_36411748_36411798_-" length="50" weight="1.000000" />
+<sequence id="sequence_17" name="chr21_37838750_37838800_-" length="50" weight="1.000000" />
+<sequence id="sequence_18" name="chr21_45705687_45705737_+" length="50" weight="1.000000" />
+<sequence id="sequence_19" name="chr21_45971413_45971463_-" length="50" weight="1.000000" />
+<sequence id="sequence_20" name="chr21_45978668_45978718_-" length="50" weight="1.000000" />
+<sequence id="sequence_21" name="chr21_45993530_45993580_+" length="50" weight="1.000000" />
+<sequence id="sequence_22" name="chr21_46020421_46020471_+" length="50" weight="1.000000" />
+<sequence id="sequence_23" name="chr21_46031920_46031970_+" length="50" weight="1.000000" />
+<sequence id="sequence_24" name="chr21_46046964_46047014_+" length="50" weight="1.000000" />
+<sequence id="sequence_25" name="chr21_46057197_46057247_+" length="50" weight="1.000000" />
+<sequence id="sequence_26" name="chr21_46086869_46086919_-" length="50" weight="1.000000" />
+<sequence id="sequence_27" name="chr21_46102103_46102153_-" length="50" weight="1.000000" />
+<sequence id="sequence_28" name="chr21_47517957_47518007_+" length="50" weight="1.000000" />
+<sequence id="sequence_29" name="chr21_47575506_47575556_-" length="50" weight="1.000000" />
+<letter_frequencies>
+<alphabet_array>
+<value letter_id="letter_A">0.294</value>
+<value letter_id="letter_C">0.231</value>
+<value letter_id="letter_D">0.000</value>
+<value letter_id="letter_E">0.000</value>
+<value letter_id="letter_F">0.000</value>
+<value letter_id="letter_G">0.257</value>
+<value letter_id="letter_H">0.000</value>
+<value letter_id="letter_I">0.000</value>
+<value letter_id="letter_K">0.000</value>
+<value letter_id="letter_L">0.000</value>
+<value letter_id="letter_M">0.000</value>
+<value letter_id="letter_N">0.000</value>
+<value letter_id="letter_P">0.000</value>
+<value letter_id="letter_Q">0.000</value>
+<value letter_id="letter_R">0.000</value>
+<value letter_id="letter_S">0.000</value>
+<value letter_id="letter_T">0.217</value>
+<value letter_id="letter_V">0.000</value>
+<value letter_id="letter_W">0.000</value>
+<value letter_id="letter_Y">0.000</value>
+</alphabet_array>
+</letter_frequencies>
+</training_set>
+<model>
+<command_line>meme /dan.dat -o /dataset_dan_files -nostatus </command_line>
+<host>dan</host>
+<type>zoops</type>
+<nmotifs>1</nmotifs>
+<evalue_threshold>inf</evalue_threshold>
+<object_function>E-value of product of p-values</object_function>
+<min_width>8</min_width>
+<max_width>50</max_width>
+<minic> 0.00</minic>
+<wg>11</wg>
+<ws>1</ws>
+<endgaps>yes</endgaps>
+<minsites>2</minsites>
+<maxsites>30</maxsites>
+<wnsites>0.8</wnsites>
+<prob>1</prob>
+<spmap>pam</spmap>
+<spfuzz>120</spfuzz>
+<prior>megap</prior>
+<beta>7500</beta>
+<maxiter>50</maxiter>
+<distance>1e-05</distance>
+<num_sequences>30</num_sequences>
+<num_positions>1500</num_positions>
+<seed>0</seed>
+<seqfrac> 1</seqfrac>
+<strands>none</strands>
+<priors_file>prior30.plib</priors_file>
+<reason_for_stopping>Stopped because nmotifs = 1 reached.</reason_for_stopping>
+<background_frequencies source="dataset with add-one prior applied">
+<alphabet_array>
+<value letter_id="letter_A">0.291</value>
+<value letter_id="letter_C">0.229</value>
+<value letter_id="letter_D">0.001</value>
+<value letter_id="letter_E">0.001</value>
+<value letter_id="letter_F">0.001</value>
+<value letter_id="letter_G">0.255</value>
+<value letter_id="letter_H">0.001</value>
+<value letter_id="letter_I">0.001</value>
+<value letter_id="letter_K">0.001</value>
+<value letter_id="letter_L">0.001</value>
+<value letter_id="letter_M">0.001</value>
+<value letter_id="letter_N">0.001</value>
+<value letter_id="letter_P">0.001</value>
+<value letter_id="letter_Q">0.001</value>
+<value letter_id="letter_R">0.001</value>
+<value letter_id="letter_S">0.001</value>
+<value letter_id="letter_T">0.215</value>
+<value letter_id="letter_V">0.001</value>
+<value letter_id="letter_W">0.001</value>
+<value letter_id="letter_Y">0.001</value>
+</alphabet_array>
+</background_frequencies>
+</model>
+<motifs>
+<motif id="motif_1" name="1" width="11" sites="25" ic="40.0" re="13.8" llr="239" e_value="2.4e-011" bayes_threshold="5.33554" elapsed_time="1.563760">
+<scores>
+<alphabet_matrix>
+<alphabet_array>
+<value letter_id="letter_A">-32</value>
+<value letter_id="letter_C">-680</value>
+<value letter_id="letter_D">91</value>
+<value letter_id="letter_E">77</value>
+<value letter_id="letter_F">7</value>
+<value letter_id="letter_G">138</value>
+<value letter_id="letter_H">-20</value>
+<value letter_id="letter_I">55</value>
+<value letter_id="letter_K">64</value>
+<value letter_id="letter_L">107</value>
+<value letter_id="letter_M">11</value>
+<value letter_id="letter_N">150</value>
+<value letter_id="letter_P">142</value>
+<value letter_id="letter_Q">72</value>
+<value letter_id="letter_R">87</value>
+<value letter_id="letter_S">396</value>
+<value letter_id="letter_T">-148</value>
+<value letter_id="letter_V">221</value>
+<value letter_id="letter_W">-140</value>
+<value letter_id="letter_Y">-36</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">-11</value>
+<value letter_id="letter_C">-680</value>
+<value letter_id="letter_D">89</value>
+<value letter_id="letter_E">76</value>
+<value letter_id="letter_F">7</value>
+<value letter_id="letter_G">137</value>
+<value letter_id="letter_H">-21</value>
+<value letter_id="letter_I">55</value>
+<value letter_id="letter_K">63</value>
+<value letter_id="letter_L">107</value>
+<value letter_id="letter_M">10</value>
+<value letter_id="letter_N">149</value>
+<value letter_id="letter_P">141</value>
+<value letter_id="letter_Q">71</value>
+<value letter_id="letter_R">87</value>
+<value letter_id="letter_S">396</value>
+<value letter_id="letter_T">-239</value>
+<value letter_id="letter_V">220</value>
+<value letter_id="letter_W">-140</value>
+<value letter_id="letter_Y">-36</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">-79</value>
+<value letter_id="letter_C">41</value>
+<value letter_id="letter_D">4</value>
+<value letter_id="letter_E">21</value>
+<value letter_id="letter_F">-7</value>
+<value letter_id="letter_G">44</value>
+<value letter_id="letter_H">-62</value>
+<value letter_id="letter_I">42</value>
+<value letter_id="letter_K">-5</value>
+<value letter_id="letter_L">99</value>
+<value letter_id="letter_M">0</value>
+<value letter_id="letter_N">99</value>
+<value letter_id="letter_P">138</value>
+<value letter_id="letter_Q">52</value>
+<value letter_id="letter_R">42</value>
+<value letter_id="letter_S">399</value>
+<value letter_id="letter_T">-46</value>
+<value letter_id="letter_V">223</value>
+<value letter_id="letter_W">-173</value>
+<value letter_id="letter_Y">-68</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">11</value>
+<value letter_id="letter_C">-677</value>
+<value letter_id="letter_D">48</value>
+<value letter_id="letter_E">47</value>
+<value letter_id="letter_F">-2</value>
+<value letter_id="letter_G">127</value>
+<value letter_id="letter_H">-43</value>
+<value letter_id="letter_I">46</value>
+<value letter_id="letter_K">27</value>
+<value letter_id="letter_L">101</value>
+<value letter_id="letter_M">3</value>
+<value letter_id="letter_N">124</value>
+<value letter_id="letter_P">138</value>
+<value letter_id="letter_Q">60</value>
+<value letter_id="letter_R">62</value>
+<value letter_id="letter_S">397</value>
+<value letter_id="letter_T">-235</value>
+<value letter_id="letter_V">220</value>
+<value letter_id="letter_W">-160</value>
+<value letter_id="letter_Y">-55</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">-596</value>
+<value letter_id="letter_C">-820</value>
+<value letter_id="letter_D">12</value>
+<value letter_id="letter_E">-21</value>
+<value letter_id="letter_F">-53</value>
+<value letter_id="letter_G">-267</value>
+<value letter_id="letter_H">-74</value>
+<value letter_id="letter_I">37</value>
+<value letter_id="letter_K">16</value>
+<value letter_id="letter_L">44</value>
+<value letter_id="letter_M">-37</value>
+<value letter_id="letter_N">98</value>
+<value letter_id="letter_P">31</value>
+<value letter_id="letter_Q">9</value>
+<value letter_id="letter_R">19</value>
+<value letter_id="letter_S">319</value>
+<value letter_id="letter_T">212</value>
+<value letter_id="letter_V">127</value>
+<value letter_id="letter_W">-193</value>
+<value letter_id="letter_Y">-95</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">165</value>
+<value letter_id="letter_C">-261</value>
+<value letter_id="letter_D">70</value>
+<value letter_id="letter_E">110</value>
+<value letter_id="letter_F">77</value>
+<value letter_id="letter_G">-521</value>
+<value letter_id="letter_H">-4</value>
+<value letter_id="letter_I">147</value>
+<value letter_id="letter_K">95</value>
+<value letter_id="letter_L">201</value>
+<value letter_id="letter_M">90</value>
+<value letter_id="letter_N">121</value>
+<value letter_id="letter_P">124</value>
+<value letter_id="letter_Q">91</value>
+<value letter_id="letter_R">107</value>
+<value letter_id="letter_S">425</value>
+<value letter_id="letter_T">-527</value>
+<value letter_id="letter_V">314</value>
+<value letter_id="letter_W">-95</value>
+<value letter_id="letter_Y">8</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">-838</value>
+<value letter_id="letter_C">-990</value>
+<value letter_id="letter_D">-89</value>
+<value letter_id="letter_E">-149</value>
+<value letter_id="letter_F">-151</value>
+<value letter_id="letter_G">-841</value>
+<value letter_id="letter_H">-161</value>
+<value letter_id="letter_I">-117</value>
+<value letter_id="letter_K">-113</value>
+<value letter_id="letter_L">-66</value>
+<value letter_id="letter_M">-209</value>
+<value letter_id="letter_N">-68</value>
+<value letter_id="letter_P">-69</value>
+<value letter_id="letter_Q">-129</value>
+<value letter_id="letter_R">-91</value>
+<value letter_id="letter_S">111</value>
+<value letter_id="letter_T">221</value>
+<value letter_id="letter_V">-55</value>
+<value letter_id="letter_W">-255</value>
+<value letter_id="letter_Y">-173</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">176</value>
+<value letter_id="letter_C">-858</value>
+<value letter_id="letter_D">-79</value>
+<value letter_id="letter_E">-103</value>
+<value letter_id="letter_F">-115</value>
+<value letter_id="letter_G">-717</value>
+<value letter_id="letter_H">-148</value>
+<value letter_id="letter_I">-95</value>
+<value letter_id="letter_K">-108</value>
+<value letter_id="letter_L">-17</value>
+<value letter_id="letter_M">-162</value>
+<value letter_id="letter_N">-61</value>
+<value letter_id="letter_P">-12</value>
+<value letter_id="letter_Q">-95</value>
+<value letter_id="letter_R">-69</value>
+<value letter_id="letter_S">193</value>
+<value letter_id="letter_T">-737</value>
+<value letter_id="letter_V">52</value>
+<value letter_id="letter_W">-240</value>
+<value letter_id="letter_Y">-153</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">134</value>
+<value letter_id="letter_C">-686</value>
+<value letter_id="letter_D">0</value>
+<value letter_id="letter_E">16</value>
+<value letter_id="letter_F">-12</value>
+<value letter_id="letter_G">-553</value>
+<value letter_id="letter_H">-68</value>
+<value letter_id="letter_I">44</value>
+<value letter_id="letter_K">-8</value>
+<value letter_id="letter_L">96</value>
+<value letter_id="letter_M">-9</value>
+<value letter_id="letter_N">88</value>
+<value letter_id="letter_P">124</value>
+<value letter_id="letter_Q">41</value>
+<value letter_id="letter_R">36</value>
+<value letter_id="letter_S">384</value>
+<value letter_id="letter_T">11</value>
+<value letter_id="letter_V">216</value>
+<value letter_id="letter_W">-177</value>
+<value letter_id="letter_Y">-71</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">165</value>
+<value letter_id="letter_C">-261</value>
+<value letter_id="letter_D">70</value>
+<value letter_id="letter_E">110</value>
+<value letter_id="letter_F">77</value>
+<value letter_id="letter_G">-521</value>
+<value letter_id="letter_H">-4</value>
+<value letter_id="letter_I">147</value>
+<value letter_id="letter_K">95</value>
+<value letter_id="letter_L">201</value>
+<value letter_id="letter_M">90</value>
+<value letter_id="letter_N">121</value>
+<value letter_id="letter_P">124</value>
+<value letter_id="letter_Q">91</value>
+<value letter_id="letter_R">107</value>
+<value letter_id="letter_S">425</value>
+<value letter_id="letter_T">-527</value>
+<value letter_id="letter_V">314</value>
+<value letter_id="letter_W">-95</value>
+<value letter_id="letter_Y">8</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">147</value>
+<value letter_id="letter_C">-614</value>
+<value letter_id="letter_D">89</value>
+<value letter_id="letter_E">129</value>
+<value letter_id="letter_F">93</value>
+<value letter_id="letter_G">-121</value>
+<value letter_id="letter_H">12</value>
+<value letter_id="letter_I">160</value>
+<value letter_id="letter_K">113</value>
+<value letter_id="letter_L">217</value>
+<value letter_id="letter_M">108</value>
+<value letter_id="letter_N">144</value>
+<value letter_id="letter_P">144</value>
+<value letter_id="letter_Q">111</value>
+<value letter_id="letter_R">125</value>
+<value letter_id="letter_S">447</value>
+<value letter_id="letter_T">-241</value>
+<value letter_id="letter_V">332</value>
+<value letter_id="letter_W">-81</value>
+<value letter_id="letter_Y">22</value>
+</alphabet_array>
+</alphabet_matrix>
+</scores>
+<probabilities>
+<alphabet_matrix>
+<alphabet_array>
+<value letter_id="letter_A">0.240000</value>
+<value letter_id="letter_C">0.000000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.680000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.080000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">0.280000</value>
+<value letter_id="letter_C">0.000000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.680000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.040000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">0.160000</value>
+<value letter_id="letter_C">0.320000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.360000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.160000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">0.320000</value>
+<value letter_id="letter_C">0.000000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.640000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.040000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">0.000000</value>
+<value letter_id="letter_C">0.000000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.040000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.960000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">0.960000</value>
+<value letter_id="letter_C">0.040000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.000000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.000000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">0.000000</value>
+<value letter_id="letter_C">0.000000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.000000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">1.000000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">1.000000</value>
+<value letter_id="letter_C">0.000000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.000000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.000000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">0.760000</value>
+<value letter_id="letter_C">0.000000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.000000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.240000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">0.960000</value>
+<value letter_id="letter_C">0.040000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.000000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.000000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+<alphabet_array>
+<value letter_id="letter_A">0.840000</value>
+<value letter_id="letter_C">0.000000</value>
+<value letter_id="letter_D">0.000000</value>
+<value letter_id="letter_E">0.000000</value>
+<value letter_id="letter_F">0.000000</value>
+<value letter_id="letter_G">0.120000</value>
+<value letter_id="letter_H">0.000000</value>
+<value letter_id="letter_I">0.000000</value>
+<value letter_id="letter_K">0.000000</value>
+<value letter_id="letter_L">0.000000</value>
+<value letter_id="letter_M">0.000000</value>
+<value letter_id="letter_N">0.000000</value>
+<value letter_id="letter_P">0.000000</value>
+<value letter_id="letter_Q">0.000000</value>
+<value letter_id="letter_R">0.000000</value>
+<value letter_id="letter_S">0.000000</value>
+<value letter_id="letter_T">0.040000</value>
+<value letter_id="letter_V">0.000000</value>
+<value letter_id="letter_W">0.000000</value>
+<value letter_id="letter_Y">0.000000</value>
+</alphabet_array>
+</alphabet_matrix>
+</probabilities>
+<regular_expression>
+[GA][GA][GC][GA]TATA[AT]AA
+</regular_expression>
+<contributing_sites>
+<contributing_site sequence_id="sequence_24" position="12" strand="none" pvalue="1.06e-06" >
+<left_flank>AAGGCCAGGA</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GCCTGAGAGC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_25" position="36" strand="none" pvalue="3.41e-06" >
+<left_flank>ACAGGCCCTG</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GCC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_19" position="9" strand="none" pvalue="3.41e-06" >
+<left_flank>CAGGCCCTG</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GCCCCAGCAG</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_9" position="13" strand="none" pvalue="3.41e-06" >
+<left_flank>GATTCACTGA</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GGCCCTCTGC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_21" position="7" strand="none" pvalue="4.00e-06" >
+<left_flank>CCAAGGA</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GCCCCACAAA</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_13" position="13" strand="none" pvalue="5.01e-06" >
+<left_flank>CCACCAGCTT</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>AGCCCTGTAC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_23" position="15" strand="none" pvalue="6.06e-06" >
+<left_flank>ATACCCAGGG</left_flank>
+<site>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>CCTCAGCAGC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_15" position="21" strand="none" pvalue="8.67e-06" >
+<left_flank>AATCACTGAG</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GTCCCAGGGA</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_12" position="18" strand="none" pvalue="8.67e-06" >
+<left_flank>CACCAGAGCT</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>AGAAGGTTCT</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_11" position="16" strand="none" pvalue="8.67e-06" >
+<left_flank>CACTATTGAA</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>TTTCATTTGC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_22" position="2" strand="none" pvalue="1.21e-05" >
+<left_flank>GA</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GCCAACATCC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_28" position="32" strand="none" pvalue="1.59e-05" >
+<left_flank>CCGGCGGGGC</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+</site>
+<right_flank>GGGGCGG</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_20" position="4" strand="none" pvalue="1.59e-05" >
+<left_flank>CAGA</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+</site>
+<right_flank>GTTCCGACCA</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_6" position="15" strand="none" pvalue="1.68e-05" >
+<left_flank>CCCACTACTT</left_flank>
+<site>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>TCATTCTGAG</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_14" position="19" strand="none" pvalue="2.03e-05" >
+<left_flank>CACCAGCAAG</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GCTCAGGAGT</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_4" position="12" strand="none" pvalue="3.06e-05" >
+<left_flank>CAGGTCTAAG</left_flank>
+<site>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>CTTGGAGTCC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_0" position="39" strand="none" pvalue="3.06e-05" >
+<left_flank>CCTCGGGACG</left_flank>
+<site>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank></right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_18" position="37" strand="none" pvalue="3.82e-05" >
+<left_flank>CGTGGTCGCG</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_5" position="0" strand="none" pvalue="3.82e-05" >
+<left_flank></left_flank>
+<site>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>ATGGTCCTGT</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_29" position="30" strand="none" pvalue="4.02e-05" >
+<left_flank>GCTGCCGGTG</left_flank>
+<site>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+</site>
+<right_flank>GCCCTGGCG</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_1" position="27" strand="none" pvalue="5.52e-05" >
+<left_flank>AGTCACAAGT</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>GGGTCGCACG</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_3" position="14" strand="none" pvalue="5.94e-05" >
+<left_flank>CCCAGGTTTC</left_flank>
+<site>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>TCGCCGCACC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_16" position="22" strand="none" pvalue="6.78e-05" >
+<left_flank>AGTTTCAGTT</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_C"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>ATTATATAAC</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_7" position="2" strand="none" pvalue="2.08e-04" >
+<left_flank>TC</left_flank>
+<site>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+</site>
+<right_flank>AAATGTTCCT</right_flank>
+</contributing_site>
+<contributing_site sequence_id="sequence_8" position="13" strand="none" pvalue="4.05e-04" >
+<left_flank>TATAACTCAG</left_flank>
+<site>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_G"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_T"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+<letter_ref letter_id="letter_A"/>
+</site>
+<right_flank>TAATTTGTAC</right_flank>
+</contributing_site>
+</contributing_sites>
+</motif>
+</motifs>
+<scanned_sites_summary p_thresh="0.0001">
+<scanned_sites sequence_id="sequence_0" pvalue="1.22e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="39" pvalue="3.06e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_1" pvalue="2.21e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="27" pvalue="5.52e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_2" pvalue="7.29e-01" num_sites="0"></scanned_sites>
+<scanned_sites sequence_id="sequence_3" pvalue="2.37e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="14" pvalue="5.94e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_4" pvalue="1.22e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="12" pvalue="3.06e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_5" pvalue="1.53e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="0" pvalue="3.82e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_6" pvalue="6.70e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="15" pvalue="1.68e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_7" pvalue="1.81e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="4" pvalue="4.54e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_8" pvalue="1.61e-02" num_sites="0"></scanned_sites>
+<scanned_sites sequence_id="sequence_9" pvalue="1.36e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="13" pvalue="3.41e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_10" pvalue="1.99e-01" num_sites="0"></scanned_sites>
+<scanned_sites sequence_id="sequence_11" pvalue="3.47e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="16" pvalue="8.67e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_12" pvalue="3.47e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="18" pvalue="8.67e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_13" pvalue="2.01e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="13" pvalue="5.01e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_14" pvalue="8.11e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="19" pvalue="2.03e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_15" pvalue="3.47e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="21" pvalue="8.67e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_16" pvalue="2.71e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="22" pvalue="6.78e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_17" pvalue="8.23e-02" num_sites="0"></scanned_sites>
+<scanned_sites sequence_id="sequence_18" pvalue="1.53e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="37" pvalue="3.82e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_19" pvalue="1.36e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="9" pvalue="3.41e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_20" pvalue="6.37e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="4" pvalue="1.59e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_21" pvalue="1.60e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="7" pvalue="4.00e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_22" pvalue="4.83e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="2" pvalue="1.21e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_23" pvalue="2.43e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="15" pvalue="6.06e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_24" pvalue="4.26e-05" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="12" pvalue="1.06e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_25" pvalue="1.36e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="36" pvalue="3.41e-06"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_26" pvalue="4.30e-02" num_sites="0"></scanned_sites>
+<scanned_sites sequence_id="sequence_27" pvalue="4.30e-02" num_sites="0"></scanned_sites>
+<scanned_sites sequence_id="sequence_28" pvalue="6.37e-04" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="32" pvalue="1.59e-05"/>
+</scanned_sites>
+<scanned_sites sequence_id="sequence_29" pvalue="1.61e-03" num_sites="1"><scanned_site motif_id="motif_1" strand="none" position="30" pvalue="4.02e-05"/>
+</scanned_sites>
+</scanned_sites_summary>
+</MEME>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/meme_input_1.fasta Tue Feb 01 11:20:02 2011 -0500
@@ -0,0 +1,66 @@
+>chr21_19617074_19617124_+
+AAAAATTATTACTAGGGAGGGGGCCGGAACCTCGGGACGTGGGTATATAA
+>chr21_26934381_26934431_+
+GCGCCTGGTCGGTTATGAGTCACAAGTGAGTTATAAAAGGGTCGCACGTT
+>chr21_28217753_28217803_-
+CAAAGGGGAGGAGTGGGGTGGGGGTGGGGGTTTCACTGGTCCACTATAAA
+>chr21_31710037_31710087_-
+AACACCCAGGTTTCTGAGTATATAATCGCCGCACCAAAGAATTTAATTTT
+>chr21_31744582_31744632_-
+CCCAGGTCTAAGAGCATATATAACTTGGAGTCCAGACTATGACATTCAAA
+>chr21_31768316_31768366_+
+AACGTATATAAATGGTCCTGTCCAGATGTGGCATGCAAACTCAGAATCTT
+>chr21_31914206_31914256_-
+TGACACCCACTACTTAGAGTATAAAATCATTCTGAGAAGTTAGAGACACC
+>chr21_31933633_31933683_-
+TCAGAGTATATATAAATGTTCCTGTCCAGTCACAGTCACCAAACTGACCT
+>chr21_31962741_31962791_-
+ACATATAACTCAGGTTGGATAAAATAATTTGTACAAATCAGGAGAGTCAA
+>chr21_31964683_31964733_+
+TCTGATTCACTGAGGCATATAAAAGGCCCTCTGCGGAGAAGTGTCCATAC
+>chr21_31973364_31973414_+
+aaacttaaaactctataaacttaaaactCTAGAATCTGATCCTGCTATAC
+>chr21_31992870_31992920_+
+CTCATACACTATTGAAGATGTATAAAATTTCATTTGCAGATGGTGACATT
+>chr21_32185595_32185645_-
+TCACCACCCACCAGAGCTGGGATATATAAAGAAGGTTCTGAGACTAGGAA
+>chr21_32202076_32202126_-
+TGCCCACCAGCTTGAGGTATAAAAAGCCCTGTACGGGAAGAGACCTTCAT
+>chr21_32253899_32253949_-
+AGCCCCACCCACCAGCAAGGATATATAAAAGCTCAGGAGTCTGGAGTGAC
+>chr21_32410820_32410870_-
+TCTACCCCACTAATCACTGAGGATGTATAAAAGTCCCAGGGAAGCTGGTG
+>chr21_36411748_36411798_-
+ATAGTTCTGTATAGTTTCAGTTGGCATCtaaaaattatataactttattt
+>chr21_37838750_37838800_-
+gatggttttataaggggcctcaccctcggctcagccctcattcttctcct
+>chr21_45705687_45705737_+
+CCGGGGCGGAGCGGCCTTTGCTCTTTGCGTGGTCGCGGGGGTATAACAGC
+>chr21_45971413_45971463_-
+CAGGCCCTGGGCATATAAAAGCCCCAGCAGCCAACAGGctcacacacaca
+>chr21_45978668_45978718_-
+CAGAGGGGTATAAAGGTTCCGACCACTCAGAGGCCTGGCACGAtcactca
+>chr21_45993530_45993580_+
+CCAAGGAGGAGTATAAAAGCCCCACAAACCCGAGCACCTCACTCACTCGC
+>chr21_46020421_46020471_+
+GAGACATATAAAAGCCAACATCCCTGAGCACCTAACACACGGactcactc
+>chr21_46031920_46031970_+
+GGAAAATACCCAGGGAGGGTATAAAACCTCAGCAGCCAGGGCACACAAAC
+>chr21_46046964_46047014_+
+ACAAGGCCAGGAGGGGTATAAAAGCCTGAGAGCCCCAAGAACctcacaca
+>chr21_46057197_46057247_+
+ATTGCTGAGTCTCCTGCTGGGAAAACACAGGCCCTGGGCATATAAAAGCC
+>chr21_46086869_46086919_-
+GACAGGTGTGCTTCTGTGCTGTGGGGATGCCTGGGCCCAGGTATAAAGGC
+>chr21_46102103_46102153_-
+AGGTGTGTGCTTCTGTGCTGTGGGGATGCCTGGGTCCAGGTATAAAGGCT
+>chr21_47517957_47518007_+
+CCTGGCGGCGGGGCGGGTCAGGCCGGCGGGGCGGGGTATAAAGGGGGCGG
+>chr21_47517957_47518007_+
+CCTGGCGGCGGGGCGGGTCAGGCCGGCGGGGCGGGGTATAAAGGGGGCGG
+>chr21_47517957_47518007_+
+CCTGGCGGCGGGGCGGGTCAGGCCGGCGGGGCGGGGTATAAAGGGGGCGG
+>chr21_47575506_47575556_-
+TGAGAAGCCGGTGGGGAGGTGCTGCCGGTGAGCGTATAAAGGCCCTGGCG
+>chr21_47575506_47575556_-
+TGAGAAGCCGGTGGGGAGGTGCTGCCGGTGAGCGTATAAAGGCCCTGGCG
--- a/tool_conf.xml.sample Tue Feb 01 11:19:40 2011 -0500
+++ b/tool_conf.xml.sample Tue Feb 01 11:20:02 2011 -0500
@@ -197,6 +197,9 @@
<tool file="evolution/codingSnps.xml" /><tool file="evolution/add_scores.xml" /></section>
+ <section name="Motif Tools" id="motifs">
+ <tool file="meme/meme.xml"/>
+ </section><section name="Metagenomic analyses" id="tax_manipulation"><tool file="taxonomy/gi2taxonomy.xml" /><tool file="taxonomy/t2t_report.xml" />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/meme/meme.xml Tue Feb 01 11:20:02 2011 -0500
@@ -0,0 +1,347 @@
+<tool id="meme_meme" name="MEME" version="1.0.0">
+ <requirements><requirement type='package'>meme</requirement></requirements>
+ <description>- Multiple Em for Motif Elicitation</description>
+ <command>meme "$input1" -o "${html_outfile.files_path}"
+ -nostatus
+
+ ##-p 8 ##number of processors
+
+ #if str( $options_type.options_type_selector ) == 'advanced':
+ -sf "${ str( $options_type.sf ).replace( ' ', '_' ) }"
+ -${options_type.alphabet_type.alphabet_type_selector}
+ -mod "${options_type.mod_type.mod_type_selector}"
+ -nmotifs "${options_type.nmotifs}"
+ -wnsites "${options_type.wnsites}"
+
+ #if $options_type.evt < float('inf'):
+ -evt "${options_type.evt}"
+ #end if
+
+ #if str( $options_type.mod_type.mod_type_selector ) != 'oops':
+ #if str( $options_type.mod_type.motif_occurrence_type.motif_occurrence_type_selector ) == 'nsites':
+ -nsites "${options_type.mod_type.motif_occurrence_type.nsites}"
+ #elif str( $options_type.mod_type.motif_occurrence_type.motif_occurrence_type_selector ) == 'min_max_sites':
+ -minsites "${options_type.mod_type.motif_occurrence_type.minsites}" -maxsites "${options_type.mod_type.motif_occurrence_type.maxsites}"
+ #end if
+ #end if
+
+ #if str( $options_type.motif_width_type.motif_width_type_selector ) == 'exact':
+ -w "${options_type.motif_width_type.width}"
+ #else
+ -minw "${options_type.motif_width_type.minw}" -maxw "${options_type.motif_width_type.maxw}"
+ #end if
+
+ #if str( $options_type.motif_trim_type.motif_trim_type_selector ) == 'nomatrim':
+ -nomatrim
+ #else
+ -wg "${options_type.motif_trim_type.wg}" -ws "${options_type.motif_trim_type.ws}" ${options_type.motif_trim_type.noendgaps}
+ #end if
+
+ #if str( $options_type.bfile ) != 'None':
+ -bfile "${options_type.bfile}"
+ #end if
+
+ #if str( $options_type.pspfile ) != 'None':
+ -psp "${options_type.pspfile}"
+ #end if
+
+ #if str( $options_type.alphabet_type.alphabet_type_selector ) == "dna":
+ ${options_type.alphabet_type.revcomp} ${options_type.alphabet_type.pal}
+ #end if
+
+ -maxiter "${options_type.maxiter}" -distance "${options_type.distance}"
+
+ -prior "${options_type.alphabet_type.prior_type.prior_type_selector}"
+ #if str( $options_type.alphabet_type.prior_type.prior_type_selector ) != 'addone':
+ -b "${options_type.alphabet_type.prior_type.prior_b}"
+ #if str( $options_type.alphabet_type.prior_type.plib ) != 'None':
+ -plib "${options_type.alphabet_type.prior_type.plib}"
+ #end if
+ #end if
+
+ #if str( $options_type.alphabet_type.spmap_type.spmap_type_selector ) == 'cons':
+ -cons "${options_type.alphabet_type.spmap_type.cons}"
+ #else
+ -spmap "${options_type.alphabet_type.spmap_type.spmap_type_selector}"
+ -spfuzz "${options_type.alphabet_type.spmap_type.spfuzz}"
+ #end if
+
+ #if str( $options_type.branching_type.branching_type_selector ) == 'x_branch':
+ -x_branch -bfactor "${options_type.branching_type.bfactor}" -heapsize "${options_type.branching_type.heapsize}"
+ #end if
+
+ ##-maxsize "1000000" ##remove hardcoded maxsize? should increase number of processors instead
+
+ #end if
+
+ 2>&1 || echo "Error running MEME."
+
+
+ && mv ${html_outfile.files_path}/meme.html ${html_outfile}
+
+ && mv ${html_outfile.files_path}/meme.txt ${txt_outfile}
+
+ && mv ${html_outfile.files_path}/meme.xml ${xml_outfile}
+
+ </command>
+ <inputs>
+ <param format="fasta" name="input1" type="data" label="Sequences"/>
+
+ <conditional name="options_type">
+ <param name="options_type_selector" type="select" label="Options Configuration">
+ <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="sf" type="text" value="Galaxy FASTA Input" label="Name of sequence set" />
+
+ <conditional name="alphabet_type">
+ <param name="alphabet_type_selector" type="select" label="Sequence Alphabet">
+ <option value="protein">Protein</option>
+ <option value="dna" selected="true">DNA</option>
+ </param>
+ <when value="protein">
+ <conditional name="prior_type">
+ <param name="prior_type_selector" type="select" label="Choice of prior">
+ <option value="dirichlet">simple Dirichlet prior</option>
+ <option value="dmix" selected="true">mixture of Dirichlets prior</option>
+ <option value="mega">extremely low variance dmix</option>
+ <option value="megap">mega for all but last iteration of EM; dmix on last iteration</option>
+ <option value="addone">add +1 to each observed count</option>
+ </param>
+ <when value="dirichlet">
+ <param name="prior_b" type="float" value="0.01" label="strength of prior on model parameters" />
+ <param name="plib" type="data" format="txt" optional="True" label="Dirichlet prior file" />
+ </when>
+ <when value="dmix">
+ <param name="prior_b" type="float" value="0" label="strength of prior on model parameters" />
+ <param name="plib" type="data" format="txt" optional="True" label="Dirichlet prior file" />
+ </when>
+ <when value="mega">
+ <param name="prior_b" type="float" value="0" label="strength of prior on model parameters" />
+ <param name="plib" type="data" format="txt" optional="True" label="Dirichlet prior file" />
+ </when>
+ <when value="megap">
+ <param name="prior_b" type="float" value="0" label="strength of prior on model parameters" />
+ <param name="plib" type="data" format="txt" optional="True" label="Dirichlet prior file" />
+ </when>
+ <when value="addone">
+ <!-- no values here? -->
+ </when>
+ </conditional>
+ <conditional name="spmap_type">
+ <param name="spmap_type_selector" type="select" label="EM starting points">
+ <option value="uni">uni</option>
+ <option value="pam" selected="true">pam</option>
+ <option value="cons">Use starting point from string</option>
+ </param>
+ <when value="uni">
+ <param name="spfuzz" type="float" value="0.5" label="Fuzziness of the mapping" />
+ </when>
+ <when value="pam">
+ <param name="spfuzz" type="integer" value="120" label="Fuzziness of the mapping" />
+ </when>
+ <when value="cons">
+ <param name="cons" type="text" value="" label="Starting point from string" />
+ </when>
+ </conditional>
+ </when>
+ <when value="dna">
+ <param name="revcomp" label="Check reverse complement" type="boolean" truevalue="-revcomp" falsevalue="" checked="False"/>
+ <param name="pal" label="Check for palindromes" type="boolean" truevalue="-pal" falsevalue="" checked="False"/>
+ <conditional name="prior_type">
+ <param name="prior_type_selector" type="select" label="Sequence Alphabet">
+ <option value="dirichlet" selected="true">simple Dirichlet prior</option>
+ <option value="dmix">mixture of Dirichlets prior</option>
+ <option value="mega">extremely low variance dmix</option>
+ <option value="megap">mega for all but last iteration of EM; dmix on last iteration</option>
+ <option value="addone">add +1 to each observed count</option>
+ </param>
+ <when value="dirichlet">
+ <param name="prior_b" type="float" value="0.01" label="strength of prior on model parameters" />
+ <param name="plib" type="data" format="txt" optional="True" label="Dirichlet prior file" />
+ </when>
+ <when value="dmix">
+ <param name="prior_b" type="float" value="0" label="strength of prior on model parameters" />
+ <param name="plib" type="data" format="txt" optional="True" label="Dirichlet prior file" />
+ </when>
+ <when value="mega">
+ <param name="prior_b" type="float" value="0" label="strength of prior on model parameters" />
+ <param name="plib" type="data" format="txt" optional="True" label="Dirichlet prior file" />
+ </when>
+ <when value="megap">
+ <param name="prior_b" type="float" value="0" label="strength of prior on model parameters" />
+ <param name="plib" type="data" format="txt" optional="True" label="Dirichlet prior file" />
+ </when>
+ <when value="addone">
+ <!-- no values here? -->
+ </when>
+ </conditional>
+ <conditional name="spmap_type">
+ <param name="spmap_type_selector" type="select" label="EM starting points">
+ <option value="uni" selected="true">uni</option>
+ <option value="pam">pam</option>
+ <option value="cons">Use starting point from string</option>
+ </param>
+ <when value="uni">
+ <param name="spfuzz" type="float" value="0.5" label="Fuzziness of the mapping" />
+ </when>
+ <when value="pam">
+ <param name="spfuzz" type="integer" value="120" label="Fuzziness of the mapping" />
+ </when>
+ <when value="cons">
+ <param name="cons" type="text" value="" label="Starting point from string" />
+ </when>
+ </conditional>
+ </when>
+ </conditional>
+
+ <param name="nmotifs" type="integer" value="1" label="Number of different motifs to search" />
+ <param name="evt" type="float" value="inf" label="E-value to stop looking for motifs" />
+ <conditional name="mod_type">
+ <param name="mod_type_selector" type="select" label="Expected motif distribution">
+ <option value="oops">One Occurrence Per Sequence</option>
+ <option value="zoops" selected="true">Zero or One Occurrence Per Sequence</option>
+ <option value="anr">Any Number of Repetitions</option>
+ </param>
+ <when value="oops">
+ <!-- no values here -->
+ </when>
+ <when value="zoops">
+ <conditional name="motif_occurrence_type">
+ <param name="motif_occurrence_type_selector" type="select" label="Number of motif occurrences">
+ <option value="default" selected="true">Use defaults</option>
+ <option value="nsites">nsites</option>
+ <option value="min_max_sites">min and max sites</option>
+ </param>
+ <when value="default">
+ <!-- no values here -->
+ </when>
+ <when value="nsites">
+ <param name="nsites" type="integer" value="1" label="Search nsites number of occurrences" />
+ </when>
+ <when value="min_max_sites">
+ <param name="minsites" type="integer" value="1" label="minsites" />
+ <param name="maxsites" type="integer" value="50" label="maxsites" />
+ </when>
+ </conditional>
+ </when>
+ <when value="anr">
+ <conditional name="motif_occurrence_type">
+ <param name="motif_occurrence_type_selector" type="select" label="Number of motif occurrences">
+ <option value="default" selected="true">Use defaults</option>
+ <option value="nsites">nsites</option>
+ <option value="min_max_sites">min and max sites</option>
+ </param>
+ <when value="default">
+ <!-- no values here -->
+ </when>
+ <when value="nsites">
+ <param name="nsites" type="integer" value="1" label="Search nsites number of occurrences" />
+ </when>
+ <when value="min_max_sites">
+ <param name="minsites" type="integer" value="1" label="minsites" />
+ <param name="maxsites" type="integer" value="50" label="maxsites" />
+ </when>
+ </conditional>
+ </when>
+ </conditional>
+ <param name="wnsites" type="float" value="0.8" label="Weight on the prior on nsites" />
+
+ <conditional name="motif_width_type">
+ <param name="motif_width_type_selector" type="select" label="Motif width type">
+ <option value="exact">Exact width</option>
+ <option value="range" selected="true">Specify a range</option>
+ </param>
+ <when value="exact">
+ <param name="width" type="integer" value="10" label="Width of motif to search" />
+ </when>
+ <when value="range">
+ <param name="minw" type="integer" value="8" label="Min width of motif to search" />
+ <param name="maxw" type="integer" value="50" label="Max width of motif to search" />
+ </when>
+ </conditional>
+
+ <conditional name="motif_trim_type">
+ <param name="motif_trim_type_selector" type="select" label="Motif trim type">
+ <option value="nomatrim">No motif trim</option>
+ <option value="trim" selected="true">Trim motif</option>
+ </param>
+ <when value="nomatrim">
+ <!-- no values here -->
+ </when>
+ <when value="trim">
+ <param name="wg" type="integer" value="11" label="Gap cost" />
+ <param name="ws" type="integer" value="1" label="Space cost" />
+ <param name="noendgaps" label="Do not penalize endgaps" type="boolean" truevalue="-noendgaps" falsevalue="" checked="False"/>
+ </when>
+ </conditional>
+
+ <param name="bfile" type="data" format="txt" optional="True" label="Background Model" />
+ <param name="pspfile" type="data" format="txt" optional="True" label="Position-Specific Prior" />
+
+ <param name="maxiter" type="integer" value="50" label="Number of iterations of EM to run" />
+ <param name="distance" type="float" value="0.001" label="Convergence criterion" />
+
+ <conditional name="branching_type">
+ <param name="branching_type_selector" type="select" label="x-branching type">
+ <option value="x_branch">Perform x-branching</option>
+ <option value="no_x_branch" selected="true">No x-branching</option>
+ </param>
+ <when value="no_x_branch">
+ <!-- no values here -->
+ </when>
+ <when value="x_branch">
+ <param name="bfactor" type="integer" value="3" label="Number of iterations of branching" />
+ <param name="heapsize" type="integer" value="64" label="Maximum number of heaps to use" />
+ </when>
+ </conditional>
+
+ </when>
+ </conditional>
+
+ <param name="non_commercial_use" label="I certify that I am not using this tool for commercial purposes." type="boolean" truevalue="NON_COMMERCIAL_USE" falsevalue="COMMERCIAL_USE" checked="False">
+ <validator type="expression" message="This tool is only available for non-commercial use.">value == True</validator>
+ </param>
+
+ </inputs>
+ <outputs>
+ <data format="html" name="html_outfile" label="${tool.name} on ${on_string} (html)"/>
+ <data format="txt" name="txt_outfile" label="${tool.name} on ${on_string} (text)"/>
+ <data format="memexml" name="xml_outfile" label="${tool.name} on ${on_string} (xml)"/>
+ </outputs>
+ <tests>
+ <test>
+ <param name="input1" value="meme_input_1.fasta" ftype="fasta" dbkey="hg19"/>
+ <param name="options_type_selector" value="basic"/>
+ <param name="non_commercial_use" value="True"/>
+ <output name="html_outfile" file="meme/meme/meme_output_html_1.html" lines_diff="14"/>
+ <output name="txt_outfile" file="meme/meme/meme_output_txt_1.txt" lines_diff="12"/>
+ <output name="xml_outfile" file="meme/meme/meme_output_xml_1.xml" lines_diff="8"/>
+ </test>
+ </tests>
+ <help>
+
+.. class:: warningmark
+
+**WARNING: This tool is only available for non-commercial use. Use for educational, research and non-profit purposes is permitted. Before using, be sure to review, agree, and comply with the license.**
+
+If you want to specify sequence weights, you must include them at the top of your input FASTA file.
+
+.. class:: infomark
+
+**To cite MEME:**
+Timothy L. Bailey and Charles Elkan, "Fitting a mixture model by expectation maximization to discover motifs in biopolymers", Proceedings of the Second International Conference on Intelligent Systems for Molecular Biology, pp. 28-36, AAAI Press, Menlo Park, California, 1994.
+
+
+For detailed information on MEME, click here_. To view the license_.
+
+.. _here: http://meme.nbcr.net/meme/meme-intro.html
+.. _license: http://meme.nbcr.net/meme/COPYRIGHT.html
+
+ </help>
+</tool>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/8c81782aa093/
changeset: r4966:8c81782aa093
user: dan
date: 2011-02-01 17:17:44
summary: Add MEME tool configuration file.
affected #: 8 files (722 bytes)
Diff too large to display.
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: Add GTF sniffer to datatypes config sample file.
by Bitbucket 31 Jan '11
by Bitbucket 31 Jan '11
31 Jan '11
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/bf060b28bb8b/
changeset: r4965:bf060b28bb8b
user: jgoecks
date: 2011-02-01 00:25:33
summary: Add GTF sniffer to datatypes config sample file.
affected #: 1 file (56 bytes)
--- a/datatypes_conf.xml.sample Mon Jan 31 16:41:03 2011 -0500
+++ b/datatypes_conf.xml.sample Mon Jan 31 18:25:33 2011 -0500
@@ -289,6 +289,7 @@
<sniffer type="galaxy.datatypes.sequence:Axt"/><sniffer type="galaxy.datatypes.interval:Bed"/><sniffer type="galaxy.datatypes.interval:CustomTrack"/>
+ <sniffer type="galaxy.datatypes.interval:Gtf"/><sniffer type="galaxy.datatypes.interval:Gff"/><sniffer type="galaxy.datatypes.interval:Gff3"/><sniffer type="galaxy.datatypes.tabular:Pileup"/>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/82107691d26e/
changeset: r4964:82107691d26e
user: greg
date: 2011-01-31 22:41:03
summary: Several data library improvements:
1. Enhance importing library dataset into the current history by now allowing the user to select from a list of existing histories or create a new named history ( similar to copying datasets ).  This feature is available for a specific library dataset, a folder ( or root folder ), when selecting multiple datasets from in a library,  and on the results page for searched library datasets.
2. Add Brad Chapman's latest patch for fixing the lucene search implementation
3. Eliminate searches on dataset state for both whoosh and lucene searches
4. Clarify the objects being searched in the regular search and advanced search boxes in the data libraries grids.
5. Add the ability to perform certain actions on 1 or more selected library datasets on the results page for searched library datasets.
6. Add a "select all" checkbox to the browse_library.mako template.
7. Fixed library functional tests accordingly.
affected #: 14 files (14.7 KB)
--- a/lib/galaxy/web/controllers/library.py Mon Jan 31 12:57:42 2011 -0500
+++ b/lib/galaxy/web/controllers/library.py Mon Jan 31 16:41:03 2011 -0500
@@ -6,7 +6,7 @@
from galaxy.datatypes import sniff
from galaxy import model, util
from galaxy.util.odict import odict
-from library_common import lucene_search, whoosh_search
+from library_common import get_comptypes, lucene_search, whoosh_search
log = logging.getLogger( __name__ )
@@ -25,17 +25,17 @@
template='/library/grid.mako'
default_sort_key = "name"
columns = [
- NameColumn( "Name",
+ NameColumn( "Data library name",
key="name",
link=( lambda library: dict( operation="browse", id=library.id ) ),
attach_popup=False,
filterable="advanced" ),
- DescriptionColumn( "Description",
+ DescriptionColumn( "Data library description",
key="description",
attach_popup=False,
filterable="advanced" ),
]
- columns.append( grids.MulticolFilterColumn( "Search",
+ columns.append( grids.MulticolFilterColumn( "search library dataset name, info, message, dbkey",
cols_to_filter=[ columns[0], columns[1] ],
key="free-text-search",
visible=False,
@@ -74,8 +74,9 @@
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
+ default_action = params.get( 'default_action', None )
return trans.fill_template( "/library/index.mako",
- default_action=params.get( 'default_action', None ),
+ default_action=default_action,
message=message,
status=status )
@web.expose
@@ -91,8 +92,9 @@
search_term = kwd[ "f-free-text-search" ]
if trans.app.config.enable_lucene_library_search:
indexed_search_enabled = True
- search_url = trans.app.config.config_dict.get( "fulltext_find_url", "" )
+ search_url = trans.app.config.config_dict.get( "fulltext_url", "" )
if search_url:
+ indexed_search_enabled = True
status, message, lddas = lucene_search( trans, 'library', search_term, search_url, **kwd )
elif trans.app.config.enable_whoosh_library_search:
indexed_search_enabled = True
@@ -100,11 +102,15 @@
else:
indexed_search_enabled = False
if indexed_search_enabled:
+ comptypes = get_comptypes( trans )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
return trans.fill_template( '/library/common/library_dataset_search_results.mako',
cntrller='library',
search_term=search_term,
+ comptypes=comptypes,
lddas=lddas,
+ show_deleted=show_deleted,
use_panels=use_panels,
message=message,
status=status )
--- a/lib/galaxy/web/controllers/library_admin.py Mon Jan 31 12:57:42 2011 -0500
+++ b/lib/galaxy/web/controllers/library_admin.py Mon Jan 31 16:41:03 2011 -0500
@@ -3,7 +3,7 @@
from galaxy.web.base.controller import *
from galaxy.web.framework.helpers import time_ago, iff, grids
from galaxy.model.orm import *
-from library_common import lucene_search, whoosh_search
+from library_common import get_comptypes, lucene_search, whoosh_search
# Older py compatibility
try:
set()
@@ -35,12 +35,12 @@
template='/admin/library/grid.mako'
default_sort_key = "name"
columns = [
- NameColumn( "Name",
+ NameColumn( "Data library name",
key="name",
link=( lambda library: dict( operation="browse", id=library.id ) ),
attach_popup=False,
filterable="advanced" ),
- DescriptionColumn( "Description",
+ DescriptionColumn( "Data library description",
key="description",
attach_popup=False,
filterable="advanced" ),
@@ -50,7 +50,7 @@
# Columns that are valid for filtering but are not visible.
grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
]
- columns.append( grids.MulticolFilterColumn( "Search",
+ columns.append( grids.MulticolFilterColumn( "search library dataset name, info, message, dbkey",
cols_to_filter=[ columns[0], columns[1] ],
key="free-text-search",
visible=False,
@@ -133,11 +133,15 @@
else:
indexed_search_enabled = False
if indexed_search_enabled:
+ comptypes = get_comptypes( trans )
+ show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
return trans.fill_template( '/library/common/library_dataset_search_results.mako',
cntrller='library_admin',
search_term=search_term,
+ comptypes=comptypes,
lddas=lddas,
+ show_deleted=show_deleted,
use_panels=use_panels,
message=message,
status=status )
--- a/lib/galaxy/web/controllers/library_common.py Mon Jan 31 12:57:42 2011 -0500
+++ b/lib/galaxy/web/controllers/library_common.py Mon Jan 31 16:41:03 2011 -0500
@@ -1,4 +1,4 @@
-import os, os.path, shutil, urllib, StringIO, re, gzip, tempfile, shutil, zipfile, copy, glob, string
+import os, os.path, shutil, urllib, StringIO, re, gzip, tempfile, shutil, zipfile, copy, glob, string, urllib2
from galaxy.web.base.controller import *
from galaxy import util, jobs
from galaxy.datatypes import sniff
@@ -7,6 +7,7 @@
from galaxy.tools.actions import upload_common
from galaxy.model.orm import *
from galaxy.util.streamball import StreamBall
+from galaxy.util import inflector
from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, TextArea, TextField, WorkflowField, WorkflowMappingField, HistoryField
import logging, tempfile, zipfile, tarfile, os, sys, operator
from galaxy.eggs import require
@@ -20,7 +21,7 @@
whoosh_search_enabled = True
# The following must be defined exactly like the
# schema in ~/scripts/data_libraries/build_whoosh_index.py
- schema = Schema( id=STORED, name=TEXT, info=TEXT, dbkey=TEXT, message=TEXT, state=TEXT )
+ schema = Schema( id=STORED, name=TEXT, info=TEXT, dbkey=TEXT, message=TEXT )
except ImportError, e:
whoosh_search_enabled = False
schema = None
@@ -125,16 +126,7 @@
message += "Don't navigate away from Galaxy or use the browser's \"stop\" or \"reload\" buttons (on this tab) until the "
message += "message \"This job is running\" is cleared from the \"Information\" column below for each selected dataset."
status = "info"
- comptypes_t = comptypes
- if trans.app.config.nginx_x_archive_files_base:
- comptypes_t = ['ngxzip']
- for comptype in trans.app.config.disable_library_comptypes:
- # TODO: do this once, not every time (we're gonna raise an
- # exception every time after the first time)
- try:
- comptypes_t.remove( comptype )
- except:
- pass
+ comptypes = get_comptypes( trans )
try:
return trans.fill_template( '/library/common/browse_library.mako',
cntrller=cntrller,
@@ -143,17 +135,18 @@
created_ldda_ids=created_ldda_ids,
hidden_folder_ids=hidden_folder_ids,
show_deleted=show_deleted,
- comptypes=comptypes_t,
+ comptypes=comptypes,
current_user_roles=current_user_roles,
message=message,
status=status )
except Exception, e:
message = 'Error attempting to display contents of library (%s): %s.' % ( str( library.name ), str( e ) )
status = 'error'
+ default_action = params.get( 'default_action', None )
return trans.response.send_redirect( web.url_for( use_panels=use_panels,
controller=cntrller,
action='browse_libraries',
- default_action=params.get( 'default_action', None ),
+ default_action=default_action,
message=util.sanitize_text( message ),
status=status ) )
@web.expose
@@ -871,7 +864,7 @@
message += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
default_action = 'manage_permissions'
else:
- default_action = 'add'
+ default_action = 'import_to_histories'
trans.response.send_redirect( web.url_for( controller='library_common',
action='browse_library',
cntrller=cntrller,
@@ -1247,7 +1240,7 @@
message += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
default_action = 'manage_permissions'
else:
- default_action = 'add'
+ default_action = 'import_to_histories'
return trans.response.send_redirect( web.url_for( controller='library_common',
action='browse_library',
cntrller=cntrller,
@@ -1512,7 +1505,12 @@
message=util.sanitize_text( message ),
status=status ) )
@web.expose
- def act_on_multiple_datasets( self, trans, cntrller, library_id, ldda_ids='', **kwd ):
+ def act_on_multiple_datasets( self, trans, cntrller, library_id=None, ldda_ids='', **kwd ):
+ # This method is called from 1 of 3 places:
+ # - this controller's download_dataset_from_folder() method
+ # - he browse_library.mako template
+ # - the library_dataset_search_results.mako template
+ # In the last case above, we will not have a library_id
class NgxZip( object ):
def __init__( self, url_base ):
self.files = {}
@@ -1534,6 +1532,16 @@
show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
action = params.get( 'do_action', None )
+ if action == 'import_to_histories':
+ return trans.response.send_redirect( web.url_for( controller='library_common',
+ action='import_datasets_to_histories',
+ cntrller=cntrller,
+ library_id=library_id,
+ ldda_ids=ldda_ids,
+ use_panels=use_panels,
+ show_deleted=show_deleted,
+ message=message,
+ status=status ) )
lddas = []
error = False
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
@@ -1557,27 +1565,177 @@
message = "Invalid library dataset id ( %s ) specified." % str( ldda_id )
break
lddas.append( ldda )
- if action == 'import_to_history' or action == 'add':
- if trans.get_history() is None:
- # Must be a bot sending a request without having a history.
- error = True
- message = "You do not have a current history"
- elif action == 'manage_permissions':
- if not is_admin:
+ if not is_admin:
+ if action == 'manage_permissions':
for ldda in lddas:
if not ( trans.app.security_agent.can_manage_library_item( current_user_roles, ldda ) and \
trans.app.security_agent.can_manage_dataset( current_user_roles, ldda.dataset ) ):
error = True
message = "You are not authorized to manage permissions on library dataset '%s'." % ldda.name
break
- elif action == 'delete':
- if not is_admin:
+ elif action == 'delete':
for ldda in lddas:
if not trans.app.security_agent.can_modify_library_item( current_user_roles, ldda ):
error = True
message = "You are not authorized to modify library dataset '%s'." % ldda.name
break
- if error:
+ if not error:
+ if action == 'manage_permissions':
+ trans.response.send_redirect( web.url_for( controller='library_common',
+ action='ldda_permissions',
+ cntrller=cntrller,
+ use_panels=use_panels,
+ library_id=library_id,
+ folder_id=trans.security.encode_id( lddas[0].library_dataset.folder.id ),
+ id=",".join( ldda_ids ),
+ show_deleted=show_deleted,
+ message=util.sanitize_text( message ),
+ status=status ) )
+ elif action == 'delete':
+ for ldda in lddas:
+ # Do not delete the association, just delete the library_dataset. The
+ # cleanup_datasets.py script handles everything else.
+ ld = ldda.library_dataset
+ ld.deleted = True
+ trans.sa_session.add( ld )
+ trans.sa_session.flush()
+ message = "The selected datasets have been deleted."
+ elif action in ['zip','tgz','tbz','ngxzip']:
+ error = False
+ killme = string.punctuation + string.whitespace
+ trantab = string.maketrans(killme,'_'*len(killme))
+ try:
+ outext = 'zip'
+ if action == 'zip':
+ # Can't use mkstemp - the file must not exist first
+ tmpd = tempfile.mkdtemp()
+ tmpf = os.path.join( tmpd, 'library_download.' + action )
+ if ziptype == '64' and trans.app.config.upstream_gzip:
+ archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_STORED, True )
+ elif ziptype == '64':
+ archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED, True )
+ elif trans.app.config.upstream_gzip:
+ archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_STORED )
+ else:
+ archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED )
+ archive.add = lambda x, y: archive.write( x, y.encode('CP437') )
+ elif action == 'tgz':
+ if trans.app.config.upstream_gzip:
+ archive = util.streamball.StreamBall( 'w|' )
+ outext = 'tar'
+ else:
+ archive = util.streamball.StreamBall( 'w|gz' )
+ outext = 'tgz'
+ elif action == 'tbz':
+ archive = util.streamball.StreamBall( 'w|bz2' )
+ outext = 'tbz2'
+ elif action == 'ngxzip':
+ archive = NgxZip( trans.app.config.nginx_x_archive_files_base )
+ except ( OSError, zipfile.BadZipfile ):
+ error = True
+ log.exception( "Unable to create archive for download" )
+ message = "Unable to create archive for download, please report this error"
+ status = 'error'
+ except:
+ error = True
+ log.exception( "Unexpected error %s in create archive for download" % sys.exc_info()[0] )
+ message = "Unable to create archive for download, please report - %s" % sys.exc_info()[0]
+ status = 'error'
+ if not error:
+ composite_extensions = trans.app.datatypes_registry.get_composite_extensions()
+ seen = []
+ for ldda in lddas:
+ if ldda.dataset.state in [ 'new', 'upload', 'queued', 'running', 'empty', 'discarded' ]:
+ continue
+ ext = ldda.extension
+ is_composite = ext in composite_extensions
+ path = ""
+ parent_folder = ldda.library_dataset.folder
+ while parent_folder is not None:
+ # Exclude the now-hidden "root folder"
+ if parent_folder.parent is None:
+ path = os.path.join( parent_folder.library_root[0].name, path )
+ break
+ path = os.path.join( parent_folder.name, path )
+ parent_folder = parent_folder.parent
+ path += ldda.name
+ while path in seen:
+ path += '_'
+ seen.append( path )
+ zpath = os.path.split(path)[-1] # comes as base_name/fname
+ outfname,zpathext = os.path.splitext(zpath)
+ if is_composite:
+ # need to add all the components from the extra_files_path to the zip
+ if zpathext == '':
+ zpath = '%s.html' % zpath # fake the real nature of the html file
+ try:
+ archive.add(ldda.dataset.file_name,zpath) # add the primary of a composite set
+ except IOError:
+ error = True
+ log.exception( "Unable to add composite parent %s to temporary library download archive" % ldda.dataset.file_name)
+ message = "Unable to create archive for download, please report this error"
+ status = 'error'
+ continue
+ flist = glob.glob(os.path.join(ldda.dataset.extra_files_path,'*.*')) # glob returns full paths
+ for fpath in flist:
+ efp,fname = os.path.split(fpath)
+ if fname > '':
+ fname = fname.translate(trantab)
+ try:
+ archive.add( fpath,fname )
+ except IOError:
+ error = True
+ log.exception( "Unable to add %s to temporary library download archive %s" % (fname,outfname))
+ message = "Unable to create archive for download, please report this error"
+ status = 'error'
+ continue
+ else: # simple case
+ try:
+ archive.add( ldda.dataset.file_name, path )
+ except IOError:
+ error = True
+ log.exception( "Unable to write %s to temporary library download archive" % ldda.dataset.file_name)
+ message = "Unable to create archive for download, please report this error"
+ status = 'error'
+ if not error:
+ if library_id:
+ lname = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) ).name
+ else:
+ # Request must have coe from the library_dataset_search_results page.
+ lname = 'selected_dataset'
+ fname = lname.replace( ' ', '_' ) + '_files'
+ if action == 'zip':
+ archive.close()
+ tmpfh = open( tmpf )
+ # clean up now
+ try:
+ os.unlink( tmpf )
+ os.rmdir( tmpd )
+ except OSError:
+ error = True
+ log.exception( "Unable to remove temporary library download archive and directory" )
+ message = "Unable to create archive for download, please report this error"
+ status = 'error'
+ if not error:
+ trans.response.set_content_type( "application/x-zip-compressed" )
+ trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
+ return tmpfh
+ elif action == 'ngxzip':
+ trans.response.set_content_type( "application/zip" )
+ trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
+ trans.response.headers[ "X-Archive-Files" ] = "zip"
+ return archive
+ else:
+ trans.response.set_content_type( "application/x-tar" )
+ trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
+ archive.wsgi_status = trans.response.wsgi_status()
+ archive.wsgi_headeritems = trans.response.wsgi_headeritems()
+ return archive.stream
+ else:
+ status = 'error'
+ message = 'Invalid action ( %s ) specified.' % action
+ if library_id:
+ # If we have a library_id, browse the associated library
return trans.response.send_redirect( web.url_for( controller='library_common',
action='browse_library',
cntrller=cntrller,
@@ -1585,181 +1743,129 @@
id=library_id,
show_deleted=show_deleted,
message=util.sanitize_text( message ),
- status='error' ) )
- if action == 'import_to_history' or action == 'add':
- history = trans.get_history()
- total_imported_lddas = 0
- message = ''
- status = 'done'
- for ldda in lddas:
- if ldda.dataset.state in [ 'new', 'upload', 'queued', 'running', 'empty', 'discarded' ]:
- message += "Cannot import dataset '%s' since its state is '%s'. " % ( ldda.name, ldda.dataset.state )
+ status=status ) )
+ else:
+ # We must have arrived here from the library_dataset_search_results page, so reddirect there.
+ search_term = params.get( 'search_term', '' )
+ comptypes = get_comptypes( trans )
+ return trans.fill_template( '/library/common/library_dataset_search_results.mako',
+ cntrller=cntrller,
+ search_term=search_term,
+ comptypes=comptypes,
+ lddas=lddas,
+ show_deleted=show_deleted,
+ use_panels=use_panels,
+ message=message,
+ status=status )
+
+ @web.expose
+ def import_datasets_to_histories( self, trans, cntrller, library_id='', folder_id='', ldda_ids='', target_history_ids='', new_history_name='', **kwd ):
+ # This method is called from one of the following places:
+ # - a menu option for a library dataset ( ldda_ids will be a singel dataset id )
+ # - a menu option for a library folder ( folder_id will have a value )
+ # - a menu option for a library dataset search result set ( ldda_ids will be a comma separated string of dataset ids )
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
+ show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
+ use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
+ user = trans.get_user()
+ current_history = trans.get_history()
+ if library_id:
+ library = trans.sa_session.query( trans.model.Library ).get( trans.security.decode_id( library_id ) )
+ else:
+ library = None
+ if folder_id:
+ folder = trans.sa_session.query( trans.model.LibraryFolder ).get( trans.security.decode_id( folder_id ) )
+ else:
+ folder = None
+ ldda_ids = util.listify( ldda_ids )
+ if ldda_ids:
+ # Check boxes cause 2 copies of each id to be included in the request
+ ldda_ids = map( trans.security.decode_id, ldda_ids )
+ unique_ldda_ids = []
+ for ldda_id in ldda_ids:
+ if ldda_id not in unique_ldda_ids:
+ unique_ldda_ids.append( ldda_id )
+ ldda_ids = unique_ldda_ids
+ target_history_ids = util.listify( target_history_ids )
+ if target_history_ids:
+ target_history_ids = [ trans.security.decode_id( target_history_id ) for target_history_id in target_history_ids if target_history_id ]
+ if params.get( 'import_datasets_to_histories_button', False ):
+ invalid_datasets = 0
+ if not ldda_ids or not ( target_history_ids or new_history_name ):
+ message = "You must provide one or more source library datasets and one or more target histories."
+ status = 'error'
+ else:
+ if new_history_name:
+ new_history = trans.app.model.History()
+ new_history.name = new_history_name
+ new_history.user = user
+ trans.sa_session.add( new_history )
+ trans.sa_session.flush()
+ target_history_ids.append( new_history.id )
+ if user:
+ target_histories = [ hist for hist in map( trans.sa_session.query( trans.app.model.History ).get, target_history_ids ) if ( hist is not None and hist.user == user )]
+ else:
+ target_histories = [ current_history ]
+ if len( target_histories ) != len( target_history_ids ):
+ message += "You do not have permission to add datasets to %i requested histories. " % ( len( target_history_ids ) - len( target_histories ) )
status = 'error'
- elif ldda.dataset.state in [ 'ok', 'error' ]:
- hda = ldda.to_history_dataset_association( target_history=history, add_to_history=True )
- total_imported_lddas += 1
- if total_imported_lddas:
- trans.sa_session.add( history )
+ for ldda in map( trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get, ldda_ids ):
+ if ldda is None:
+ message += "You tried to import a library dataset that does not exist. "
+ status = 'error'
+ invalid_datasets += 1
+ elif ldda.dataset.state not in [ trans.model.Dataset.states.OK, trans.model.Dataset.states.ERROR ]:
+ message += "Cannot import dataset '%s' since its state is '%s'. " % ( ldda.name, ldda.dataset.state )
+ status = 'error'
+ invalid_datasets += 1
+ elif not ldda.has_data():
+ message += "Cannot import empty dataset '%s'. " % ldda.name
+ status = 'error'
+ invalid_datasets += 1
+ else:
+ for target_history in target_histories:
+ hda = ldda.to_history_dataset_association( target_history=target_history, add_to_history=True )
trans.sa_session.flush()
- message += "%i dataset(s) have been imported into your history. " % total_imported_lddas
- elif action == 'manage_permissions':
- trans.response.send_redirect( web.url_for( controller='library_common',
- action='ldda_permissions',
- cntrller=cntrller,
- use_panels=use_panels,
- library_id=library_id,
- folder_id=trans.security.encode_id( lddas[0].library_dataset.folder.id ),
- id=",".join( ldda_ids ),
- show_deleted=show_deleted,
- message=util.sanitize_text( message ),
- status=status ) )
- elif action == 'delete':
- for ldda in lddas:
- # Do not delete the association, just delete the library_dataset. The
- # cleanup_datasets.py script handles everything else.
- ld = ldda.library_dataset
- ld.deleted = True
- trans.sa_session.add( ld )
- trans.sa_session.flush()
- message = "The selected datasets have been removed from this data library"
- elif action in ['zip','tgz','tbz','ngxzip']:
- error = False
- killme = string.punctuation + string.whitespace
- trantab = string.maketrans(killme,'_'*len(killme))
- try:
- outext = 'zip'
- if action == 'zip':
- # Can't use mkstemp - the file must not exist first
- tmpd = tempfile.mkdtemp()
- tmpf = os.path.join( tmpd, 'library_download.' + action )
- if ziptype == '64' and trans.app.config.upstream_gzip:
- archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_STORED, True )
- elif ziptype == '64':
- archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED, True )
- elif trans.app.config.upstream_gzip:
- archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_STORED )
- else:
- archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED )
- archive.add = lambda x, y: archive.write( x, y.encode('CP437') )
- elif action == 'tgz':
- if trans.app.config.upstream_gzip:
- archive = util.streamball.StreamBall( 'w|' )
- outext = 'tar'
- else:
- archive = util.streamball.StreamBall( 'w|gz' )
- outext = 'tgz'
- elif action == 'tbz':
- archive = util.streamball.StreamBall( 'w|bz2' )
- outext = 'tbz2'
- elif action == 'ngxzip':
- archive = NgxZip( trans.app.config.nginx_x_archive_files_base )
- except (OSError, zipfile.BadZipfile):
- error = True
- log.exception( "Unable to create archive for download" )
- message = "Unable to create archive for download, please report this error"
- status = 'error'
- except:
- error = True
- log.exception( "Unexpected error %s in create archive for download" % sys.exc_info()[0])
- message = "Unable to create archive for download, please report - %s" % sys.exc_info()[0]
- status = 'error'
- if not error:
- composite_extensions = trans.app.datatypes_registry.get_composite_extensions( )
- seen = []
- for ldda in lddas:
- if ldda.dataset.state in [ 'new', 'upload', 'queued', 'running', 'empty', 'discarded' ]:
- continue
- ext = ldda.extension
- is_composite = ext in composite_extensions
- path = ""
- parent_folder = ldda.library_dataset.folder
- while parent_folder is not None:
- # Exclude the now-hidden "root folder"
- if parent_folder.parent is None:
- path = os.path.join( parent_folder.library_root[0].name, path )
- break
- path = os.path.join( parent_folder.name, path )
- parent_folder = parent_folder.parent
- path += ldda.name
- while path in seen:
- path += '_'
- seen.append( path )
- zpath = os.path.split(path)[-1] # comes as base_name/fname
- outfname,zpathext = os.path.splitext(zpath)
- if is_composite:
- # need to add all the components from the extra_files_path to the zip
- if zpathext == '':
- zpath = '%s.html' % zpath # fake the real nature of the html file
- try:
- archive.add(ldda.dataset.file_name,zpath) # add the primary of a composite set
- except IOError:
- error = True
- log.exception( "Unable to add composite parent %s to temporary library download archive" % ldda.dataset.file_name)
- message = "Unable to create archive for download, please report this error"
- status = 'error'
- continue
- flist = glob.glob(os.path.join(ldda.dataset.extra_files_path,'*.*')) # glob returns full paths
- for fpath in flist:
- efp,fname = os.path.split(fpath)
- if fname > '':
- fname = fname.translate(trantab)
- try:
- archive.add( fpath,fname )
- except IOError:
- error = True
- log.exception( "Unable to add %s to temporary library download archive %s" % (fname,outfname))
- message = "Unable to create archive for download, please report this error"
- status = 'error'
- continue
- else: # simple case
- try:
- archive.add( ldda.dataset.file_name, path )
- except IOError:
- error = True
- log.exception( "Unable to write %s to temporary library download archive" % ldda.dataset.file_name)
- message = "Unable to create archive for download, please report this error"
- status = 'error'
- if not error:
- lname = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) ).name
- fname = lname.replace( ' ', '_' ) + '_files'
- if action == 'zip':
- archive.close()
- tmpfh = open( tmpf )
- # clean up now
- try:
- os.unlink( tmpf )
- os.rmdir( tmpd )
- except OSError:
- error = True
- log.exception( "Unable to remove temporary library download archive and directory" )
- message = "Unable to create archive for download, please report this error"
- status = 'error'
- if not error:
- trans.response.set_content_type( "application/x-zip-compressed" )
- trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
- return tmpfh
- elif action == 'ngxzip':
- trans.response.set_content_type( "application/zip" )
- trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
- trans.response.headers[ "X-Archive-Files" ] = "zip"
- return archive
- else:
- trans.response.set_content_type( "application/x-tar" )
- trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
- archive.wsgi_status = trans.response.wsgi_status()
- archive.wsgi_headeritems = trans.response.wsgi_headeritems()
- return archive.stream
- else:
- status = 'error'
- message = 'Invalid action ( %s ) specified.' % action
- return trans.response.send_redirect( web.url_for( controller='library_common',
- action='browse_library',
- cntrller=cntrller,
- use_panels=use_panels,
- id=library_id,
- show_deleted=show_deleted,
- message=util.sanitize_text( message ),
- status=status ) )
+ hist_names_str = ", ".join( [ target_history.name for target_history in target_histories ] )
+ num_source = len( ldda_ids ) - invalid_datasets
+ num_target = len( target_histories )
+ message = "%i %s have been imported into %i %s: %s" % ( num_source,
+ inflector.cond_plural( num_source, "dataset" ),
+ num_target,
+ inflector.cond_plural( num_target, "history" ),
+ hist_names_str )
+ trans.sa_session.refresh( current_history )
+ current_user_roles = trans.get_current_user_roles()
+ source_lddas = []
+ if folder:
+ for library_dataset in folder.datasets:
+ ldda = library_dataset.library_dataset_dataset_association
+ if not ldda.deleted and trans.app.security_agent.can_access_library_item( current_user_roles, ldda, trans.user ):
+ source_lddas.append( ldda )
+ elif ldda_ids:
+ for ldda_id in ldda_ids:
+ # Secuirty access permiision chcck is not needed here since the current user had access
+ # to the lddas in order for the menu optin to be available.
+ ldda = trans.sa_session.query( trans.model.LibraryDatasetDatasetAssociation ).get( ldda_id )
+ source_lddas.append( ldda )
+ target_histories = [ current_history ]
+ if user:
+ target_histories = user.active_histories
+ return trans.fill_template( "/library/common/import_datasets_to_histories.mako",
+ cntrller=cntrller,
+ library=library,
+ current_history=trans.get_history(),
+ ldda_ids=ldda_ids,
+ target_history_ids=target_history_ids,
+ source_lddas=source_lddas,
+ target_histories=target_histories,
+ new_history_name=new_history_name,
+ show_deleted=show_deleted,
+ use_panels=use_panels,
+ message=message,
+ status=status )
@web.expose
def manage_template_inheritance( self, trans, cntrller, item_type, library_id, folder_id=None, ldda_id=None, **kwd ):
params = util.Params( kwd )
@@ -2064,6 +2170,31 @@
if library.root_folder == folder:
return library
return None
+def get_comptypes( trans ):
+ comptypes_t = comptypes
+ if trans.app.config.nginx_x_archive_files_base:
+ comptypes_t = ['ngxzip']
+ for comptype in trans.app.config.disable_library_comptypes:
+ # TODO: do this once, not every time (we're gonna raise an
+ # exception every time after the first time)
+ try:
+ comptypes_t.remove( comptype )
+ except:
+ pass
+ return comptypes_t
+def get_sorted_accessible_library_items( trans, cntrller, items, sort_attr ):
+ is_admin = trans.user_is_admin() and cntrller == 'library_admin'
+ if is_admin:
+ accessible_items = items
+ else:
+ # Enforce access permission settings
+ current_user_roles = trans.get_current_user_roles()
+ accessible_items = []
+ for item in items:
+ if trans.app.security_agent.can_access_library_item( current_user_roles, item, trans.user ):
+ accessible_items.append( item )
+ # Sort by name
+ return sort_by_attr( [ item for item in accessible_items ], sort_attr )
def sort_by_attr( seq, attr ):
"""
Sort the sequence of objects by object's attribute
@@ -2079,25 +2210,12 @@
intermed = map( None, map( getattr, seq, ( attr, ) * len( seq ) ), xrange( len( seq ) ), seq )
intermed.sort()
return map( operator.getitem, intermed, ( -1, ) * len( intermed ) )
-def get_sorted_accessible_library_items( trans, cntrller, items, sort_attr ):
- is_admin = trans.user_is_admin() and cntrller == 'library_admin'
- if is_admin:
- accessible_items = items
- else:
- # Enforce access permission settings
- current_user_roles = trans.get_current_user_roles()
- accessible_items = []
- for item in items:
- if trans.app.security_agent.can_access_library_item( current_user_roles, item, trans.user ):
- accessible_items.append( item )
- # Sort by name
- return sort_by_attr( [ item for item in accessible_items ], sort_attr )
def lucene_search( trans, cntrller, search_term, search_url, **kwd ):
"""Return display of results from a full-text lucene search of data libraries."""
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
- full_url = "%s?%s" % ( search_url, urllib.urlencode( { "kwd" : search_term } ) )
+ full_url = "%s/find?%s" % ( search_url, urllib.urlencode( { "kwd" : search_term } ) )
response = urllib2.urlopen( full_url )
ldda_ids = util.json.from_json_string( response.read() )[ "ids" ]
response.close()
@@ -2115,17 +2233,20 @@
if index_exists:
index = whoosh.index.open_dir( whoosh_index_dir )
# Set field boosts for searcher to place equal weight on all search fields.
- searcher = index.searcher( weighting=BM25F( field_B={ 'name_B' : 3.5,
- 'info_B' : 2.3,
- 'dbkey_B' : 3.1,
- 'message_B' : 2.1,
- 'state_B' : 1.2 } ) )
+ searcher = index.searcher( weighting=BM25F( field_B={ 'name_B' : 3.4,
+ 'info_B' : 3.2,
+ 'dbkey_B' : 3.3,
+ 'message_B' : 3.5 } ) )
# Perform search
- parser = MultifieldParser( [ 'name', 'info', 'dbkey', 'message', 'state' ], schema=schema )
+ parser = MultifieldParser( [ 'name', 'info', 'dbkey', 'message' ], schema=schema )
# Search term with wildcards may be slow...
- results = searcher.search( parser.parse( '*' + search_term + '*' ), minscore=1.0 )
+ results = searcher.search( parser.parse( '*' + search_term + '*' ), minscore=0.1 )
ldda_ids = [ result[ 'id' ] for result in results ]
- lddas = [ trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_id ) for ldda_id in ldda_ids ]
+ lddas = []
+ for ldda_id in ldda_ids:
+ ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_id )
+ if ldda:
+ lddas.append( ldda )
lddas = get_sorted_accessible_library_items( trans, cntrller, lddas, 'name' )
else:
message = "Tell your Galaxy administrator that the directory %s does not contain valid whoosh indexes" % str( whoosh_index_dir )
--- a/scripts/data_libraries/build_lucene_index.py Mon Jan 31 12:57:42 2011 -0500
+++ b/scripts/data_libraries/build_lucene_index.py Mon Jan 31 16:41:03 2011 -0500
@@ -30,7 +30,7 @@
sa_session, gconfig = get_sa_session( ini_file )
max_size = float( gconfig.get( "fulltext_max_size", 100 ) ) * 1048576
ignore_exts = gconfig.get( "fulltext_noindex_filetypes", "" ).split( "," )
- search_url = gconfig.get( "fulltext_index_url", None )
+ search_url = gconfig.get( "fulltext_url", None )
if not search_url:
raise ValueError( "Need to specify search functionality in universe_wsgi.ini" )
dataset_file = create_dataset_file( get_lddas( sa_session, max_size, ignore_exts ) )
@@ -41,7 +41,7 @@
os.remove( dataset_file )
def build_index( search_url, dataset_file ):
- url = "%s?%s" % ( search_url, urllib.urlencode( { "docfile" : dataset_file } ) )
+ url = "%s/index?%s" % ( search_url, urllib.urlencode( { "docfile" : dataset_file } ) )
request = urllib2.Request( url )
request.get_method = lambda: "PUT"
response = urllib2.urlopen( request )
@@ -57,21 +57,35 @@
def get_lddas( sa_session, max_size, ignore_exts ):
for ldda in sa_session.query( model.LibraryDatasetDatasetAssociation ).filter_by( deleted=False ):
- id = ldda.id
- name = ldda.name
- info = ldda.library_dataset.get_info()
- if info and not info.startswith( 'upload' ):
- info = info.replace( 'no info', '' )
- else:
- info = ''
- dbkey = ldda.metadata.dbkey
- state = ldda.state
- message = ldda.message
if ( float( ldda.dataset.get_size() ) > max_size or ldda.extension in ignore_exts ):
fname = ""
else:
fname = ldda.dataset.get_file_name()
- yield id, name, info, dbkey, state, message, fname
+ yield ldda.id, fname, _get_dataset_metadata(ldda)
+
+def _get_dataset_metadata(ldda):
+ """Retrieve descriptions and information associated with a dataset.
+ """
+ lds = ldda.library_dataset
+ folder_info = _get_folder_info(lds.folder)
+ lds_info = lds.get_info()
+ if lds_info and not lds_info.startswith("upload"):
+ lds_info = lds_info.replace("no info", "")
+ else:
+ lds_info = ""
+ return "%s %s %s %s %s" % (lds.name or "", lds_info, ldda.metadata.dbkey,
+ ldda.message, folder_info)
+
+def _get_folder_info(folder):
+ """Get names and descriptions for all parent folders except top level.
+ """
+ folder_info = ""
+ if folder and folder.parent:
+ folder_info = _get_folder_info(folder.parent)
+ folder_info += " %s %s" % (
+ folder.name.replace("Unnamed folder", ""),
+ folder.description or "")
+ return folder_info
def get_sa_session( ini_file ):
conf_parser = ConfigParser.ConfigParser( { 'here':os.getcwd() } )
--- a/scripts/data_libraries/build_whoosh_index.py Mon Jan 31 12:57:42 2011 -0500
+++ b/scripts/data_libraries/build_whoosh_index.py Mon Jan 31 16:41:03 2011 -0500
@@ -24,7 +24,7 @@
from whoosh.fields import Schema, STORED, ID, KEYWORD, TEXT
from whoosh.index import Index
whoosh_search_enabled = True
- schema = Schema( id=STORED, name=TEXT, info=TEXT, dbkey=TEXT, message=TEXT, state=TEXT )
+ schema = Schema( id=STORED, name=TEXT, info=TEXT, dbkey=TEXT, message=TEXT )
import galaxy.model.mapping
from galaxy import config, model
import pkg_resources
@@ -43,13 +43,12 @@
else:
return a_basestr
lddas_indexed = 0
- for id, name, info, dbkey, state, message in get_lddas( sa_session ):
+ for id, name, info, dbkey, message in get_lddas( sa_session ):
writer.add_document( id=id,
name=to_unicode( name ),
info=to_unicode( info ),
dbkey=to_unicode( dbkey ),
- message=to_unicode( message ),
- state=to_unicode( state ) )
+ message=to_unicode( message ) )
lddas_indexed += 1
writer.commit()
print "Number of active library datasets indexed: ", lddas_indexed
@@ -64,9 +63,8 @@
else:
info = ''
dbkey = ldda.metadata.dbkey
- state = ldda.state
message = ldda.message
- yield id, name, info, dbkey, state, message
+ yield id, name, info, dbkey, message
def get_sa_session_and_needed_config_settings( ini_file ):
conf_parser = ConfigParser.ConfigParser( { 'here' : os.getcwd() } )
--- a/templates/library/common/browse_library.mako Mon Jan 31 12:57:42 2011 -0500
+++ b/templates/library/common/browse_library.mako Mon Jan 31 16:41:03 2011 -0500
@@ -1,6 +1,7 @@
<%namespace file="/message.mako" import="render_msg" /><%namespace file="/library/common/library_item_info.mako" import="render_library_item_info" /><%namespace file="/library/common/common.mako" import="render_actions_on_multiple_items" />
+<%namespace file="/library/common/common.mako" import="common_javascripts" /><%!
def inherit(context):
@@ -46,6 +47,7 @@
<%def name="javascripts()">
${parent.javascripts()}
${h.js("class", "jquery.jstore")}
+ ${common_javascripts()}
${self.grid_javascripts()}
</%def>
@@ -152,15 +154,6 @@
});
});
- function checkForm() {
- if ( $("select#action_on_datasets_select option:selected").text() == "delete" ) {
- if ( confirm( "Click OK to delete these datasets?" ) ) {
- return true;
- } else {
- return false;
- }
- }
- }
// Looks for changes in dataset state using an async request. Keeps
// calling itself (via setTimeout) until all datasets are in a terminal
// state.
@@ -212,7 +205,7 @@
</script></%def>
-<%def name="render_dataset( cntrller, ldda, library_dataset, selected, library, folder, pad, parent, row_counter, tracked_datasets, show_deleted=False, render_checkboxes=True )">
+<%def name="render_dataset( cntrller, ldda, library_dataset, selected, library, folder, pad, parent, row_counter, tracked_datasets, show_deleted=False )"><%
## The received ldda must always be a LibraryDatasetDatasetAssociation object. The object id passed to methods
## from the drop down menu should be the ldda id to prevent id collision ( which could happen when displaying
@@ -248,13 +241,11 @@
%endif
id="libraryItem-${ldda.id}"><td style="padding-left: ${pad+20}px;">
- %if render_checkboxes:
- <input style="float: left;" type="checkbox" name="ldda_ids" value="${trans.security.encode_id( ldda.id )}"
- %if selected:
- checked="checked"
- %endif
- />
+ <input style="float: left;" type="checkbox" name="ldda_ids" value="${trans.security.encode_id( ldda.id )}"
+ %if selected:
+ checked="checked"
%endif
+ />
%if ldda.library_dataset.deleted:
<span class="libraryItem-error">
%endif
@@ -288,7 +279,7 @@
<a class="action-button" href="${h.url_for( controller='library_common', action='upload_library_dataset', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), replace_id=trans.security.encode_id( library_dataset.id ), show_deleted=show_deleted )}">Upload a new version of this dataset</a>
%endif
%if not branch_deleted( folder ) and not ldda.library_dataset.deleted and ldda.has_data:
- <a class="action-button" href="${h.url_for( controller='library_common', action='act_on_multiple_datasets', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), ldda_ids=trans.security.encode_id( ldda.id ), do_action='import_to_history', use_panels=use_panels, show_deleted=show_deleted )}">Import this dataset into your current history</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='import_datasets_to_histories', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), ldda_ids=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Import this dataset into selected histories</a><a class="action-button" href="${h.url_for( controller='library_common', action='download_dataset_from_folder', cntrller=cntrller, id=trans.security.encode_id( ldda.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels )}">Download this dataset</a>
%endif
%if can_modify:
@@ -379,6 +370,7 @@
<a class="action-button" href="${h.url_for( controller='library_common', action='create_folder', cntrller=cntrller, parent_id=trans.security.encode_id( folder.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Add sub-folder</a>
%endif
%if not branch_deleted( folder ):
+ <a class="action-button" href="${h.url_for( controller='library_common', action='import_datasets_to_histories', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), use_panels=use_panels, show_deleted=show_deleted )}">Select folder datasets for import into selected histories</a>
%if can_modify:
<a class="action-button" href="${h.url_for( controller='library_common', action='folder_info', cntrller=cntrller, id=trans.security.encode_id( folder.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a>
%else:
@@ -515,6 +507,7 @@
%endif
<a class="action-button" href="${h.url_for( controller='library_common', action='library_permissions', cntrller=cntrller, id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit permissions</a>
%endif
+ <a class="action-button" href="${h.url_for( controller='library_common', action='import_datasets_to_histories', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( library.root_folder.id ), use_panels=use_panels, show_deleted=show_deleted )}">Select datasets for import into selected histories</a>
%elif can_modify and not library.purged:
<a class="action-button" href="${h.url_for( controller='library_common', action='undelete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library.id ), item_type='library', use_panels=use_panels )}">Undelete this data library</a>
%elif library.purged:
@@ -539,7 +532,10 @@
<table cellspacing="0" cellpadding="0" border="0" width="100%" class="grid" id="library-grid"><thead><tr class="libraryTitle">
- <th>Name</th>
+ <th>
+ <input type="checkbox" id="checkAll" name=select_all_datasets_checkbox value="true" onclick='checkAllFields(1);'/><input type="hidden" name=select_all_datasets_checkbox value="true"/>
+ Name
+ </th><th>Message</th><th>Uploaded By</th><th>Date</th>
--- a/templates/library/common/common.mako Mon Jan 31 12:57:42 2011 -0500
+++ b/templates/library/common/common.mako Mon Jan 31 16:41:03 2011 -0500
@@ -1,5 +1,48 @@
<%namespace file="/common/template_common.mako" import="render_template_field" />
+<%def name="common_javascripts()">
+ <script type="text/javascript">
+ function checkAllFields()
+ {
+ var chkAll = document.getElementById('checkAll');
+ var checks = document.getElementsByTagName('input');
+ var boxLength = checks.length;
+ var allChecked = false;
+ var totalChecked = 0;
+ if ( chkAll.checked == true )
+ {
+ for ( i=0; i < boxLength; i++ )
+ {
+ if ( checks[i].name.indexOf( 'ldda_ids' ) != -1)
+ {
+ checks[i].checked = true;
+ }
+ }
+ }
+ else
+ {
+ for ( i=0; i < boxLength; i++ )
+ {
+ if ( checks[i].name.indexOf( 'ldda_ids' ) != -1)
+ {
+ checks[i].checked = false
+ }
+ }
+ }
+ }
+
+ function checkForm() {
+ if ( $("select#action_on_datasets_select option:selected").text() == "delete" ) {
+ if ( confirm( "Click OK to delete these datasets?" ) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ </script>
+</%def>
+
<%def name="render_upload_form( cntrller, upload_option, action, library_id, folder_id, replace_dataset, file_formats, dbkeys, space_to_tab, link_data_only, widgets, roles_select_list, history, show_deleted )"><%
import os, os.path
@@ -319,26 +362,34 @@
%endif
</%def>
-<%def name="render_actions_on_multiple_items()">
+<%def name="render_actions_on_multiple_items( actions_to_exclude=[] )">
+ <%
+ is_admin = trans.user_is_admin() and cntrller=='library_admin'
+ can_delete = 'delete' not in actions_to_exclude and is_admin
+ can_download = 'download' not in actions_to_exclude
+ can_import_to_histories = 'import_to_histories' not in actions_to_exclude
+ can_manage_permissions = 'manage_permissions' not in actions_to_exclude
+ %><tfoot><tr><td colspan="5" style="padding-left: 42px;">
For selected items:
<select name="do_action" id="action_on_selected_items">
- %if ( trans.user_is_admin() and cntrller=='library_admin' ):
- <option value="manage_permissions">Edit permissions</option>
- <option value="delete">Delete</option>
- %elif cntrller in ['library', 'library_search']:
- %if default_action == 'add':
- <option value="add" selected>Import into your current history</option>
+ %if can_import_to_histories:
+ %if not is_admin and default_action == 'import_to_histories':
+ <option value="import_to_histories" selected>Import selected datasets to histories</option>
%else:
- <option value="add">Import into your current history</option>
+ <option value="import_to_histories">Import selected datasets to histories</option>
%endif
- %if default_action == 'manage_permissions':
+ %endif
+ %if can_manage_permissions:
+ %if not is_admin and default_action == 'manage_permissions':
<option value="manage_permissions" selected>Edit permissions</option>
- # This condition should not contain an else clause because the user is not authorized
- # to manage dataset permissions unless the default action is 'manage_permissions'
+ %else:
+ <option value="manage_permissions">Edit permissions</option>
%endif
+ %endif
+ %if can_download:
%if 'gz' in comptypes:
<option value="tgz"
%if default_action == 'download':
@@ -361,6 +412,9 @@
>Download as a .zip file</option>
%endif
%endif
+ %if can_delete:
+ <option value="delete">Delete</option>
+ %endif
</select><input type="submit" class="primary-button" name="action_on_datasets_button" id="action_on_datasets_button" value="Go"/></td>
--- a/templates/library/common/ldda_info.mako Mon Jan 31 12:57:42 2011 -0500
+++ b/templates/library/common/ldda_info.mako Mon Jan 31 16:41:03 2011 -0500
@@ -66,7 +66,7 @@
<a class="action-button" href="${h.url_for( controller='library_common', action='upload_library_dataset', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), replace_id=trans.security.encode_id( ldda.library_dataset.id ) )}">Upload a new version of this dataset</a>
%endif
%if cntrller=='library' and ldda.has_data():
- <a class="action-button" href="${h.url_for( controller='library_common', action='act_on_multiple_datasets', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), ldda_ids=trans.security.encode_id( ldda.id ), do_action='import_to_history', use_panels=use_panels, show_deleted=show_deleted )}">Import this dataset into your current history</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='import_datasets_to_histories', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), ldda_ids=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Select histories to import this dataset</a><a class="action-button" href="${h.url_for( controller='library_common', action='download_dataset_from_folder', cntrller=cntrller, id=trans.security.encode_id( ldda.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Download this dataset</a>
%endif
%if show_associated_hdas_and_lddas:
--- a/templates/library/common/library_dataset_search_results.mako Mon Jan 31 12:57:42 2011 -0500
+++ b/templates/library/common/library_dataset_search_results.mako Mon Jan 31 16:41:03 2011 -0500
@@ -1,5 +1,7 @@
<%namespace file="/message.mako" import="render_msg" /><%namespace file="/library/common/browse_library.mako" import="render_dataset" />
+<%namespace file="/library/common/common.mako" import="render_actions_on_multiple_items" />
+<%namespace file="/library/common/common.mako" import="common_javascripts" /><%!
def inherit(context):
@@ -44,6 +46,7 @@
<%def name="javascripts()">
${parent.javascripts()}
${h.js("class", "jquery.jstore")}
+ ${common_javascripts()}
</%def><%def name="render_searched_components()">
@@ -52,7 +55,6 @@
<li>info</li><li>dbkey (genome build)</li><li>message</li>
- <li>state</li>
%if trans.app.config.enable_lucene_library_search:
<li>disk file content</li>
%endif
@@ -91,34 +93,69 @@
%if lddas:
<p>The string "${search_term}" was found in at least one of the following information components of the displayed library datasets.</p>
${render_searched_components()}
- <table cellspacing="0" cellpadding="0" border="0" width="100%" class="grid" id="library-grid">
- <thead>
- <tr class="libraryTitle">
- <th>Name</th>
- <th>Message</th>
- <th>Uploaded By</th>
- <th>Date</th>
- <th>File Size</th>
- </tr>
- </thead>
- <%
- tracked_datasets = {}
- row_counter = RowCounter()
- my_row = row_counter.count
- %>
- %for ldda in lddas:
+ <form name="act_on_multiple_datasets" action="${h.url_for( controller='library_common', action='act_on_multiple_datasets', cntrller=cntrller, use_panels=use_panels, show_deleted=show_deleted )}" onSubmit="javascript:return checkForm();" method="post">
+ <table cellspacing="0" cellpadding="0" border="0" width="100%" class="grid" id="library-grid">
+ <thead>
+ <tr class="libraryTitle">
+ <th>
+ <input type="checkbox" id="checkAll" name=select_all_datasets_checkbox value="true" onclick='checkAllFields(1);'/><input type="hidden" name=select_all_datasets_checkbox value="true"/>
+ Name
+ </th>
+ <th>Message</th>
+ <th>Uploaded By</th>
+ <th>Date</th>
+ <th>File Size</th>
+ </tr>
+ </thead><%
- library_dataset = ldda.library_dataset
- folder = library_dataset.folder
- library = folder.parent_library
+ tracked_datasets = {}
+ row_counter = RowCounter()
+ my_row = row_counter.count
%>
- ${render_dataset( cntrller, ldda, library_dataset, False, library, folder, 0, my_row, row_counter, tracked_datasets, show_deleted=False, render_checkboxes=False )}
- <%
- my_row = row_counter.count
- row_counter.increment()
- %>
- %endfor
- </table>
+ %for ldda in lddas:
+ <%
+ library_dataset = ldda.library_dataset
+ folder = library_dataset.folder
+ library = folder.parent_library
+ %>
+ ${render_dataset( cntrller, ldda, library_dataset, False, library, folder, 0, my_row, row_counter, tracked_datasets, show_deleted=False )}
+ <%
+ my_row = row_counter.count
+ row_counter.increment()
+ %>
+ %endfor
+ ${render_actions_on_multiple_items( actions_to_exclude=[ 'manage_permissions' ] )}
+ </table>
+ </form>
+ ## Help about compression types
+
+ <div class="libraryItemBody">
+ <p class="infomark">
+ TIP: You can download individual library files by selecting "Download this dataset" from the context menu (triangle) next to the dataset's name.
+ </p>
+ </div>
+ %if len( comptypes ) > 1:
+ <div class="libraryItemBody">
+ <p class="infomark">
+ TIP: Multiple compression options are available for downloading library datasets:
+ </p>
+ <ul style="padding-left: 1em; list-style-type: disc;">
+ %if 'gz' in comptypes:
+ <li>gzip: Recommended for fast network connections
+ %if trans.app.config.upstream_gzip:
+ NOTE: The file you receive will be an uncompressed .tar file - this is because the Galaxy server compresses it and your browser decompresses it on the fly.
+ %endif
+ </li>
+ %endif
+ %if 'bz2' in comptypes:
+ <li>bzip2: Recommended for slower network connections (smaller size but takes longer to compress)</li>
+ %endif
+ %if 'zip' in comptypes:
+ <li>zip: Not recommended but is provided as an option for those who cannot open the above formats</li>
+ %endif
+ </ul>
+ </div>
+ %endif
%elif status != 'error':
<p>The string "${search_term}" was not found in any of the following information components for any library datasets that you can access.</p>
${render_searched_components()}
--- a/test/base/twilltestcase.py Mon Jan 31 12:57:42 2011 -0500
+++ b/test/base/twilltestcase.py Mon Jan 31 16:41:03 2011 -0500
@@ -2106,6 +2106,13 @@
% ( self.url, cntrller, library_id, ldda_ids, do_action ) )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
+ def import_datasets_to_histories( self, cntrller, library_id, ldda_ids='', new_history_name='Unnamed history', strings_displayed=[] ):
+ # Can't use the ~/library_admin/libraries form as twill barfs on it so we'll simulate the form submission
+ # by going directly to the form action
+ self.visit_url( '%s/library_common/import_datasets_to_histories?cntrller=%s&library_id=%s&ldda_ids=%s&new_history_name=%s&import_datasets_to_histories_button=Import+library+datasets' \
+ % ( self.url, cntrller, library_id, ldda_ids, new_history_name ) )
+ for check_str in strings_displayed:
+ self.check_page_for_string( check_str )
def download_archive_of_library_files( self, cntrller, library_id, ldda_ids, format ):
self.home()
# Here it would be ideal to have twill set form values and submit the form, but
--- a/test/functional/test_library_security.py Mon Jan 31 12:57:42 2011 -0500
+++ b/test/functional/test_library_security.py Mon Jan 31 16:41:03 2011 -0500
@@ -296,11 +296,11 @@
strings_displayed=[ '2.bed',
'This is the latest version of this library dataset',
'Edit attributes of 2.bed' ] )
- self.act_on_multiple_datasets( 'library',
- self.security.encode_id( library1.id ),
- 'import_to_history',
- ldda_ids=self.security.encode_id( ldda2.id ),
- strings_displayed=[ '1 dataset(s) have been imported into your history' ] )
+ self.import_datasets_to_histories( cntrller='library',
+ library_id=self.security.encode_id( library1.id ),
+ ldda_ids=self.security.encode_id( ldda2.id ),
+ new_history_name='goodbye',
+ strings_displayed=[ '1 dataset have been imported into 1 history' ] )
self.logout()
# regular_user2 should not be able to see ldda2
self.login( email=regular_user2.email )
@@ -382,10 +382,10 @@
def check_edit_page( lddas, strings_displayed=[], strings_not_displayed=[] ):
for ldda in lddas:
# Import each library dataset into our history
- self.act_on_multiple_datasets( 'library',
- self.security.encode_id( library1.id ),
- 'import_to_history',
- ldda_ids=self.security.encode_id( ldda.id ) )
+ self.import_datasets_to_histories( cntrller='library',
+ library_id=self.security.encode_id( library1.id ),
+ ldda_ids=self.security.encode_id( ldda.id ),
+ new_history_name='hello' )
# Determine the new HistoryDatasetAssociation id created when the library dataset was imported into our history
last_hda_created = get_latest_hda()
self.edit_hda_attribute_info( str( last_hda_created.id ),
@@ -393,8 +393,8 @@
# admin_user is associated with role1, so should have all permissions on imported datasets
check_edit_page( latest_3_lddas,
strings_displayed=[ 'Manage dataset permissions on',
- 'can manage the roles associated with permissions on this dataset',
- 'can import this dataset into their history for analysis' ] )
+ 'can manage the roles associated with permissions on this dataset',
+ 'can import this dataset into their history for analysis' ] )
self.logout()
# regular_user1 is associated with role1, so should have all permissions on imported datasets
self.login( email=regular_user1.email )
--- a/tools/data_source/access_libraries.xml Mon Jan 31 12:57:42 2011 -0500
+++ b/tools/data_source/access_libraries.xml Mon Jan 31 16:41:03 2011 -0500
@@ -2,7 +2,7 @@
<tool name="Access Libraries" id="library_access1"><description>stored locally</description><inputs action="/library/index" method="get" target="_parent">
- <param name="default_action" type="hidden" value="add" />
+ <param name="default_action" type="hidden" value="import_to_histories" /></inputs><uihints minwidth="800"/></tool>
--- a/universe_wsgi.ini.sample Mon Jan 31 12:57:42 2011 -0500
+++ b/universe_wsgi.ini.sample Mon Jan 31 16:41:03 2011 -0500
@@ -337,18 +337,17 @@
#transfer_manager_port = 8163
# Search data libraries with whoosh
-enable_whoosh_library_search = True
+#enable_whoosh_library_search = True
# Whoosh indexes are stored in this directory.
-whoosh_index_dir = database/whoosh_indexes
+#whoosh_index_dir = database/whoosh_indexes
# Search data libraries with lucene
#enable_lucene_library_search = False
# maxiumum file size to index for searching, in MB
#fulltext_max_size = 500
#fulltext_noindex_filetypes=bam,sam,wig,bigwig,fasta,fastq,fastqsolexa,fastqillumina,fastqsanger
-# base URL of server providing search functionality using whoosh.
-#fulltext_index_url = http://localhost:8081/index
-#fulltext_find_url = http://localhost:8081/find
+# base URL of server providing search functionality using lucene
+#fulltext_url = http://localhost:8081
# -- Users and Security
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

galaxy-dist commit fd4a22ba5b57: trackster: Make navbar more compact; line things up properly. Fix ReferenceTrack adding extra space to top LabelTrack
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1289775205 18000
# Node ID fd4a22ba5b57a48a2bed45333c2dfddaec61c359
# Parent 9b2bc4d4d6ca9b1f4275cb335460c8d570c7eeaf
trackster: Make navbar more compact; line things up properly. Fix ReferenceTrack adding extra space to top LabelTrack
--- a/static/scripts/trackster.js
+++ b/static/scripts/trackster.js
@@ -155,8 +155,8 @@ var View = function( container, title, v
if (this.vis_id !== undefined) {
this.hidden_input = $("<input/>").attr("type", "hidden").val(this.vis_id).appendTo(this.chrom_form);
}
- this.zo_link = $("<a/>").click(function() { view.zoom_out(); view.redraw(); }).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);
- this.zi_link = $("<a/>").click(function() { view.zoom_in(); view.redraw(); }).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);
+ this.zo_link = $("<a id='zoom-out' />").click(function() { view.zoom_out(); view.redraw(); }).appendTo(this.chrom_form);
+ this.zi_link = $("<a id='zoom-in' />").click(function() { view.zoom_in(); view.redraw(); }).appendTo(this.chrom_form);
$.ajax({
url: chrom_url,
@@ -1039,10 +1039,10 @@ var LineTrack = function ( name, view, d
var min_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_minval').text(round_1000(track.prefs.min_value));
var max_label = $("<div />").addClass('yaxislabel').attr("id", 'linetrack_' + track_id + '_maxval').text(round_1000(track.prefs.max_value));
- max_label.css({ position: "absolute", top: "22px", left: "10px" });
+ max_label.css({ position: "absolute", top: "24px", left: "10px" });
max_label.prependTo(track.container_div);
- min_label.css({ position: "absolute", top: track.height_px + 11 + "px", left: "10px" });
+ min_label.css({ position: "absolute", top: track.height_px + 12 + "px", left: "10px" });
min_label.prependTo(track.container_div);
});
},
--- a/static/june_2007_style/blue/trackster.css
+++ b/static/june_2007_style/blue/trackster.css
@@ -1,12 +1,14 @@
.viewport-container{overflow-x:hidden;overflow-y:auto;}
-.nav{padding:0 0;color:#333;font-weight:bold;background:#cccccc;background-image:url(panel_header_bg.png);background-position:bottom center;background-repeat:repeat-x;height:2.5em;border-bottom:solid #333 1px;}
+.nav{padding:0 0;color:#333;font-weight:bold;background:#cccccc;background-image:url(panel_header_bg.png);background-position:middle center;background-repeat:repeat-x;border-bottom:solid #333 1px;}
.content{font:10px verdana;}
-.nav-controls{text-align:center;position:relative;padding:2px 0;}
+.nav-controls{text-align:center;padding:1px 0;}
.nav-controls input{margin:0 5px;}
-.nav-controls a{padding:0 0.4em;}
+#zoom-in,#zoom-out{display:inline-block;height:16px;width:16px;margin-bottom:-3px;}
+#zoom-out{background:transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;}
+#zoom-in{margin-left:10px;background:transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;}
.nav-input{font-size:12px;width:30em;z-index:1000;}
-.location{display:inline-block;width:15em;margin:0px 10px;}
-.draghandle{cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;}
+.location{display:inline-block;width:15em;margin:0 10px;}
+.draghandle{margin-top:2px;cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;}
.intro{z-index:1000;margin-left:auto;margin-right:auto;color:#555;text-align:center;font-size:16px;}
.overview{width:100%;margin:0px;color:white;}
.overview-viewport{position:relative;height:14px;background:white;margin:0;}
@@ -17,15 +19,16 @@
.viewport-canvas{width:100%;height:100px;}
.yaxislabel{color:#777;z-index:100;}
.line-track .track-content{border-top:1px solid #ddd;border-bottom:1px solid #ddd;}
-.track{background:white;margin-bottom:1px;padding-bottom:4px;border-bottom:#eee solid 1px;}
+.track{background:white;margin-bottom:2px;border-bottom:#eee solid 1px;}
.track-header{text-align:left;padding:4px 0px;color:#666;}
-.track-header .menubutton{margin-left:3px;}
+.track-header .menubutton{margin-left:0px;}
.track-content{overflow:hidden;text-align:center;}
-.track.error .track-content{background-color:#ECB4AF;}
-.track.nodata .track-content{background-color:#ddd;}
+.track.error .track-content{background-color:#ECB4AF;padding:2px 0;}
+.track.nodata .track-content{background-color:#ddd;padding:2px 0;}
.loading{min-height:100px;}
.label-track{font-size:10px;border:none;padding:0;margin:0;height:1.3em;}
.label-track .label{border-left:solid #999 1px;padding:1px;padding-bottom:2px;display:inline-block;}
+.reference-track{border:none;margin:0;padding:0;}
.right-float{float:right;margin-left:5px;}
.top-labeltrack{position:relative;border-bottom:solid #999 1px;}
.nav-labeltrack{border-top:solid #999 1px;border-bottom:solid #333 1px;}
--- a/static/june_2007_style/trackster.css.tmpl
+++ b/static/june_2007_style/trackster.css.tmpl
@@ -4,12 +4,12 @@
}
.nav {
padding: 0 0;
- color:#333;font-weight:bold;
+ color:#333;
+ font-weight:bold;
background:#cccccc;
background-image:url(panel_header_bg.png);
- background-position: bottom center;
+ background-position: middle center;
background-repeat:repeat-x;
- height: 2.5em;
border-bottom: solid #333 1px;
}
.content {
@@ -17,14 +17,23 @@
}
.nav-controls {
text-align: center;
- position: relative;
- padding: 2px 0;
+ padding: 1px 0;
}
.nav-controls input {
margin: 0 5px;
}
-.nav-controls a {
- padding: 0 0.4em;
+#zoom-in, #zoom-out {
+ display:inline-block;
+ height: 16px;
+ width: 16px;
+ margin-bottom: -3px;
+}
+#zoom-out {
+ background: transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;
+}
+#zoom-in {
+ margin-left: 10px;
+ background: transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;
}
.nav-input {
font-size: 12px;
@@ -34,9 +43,10 @@
.location {
display: inline-block;
width: 15em;
- margin: 0px 10px;
+ margin: 0 10px;
}
.draghandle {
+ margin-top: 2px;
cursor: move;
float: left;
background: transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;
@@ -120,8 +130,7 @@
/* border-top: solid #DDDDDD 1px; */
/* border-bottom: solid #DDDDDD 1px; */
background: white;
- margin-bottom: 1px;
- padding-bottom: 4px;
+ margin-bottom: 2px;
border-bottom: #eee solid 1px;
}
@@ -132,7 +141,7 @@
}
.track-header .menubutton {
- margin-left: 3px;
+ margin-left: 0px;
}
.track-content {
@@ -142,9 +151,11 @@
.track.error .track-content {
background-color: #ECB4AF;
+ padding: 2px 0;
}
.track.nodata .track-content {
background-color: #ddd;
+ padding: 2px 0;
}
.loading {
@@ -165,6 +176,11 @@
padding-bottom: 2px;
display: inline-block;
}
+.reference-track {
+ border: none;
+ margin: 0;
+ padding: 0;
+}
.right-float {
float: right;
margin-left: 5px;
--- a/static/scripts/packed/trackster.js
+++ b/static/scripts/packed/trackster.js
@@ -1,1 +1,1 @@
-var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=50,CONNECTOR_COLOR="#ccc",DATA_ERROR="There was an error in indexing this dataset.",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",FILTERABLE_CLASS="filterable",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=5,CACHED_DATA=5,DUMMY_CANVAS=document.createElement("canvas"),RIGHT_STRAND,LEFT_STRAND;if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(DUMMY_CANVAS)}CONTEXT=DUMMY_CANVAS.getContext("2d");PX_PER_CHAR=CONTEXT.measureText("A").width;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPa
ttern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,d,c,b,e){this.container=a;this.vis_id=c;this.dbkey=b;this.
title=d;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(e);this.reset()};$.extend(View.prototype,{init:function(d){var c=this.container,a=this;this.top_container=$("<div/>").addClass("top-container").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(c);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top
_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-a
utocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(f){if(f.type==="focusout"||(f.keyCode||f.which)===13||(f.keyCode||f.which)===27){if((f.keyCode||f.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a/>").click(function(){a.zoom_out();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom-out.png" />').appendTo(this.chrom_form);this.zi_link=$("<a/>").click(funct
ion(){a.zoom_in();a.redraw()}).html('<img src="'+image_path+'/fugue/magnifier-zoom.png" />').appendTo(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(f){if(f.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=f.chrom_info;var j='<option value="">Select Chrom/Contig</option>';for(var h=0,e=a.chrom_data.length;h<e;h++){var g=a.chrom_data[h].chrom;j+='<option value="'+g+'">'+g+"</option>"}a.chrom_select.html(j);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())});if(d){d()}},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(f){a.zoom_in(f.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(f){this.current_x=f.offsetX}).bind("drag",function(f){var h=f.offsetX-this.current_x;this.current_x=f.offsetX;var g=Math.round(h/a.viewport_container
.width()*(a.max_high-a.max_low));a.move_delta(-g)});this.overview_close.bind("click",function(){for(var f=0,e=a.tracks.length;f<e;f++){a.tracks[f].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("dragstart",function(f){this.original_low=a.low;this.current_height=f.clientY;this.current_x=f.offsetX;this.enable_pan=(f.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(h){if(!this.enable_pan||this.in_reordering){return}var f=$(this);var j=h.offsetX-this.current_x;var g=f.scrollTop()-(h.clientY-this.current_height);f.scrollTop(g);this.current_height=h.clientY;this.current_x=h.offsetX;var i=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(i)});this.top_labeltrack.bind("dragstart",function(f){this.drag_origin_x=f.clientX;this.drag_origin_pos=f.clientX/a.viewport_container.width()*(a.high-a.low)+
a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+a.top_labeltrack.height()+a.nav_labeltrack.height(),top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var g=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,f=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,i=(a.high-a.low),h=a.viewport_container.width();a.update_location(Math.round(g/h*i)+a.low,Math.round(f/h*i)+a.low);this.drag_div.css({left:g+"px",width:(f-g)+"px"})}).bind("dragend",function(k){var g=Math.min(k.clientX,this.drag_origin_x),f=Math.max(k.clientX,this.drag_origin_x),i=(a.high-a.low),h=a.viewport_container.width(),j=a.low;a.low=Math.round(g/h*i)+j;a.high=Math.round(f/h*i)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack));$(window).bind("resize",function(){a.resize_window(
)});$(document).bind("redraw",function(){a.redraw()});this.reset();$(window).trigger("resize")},update_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(e,b,g){var d=this;var f=$.grep(d.chrom_data,function(j,k){return j.chrom===e})[0];if(f===undefined){return}if(e!==d.chrom){d.chrom=e;if(!d.chrom){d.intro_div.show()}else{d.intro_div.hide()}d.chrom_select.val(d.chrom);d.max_high=f.len;d.reset();d.redraw(true);for(var h=0,a=d.tracks.length;h<a;h++){var c=d.tracks[h];if(c.init){c.init()}}}if(b!==undefined&&g!==undefined){d.low=Math.max(b,0);d.high=Math.min(g,d.max_high)}d.reset_overview();d.redraw()},go_to:function(f){var j=this,a,d,b=f.split(":"),h=b[0],i=b[1];if(i!==undefined){try{var g=i.split("-");a=parseInt(g[0].replace(/,/g,""),10);d=parseInt(g[1].replace(/,/g,""),10)}catch(c){return false}}j.change_chrom(h,a,d)},move_fraction:function(c){var a=this;var b=
a.high-a.low;this.move_delta(c*b)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.
min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var e=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left:a,width:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+
this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Filter=function(b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.sli
der_min=Number.MAX_VALUE;this.slider_max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null};$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values",[this.slider_min,this.slider_max])}}});var get_filters=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e=="int"||e=="f
loat"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var Track=function(b,a,d,c){this.name=b;this.view=a;this.parent_element=d;this.filters=(c!==undefined?get_filters(c):[]);this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.filtering_div=$("<div class='track-filters'>").appendTo(this.container_div);this.filtering_div.hide();this.filtering_div.bind("drag",function(i){i.stopPropagation()});var b=$("<table class='filters'>").appendTo(this.filtering_div);var c=this;for(va
r e=0;e<this.filters.length;e++){var a=this.filters[e];var f=$("<tr>").appendTo(b);var g=$("<th class='filter-info'>").appendTo(f);var j=$("<span class='name'>").appendTo(g);j.text(a.name+" ");var d=$("<span class='values'>").appendTo(g);var h=$("<td>").appendTo(f);a.control_element=$("<div id='"+a.name+"-filter-control' style='width: 200px; position: relative'>").appendTo(h);a.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(k,l){var i=l.values;d.text("["+i[0]+"-"+i[1]+"]");a.low=i[0];a.high=i[1];c.draw(true)},change:function(i,k){a.control_element.slider("option","slide").call(a.control_element,i,k)}});a.slider=a.control_element;a.slider_label=d}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_di
v.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.removeClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a
.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}}});var TiledTrack=function(){var b=this,j=b.view;if(b.hidden){return}if(b.display_modes!==undefined){if(b.mode_div===undefined){b.mode_div=$("<div class='right-float menubutton popup' />").appendTo(b.header_div);var e=b.display_modes[0];b.mode=e;b.mode_div.text(e);var c=function(i){b.mode_div.text(i);b.mode=i;b.tile_cache.clear();b.draw()};var a={};for(var f=0,h=b.display_modes.length;f<h;f++){var g=b.display_modes[f];a[g]=function(i){return function(){c(i)}}(g)}make_popupmenu(b.mode_div,a)}else{b.mode_div.hide()}}var d={};d["Set as overview"]=function(){j.overview_viewport.find("canvas").remove();b.is_overview=true;b.set_overview();for(var i in j.tracks){if(j.tracks[i]!==b){j.tracks[i].is_overview=false}}};d["Edit configuration"]=function(){var l=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},i=function(){b.update_options(b.track_
id);hide_modal();$(window).unbind("keypress.check_enter_esc")},k=function(m){if((m.keyCode||m.which)===27){l()}else{if((m.keyCode||m.which)===13){i()}}};$(window).bind("keypress.check_enter_esc",k);show_modal("Configure Track",b.gen_options(b.track_id),{Cancel:l,OK:i})};if(b.filters.length>0){d["Show filters"]=function(){var i;if(!b.filtering_div.is(":visible")){i="Hide filters";b.filters_visible=true}else{i="Show filters";b.filters_visible=false}$("#"+b.name_div.attr("id")+"-menu").find("li").eq(2).text(i);b.filtering_div.toggle()}}d.Remove=function(){j.remove_track(b);if(j.num_tracks===0){$("#no-tracks").show()}};b.popup_menu=make_popupmenu(b.name_div,d);show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(a){var k=this.view.low,g=this.view.high,h=g-k,f=this.view.resolution;var n=$("<div style='position: relative;'></div>"),o=this.content_div.width()/h;this.content_div.append(n);this.max_height=
0;var b=Math.floor(k/f/DENSITY);var j={};while((b*DENSITY*f)<g){var l=this.content_div.width()+"_"+o+"_"+b;var e=this.tile_cache.get(l);if(!a&&e){var i=b*DENSITY*f;var d=(i-k)*o;if(this.left_offset){d-=this.left_offset}e.css({left:d});this.show_tile(e,n)}else{this.delayed_draw(this,l,k,g,b,f,n,o,j)}b+=1}var c=this;var m=setInterval(function(){if(obj_length(j)===0){if(c.content_div.children().length>1){c.content_div.children(":first").remove()}for(var p=0;p<c.filters.length;p++){c.filters[p].update_ui_elt()}clearInterval(m)}},50)},delayed_draw:function(c,h,g,e,b,d,i,j,f){var a=setTimeout(function(){if(g<=c.view.high&&e>=c.view.low){var k=c.draw_tile(d,b,i,j);if(k){if(!c.initial_canvas&&!window.G_vmlCanvasManager){c.initial_canvas=$(k).clone();var n=k.get(0).getContext("2d");var l=c.initial_canvas.get(0).getContext("2d");var m=n.getImageData(0,0,n.canvas.width,n.canvas.height);l.putImageData(m,0,0);c.set_overview()}c.tile_cache.set(h,k);c.show_tile(k,i)}}delete f[a]},50);f[a]=
true},show_tile:function(a,c){var b=this;c.append(a);b.max_height=Math.max(b.max_height,a.height());b.content_div.css("height",b.max_height+"px");if(a.hasClass(FILTERABLE_CLASS)){show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters");if(b.filters_visible){b.filtering_div.show()}}else{show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false);b.filtering_div.hide()}},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.
floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g)
{c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,j=f+"_"+b;var e=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(e)}e=$(e);var n=e.get(0).getContext("2d");if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o),i=Math.round(o/2);n.fillText(m[h],a+this.left_offset+i,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_conta
iner);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");var e=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=e.min;a.prefs.max_value=e.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=e.total_frequency;a.container_div.find(".yaxislabel").remove();var f=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));v
ar d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.prefs.max_value));d.css({position:"absolute",top:"22px",left:"10px"});d.prependTo(a.container_div);f.css({position:"absolute",top:a.height_px+11+"px",left:"10px"});f.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){var h=g.data;c.data_cache.set(e,h);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(o,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*o,a=DENSITY*o,w=o+"_"+r;var b=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(b)}b=$(b);if(this.data_cache.get(w)===undefined){this.get_data(o,r);return}var v=this.data_cache.
get(w);if(!v){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var n=b.get(0).getContext("2d"),j=false,k=this.prefs.min_value,g=this.prefs.max_value,m=this.vertical_range,t=this.total_frequency,d=this.height_px,l=this.mode;n.beginPath();n.fillStyle=this.prefs.color;var u,h,f;if(v.length>1){f=Math.ceil((v[1][0]-v[0][0])*e)}else{f=10}for(var p=0,q=v.length;p<q;p++){u=Math.round((v[p][0]-s)*e);h=v[p][1];if(h===null){if(j&&l==="Filled"){n.lineTo(u,d)}j=false;continue}if(h<k){h=k}else{if(h>g){h=g}}if(l==="Histogram"){h=Math.round(d-(h-k)/m*d);n.fillRect(u,h,f,d-h)}else{if(l==="Intensity"){h=255-Math.floor((h-k)/m*255);n.fillStyle="rgb("+h+","+h+","+h+")";n.fillRect(u,0,f,d)}else{h=Math.round(d-(h-k)/m*d);if(j){n.lineTo(u,h)}else{j=true;if(l==="Filled"){n.moveTo(u,d);n.lineTo(u,h)}else{n.moveTo(u,h)}}}}}if(l==="Filled"){if(j){n.lineTo(u,d)}n.fill()}else{n.stroke()}c.append(b);return b},gen_options:funct
ion(m){var a=$("<div />").addClass("form-row");var e="track_"+m+"_color",b=$("<label />").attr("for",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+m+"_minval",l=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),k=$("<input></input>").attr("id",h).val(d),j="track_"+m+"_maxval",g=$("<label></label>").attr("for",j).text("Max value:"),i=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",j).val(i);return a.append(l).append(k).append(g).append(f).append(b).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_color").val();if(a!==this.prefs.min_value||c!==this.prefs.max_value||b!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(c);this.prefs.color=b;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetr
ack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,e,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container,e);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"#444",label_color:"black",show_counts:true}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.m
ax_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},function(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,g,b,q){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=a;this.inc_slots[a].mode=q;this.s_e_by_tile[a]={}}var m=this.inc_slots[a].w_scale,y=[],h=0,n=this.view.max_low;var A=[];if(this.inc_slots[a].mode!==q){delete this.inc_slots[a];this.inc_slots[a]={mode:q,w_scale:m};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var v=0,w=g.length;v<w;v++){var f=g[v],l=f[0];if(this.inc_slots[a][l]!==undefined){h=Math.max(h,this.inc_slots[a][l]);A.push(this.inc_slots[a][l])}else{y.push(v)}}for(var v=0,w
=y.length;v<w;v++){var f=g[y[v]],l=f[0],r=f[1],c=f[2],p=f[3],d=Math.floor((r-n)*m),e=Math.ceil((c-n)*m);if(p!==undefined&&!b){var s=CONTEXT.measureText(p).width;if(d-s<0){e+=s}else{d-=s}}var u=0;while(u<=MAX_FEATURE_DEPTH){var o=true;if(this.s_e_by_tile[a][u]!==undefined){for(var t=0,z=this.s_e_by_tile[a][u].length;t<z;t++){var x=this.s_e_by_tile[a][u][t];if(e>x[0]&&d<x[1]){o=false;break}}}if(o){if(this.s_e_by_tile[a][u]===undefined){this.s_e_by_tile[a][u]=[]}this.s_e_by_tile[a][u].push([d,e]);this.inc_slots[a][l]=u;h=Math.max(h,u);break}u++}}return h},rect_or_text:function(r,l,t,b,q,f,i,e){r.textAlign="center";var k=0,p=Math.round(l/2);for(var m=0,s=i.length;m<s;m++){var j=i[m],d="MIDNSHP"[j[0]],n=j[1];if(d==="H"||d==="S"){k-=n}var g=q+k,w=Math.floor(Math.max(0,(g-t)*l)),h=Math.floor(Math.max(0,(g+n-t)*l));switch(d){case"S":case"H":case"M":var o=f.slice(k,n);if((this.mode==="Pack"||this.mode==="Auto")&&f!==undefined&&l>PX_PER_CHAR){r.fillStyle=this.prefs.block_color;r.fillR
ect(w+this.left_offset,e+1,h-w,9);r.fillStyle=CONNECTOR_COLOR;for(var u=0,a=o.length;u<a;u++){if(g+u>=t&&g+u<=b){var v=Math.floor(Math.max(0,(g+u-t)*l));r.fillText(o[u],v+this.left_offset+p,e+9)}}}else{r.fillStyle=this.prefs.block_color;r.fillRect(w+this.left_offset,e+4,h-w,3)}break;case"N":r.fillStyle=CONNECTOR_COLOR;r.fillRect(w+this.left_offset,e+5,h-w,1);break;case"D":r.fillStyle="red";r.fillRect(w+this.left_offset,e+4,h-w,3);break;case"P":case"I":break}k+=n}},draw_tile:function(ag,o,s,av){var N=o*DENSITY*ag,al=(o+1)*DENSITY*ag,M=al-N;var an=(!this.initial_canvas?"initial":N+"_"+al);var I=this.data_cache.get(an);var e;if(I===undefined||(this.mode!=="Auto"&&I.dataset_type==="summary_tree")){this.data_queue[[N,al]]=true;this.get_data(N,al);return}var a=Math.ceil(M*av),ai=this.prefs.label_color,l=this.prefs.block_color,r=this.mode,z=25,ae=(r==="Squish")||(r==="Dense")&&(r!=="Pack")||(r==="Auto"&&(I.extra_info==="no_detail")),W=this.left_offset,au,D,aw;var q=document.createE
lement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(q)}q=$(q);if(I.dataset_type==="summary_tree"){D=this.summary_draw_height}else{if(r==="Dense"){D=z;aw=10}else{aw=(ae?this.vertical_nodetail_px:this.vertical_detail_px);var A=(av<0.0001?1/this.view.zoom_res:av);D=this.incremental_slots(A,I.data,ae,r)*aw+z;au=this.inc_slots[A]}}q.css({position:"absolute",top:0,left:(N-this.view.low)*av-W});q.get(0).width=a+W;q.get(0).height=D;s.parent().css("height",Math.max(this.height_px,D)+"px");var J=q.get(0).getContext("2d");J.fillStyle=l;J.font=this.default_font;J.textAlign="right";this.container_div.find(".yaxislabel").remove();if(I.dataset_type=="summary_tree"){var Y=I.data,L=I.max,b=Math.ceil(I.delta*av);var p=$("<div />").addClass("yaxislabel").text(L);p.css({position:"absolute",top:"22px",left:"10px"});p.prependTo(this.container_div);for(var ap=0,H=Y.length;ap<H;ap++){var aa=Math.floor((Y[ap][0]-N)*av);var Z=Y[ap][1];if(!Z){continue}var am=Z/L*this.summary_
draw_height;J.fillStyle="black";J.fillRect(aa+W,this.summary_draw_height-am,b,am);if(this.prefs.show_counts&&J.measureText(Z).width<b){J.fillStyle="#bbb";J.textAlign="center";J.fillText(Z,aa+W+(b/2),this.summary_draw_height-5)}}e="Summary";s.append(q);return q}if(I.message){q.css({border:"solid red","border-width":"2px 2px 2px 0px"});J.fillStyle="red";J.textAlign="left";J.fillText(I.message,100+W,aw)}var ad=false;if(I.data){ad=true;for(var ar=0;ar<this.filters.length;ar++){if(!this.filters[ar].applies_to(I.data[0])){ad=false}}}if(ad){q.addClass(FILTERABLE_CLASS)}var at=I.data;var ao=0;for(var ap=0,H=at.length;ap<H;ap++){var S=at[ap],R=S[0],aq=S[1],ac=S[2],O=S[3];if(au[R]===undefined){continue}var ab=false;var U;for(var ar=0;ar<this.filters.length;ar++){U=this.filters[ar];U.update_attrs(S);if(!U.keep(S)){ab=true;break}}if(ab){continue}if(aq<=al&&ac>=N){var af=Math.floor(Math.max(0,(aq-N)*av)),K=Math.ceil(Math.min(a,Math.max(0,(ac-N)*av))),X=(r==="Dense"?1:(1+au[R]))*aw;var G,
aj,P=null,ax=null;if(I.dataset_type==="bai"){var v=S[4];J.fillStyle=l;if(S[5] instanceof Array){var E=Math.floor(Math.max(0,(S[5][0]-N)*av)),Q=Math.ceil(Math.min(a,Math.max(0,(S[5][1]-N)*av))),C=Math.floor(Math.max(0,(S[6][0]-N)*av)),w=Math.ceil(Math.min(a,Math.max(0,(S[6][1]-N)*av)));if(S[5][1]>=N&&S[5][0]<=al){this.rect_or_text(J,av,N,al,S[5][0],S[5][2],v,X)}if(S[6][1]>=N&&S[6][0]<=al){this.rect_or_text(J,av,N,al,S[6][0],S[6][2],v,X)}if(C>Q){J.fillStyle=CONNECTOR_COLOR;J.fillRect(Q+W,X+5,C-Q,1)}}else{J.fillStyle=l;this.rect_or_text(J,av,N,al,aq,O,v,X)}if(r!=="Dense"&&!ae&&aq>N){J.fillStyle=this.prefs.label_color;if(o===0&&af-J.measureText(O).width<0){J.textAlign="left";J.fillText(R,K+2+W,X+8)}else{J.textAlign="right";J.fillText(R,af-2+W,X+8)}J.fillStyle=l}}else{if(I.dataset_type==="interval_index"){if(ae){J.fillStyle=l;J.fillRect(af+W,X+5,K-af,1)}else{var F=S[4],V=S[5],ah=S[6],h=S[7];if(V&&ah){P=Math.floor(Math.max(0,(V-N)*av));ax=Math.ceil(Math.min(a,Math.max(0,(ah-N)*av)
))}if(r!=="Dense"&&O!==undefined&&aq>N){J.fillStyle=ai;if(o===0&&af-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+W,X+8)}else{J.textAlign="right";J.fillText(O,af-2+W,X+8)}J.fillStyle=l}if(h){if(F){if(F=="+"){J.fillStyle=RIGHT_STRAND}else{if(F=="-"){J.fillStyle=LEFT_STRAND}}J.fillRect(af+W,X,K-af,10);J.fillStyle=l}for(var an=0,g=h.length;an<g;an++){var u=h[an],d=Math.floor(Math.max(0,(u[0]-N)*av)),T=Math.ceil(Math.min(a,Math.max((u[1]-N)*av)));if(d>T){continue}G=5;aj=3;J.fillRect(d+W,X+aj,T-d,G);if(P!==undefined&&!(d>ax||T<P)){G=9;aj=1;var ak=Math.max(d,P),B=Math.min(T,ax);J.fillRect(ak+W,X+aj,B-ak,G)}}}else{G=9;aj=1;J.fillRect(af+W,X+aj,K-af,G);if(S.strand){if(S.strand=="+"){J.fillStyle=RIGHT_STRAND_INV}else{if(S.strand=="-"){J.fillStyle=LEFT_STRAND_INV}}J.fillRect(af+W,X,K-af,10);J.fillStyle=l}}}}else{if(I.dataset_type==="vcf"){if(ae){J.fillStyle=l;J.fillRect(af+W,X+5,K-af,1)}else{var t=S[4],n=S[5],c=S[6];G=9;aj=1;J.fillRect(af+W,X,K-af,G);if(r!=="Dense"&&O!
==undefined&&aq>N){J.fillStyle=ai;if(o===0&&af-J.measureText(O).width<0){J.textAlign="left";J.fillText(O,K+2+W,X+8)}else{J.textAlign="right";J.fillText(O,af-2+W,X+8)}J.fillStyle=l}var m=t+" / "+n;if(aq>N&&J.measureText(m).width<(K-af)){J.fillStyle="white";J.textAlign="center";J.fillText(m,W+af+(K-af)/2,X+8);J.fillStyle=l}}}}}ao++}}return q},gen_options:function(i){var a=$("<div />").addClass("form-row");var e="track_"+i+"_block_color",k=$("<label />").attr("for",e).text("Block color:"),l=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),j="track_"+i+"_label_color",g=$("<label />").attr("for",j).text("Text color:"),h=$("<input />").attr("id",j).attr("name",j).val(this.prefs.label_color),f="track_"+i+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(k).append(
l).append(g).append(h).append(d)},update_options:function(d){var b=$("#track_"+d+"_block_color").val(),c=$("#track_"+d+"_label_color").val(),a=$("#track_"+d+"_show_count").attr("checked");if(b!==this.prefs.block_color||c!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=c;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,e,c){FeatureTrack.call(this,d,b,a,e,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
+var DENSITY=200,FEATURE_LEVELS=10,MAX_FEATURE_DEPTH=50,CONNECTOR_COLOR="#ccc",DATA_ERROR="There was an error in indexing this dataset.",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",FILTERABLE_CLASS="filterable",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=5,CACHED_DATA=5,DUMMY_CANVAS=document.createElement("canvas"),RIGHT_STRAND,LEFT_STRAND;if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(DUMMY_CANVAS)}CONTEXT=DUMMY_CANVAS.getContext("2d");PX_PER_CHAR=CONTEXT.measureText("A").width;var right_img=new Image();right_img.src=image_path+"/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src=image_path+"/visualization/strand_left.png";left_img.onload=function(){LEFT_STRAND=CONTEXT.createPa
ttern(left_img,"repeat")};var right_img_inv=new Image();right_img_inv.src=image_path+"/visualization/strand_right_inv.png";right_img_inv.onload=function(){RIGHT_STRAND_INV=CONTEXT.createPattern(right_img_inv,"repeat")};var left_img_inv=new Image();left_img_inv.src=image_path+"/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function round_1000(a){return Math.round(a*1000)/1000}var Cache=function(a){this.num_elements=a;this.clear()};$.extend(Cache.prototype,{get:function(b){var a=this.key_ary.indexOf(b);if(a!=-1){this.key_ary.splice(a,1);this.key_ary.push(b)}return this.obj_cache[b]},set:function(b,c){if(!this.obj_cache[b]){if(this.key_ary.length>=this.num_elements){var a=this.key_ary.shift();delete this.obj_cache[a]}this.key_ary.push(b)}this.obj_cache[b]=c;return c},clear:function(){this.obj_cache={};this.key_ary=[]}});var View=function(a,d,c,b,e){this.container=a;this.vis_id=c;this.dbkey=b;this.
title=d;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_high=0;this.num_tracks=0;this.track_id_counter=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.init(e);this.reset()};$.extend(View.prototype,{init:function(d){var c=this.container,a=this;this.top_container=$("<div/>").addClass("top-container").appendTo(c);this.content_div=$("<div/>").addClass("content").css("position","relative").appendTo(c);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(c);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").addClass("viewport-container").appendTo(this.content_div);this.intro_div=$("<div/>").addClass("intro").text("Select a chrom from the dropdown below").hide();this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top
_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div />").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_form=$("<form/>").attr("action",function(){}).appendTo(this.nav_controls);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-a
utocomplete").append("<option value=''>Loading</option>").appendTo(this.chrom_form);var b=function(f){if(f.type==="focusout"||(f.keyCode||f.which)===13||(f.keyCode||f.which)===27){if((f.keyCode||f.which)!==27){a.go_to($(this).val())}$(this).hide();a.location_span.show();a.chrom_select.show();return false}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keypress focusout",b).appendTo(this.chrom_form);this.location_span=$("<span/>").addClass("location").appendTo(this.chrom_form);this.location_span.bind("click",function(){a.location_span.hide();a.chrom_select.hide();a.nav_input.css("display","inline-block");a.nav_input.select();a.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.chrom_form)}this.zo_link=$("<a id='zoom-out' />").click(function(){a.zoom_out();a.redraw()}).appendTo(this.chrom_form);this.zi_link=$("<a id='zoom-in' />").click(function(){a.zoom_in();a.redraw()}).append
To(this.chrom_form);$.ajax({url:chrom_url,data:(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}),dataType:"json",success:function(f){if(f.reference){a.add_label_track(new ReferenceTrack(a))}a.chrom_data=f.chrom_info;var j='<option value="">Select Chrom/Contig</option>';for(var h=0,e=a.chrom_data.length;h<e;h++){var g=a.chrom_data[h].chrom;j+='<option value="'+g+'">'+g+"</option>"}a.chrom_select.html(j);a.intro_div.show();a.chrom_select.bind("change",function(){a.change_chrom(a.chrom_select.val())});if(d){d()}},error:function(){alert("Could not load chroms for this dbkey:",a.dbkey)}});this.content_div.bind("dblclick",function(f){a.zoom_in(f.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(f){this.current_x=f.offsetX}).bind("drag",function(f){var h=f.offsetX-this.current_x;this.current_x=f.offsetX;var g=Math.round(h/a.viewport_container.width()*(a.max_high-a.max_low));a.move_delta(-g)});this.overview_close.bind("click",function(){for
(var f=0,e=a.tracks.length;f<e;f++){a.tracks[f].is_overview=false}$(this).siblings().filter("canvas").remove();$(this).parent().css("height",a.overview_box.height());a.overview_highlight.hide();$(this).hide()});this.viewport_container.bind("dragstart",function(f){this.original_low=a.low;this.current_height=f.clientY;this.current_x=f.offsetX;this.enable_pan=(f.clientX<a.viewport_container.width()-16)?true:false}).bind("drag",function(h){if(!this.enable_pan||this.in_reordering){return}var f=$(this);var j=h.offsetX-this.current_x;var g=f.scrollTop()-(h.clientY-this.current_height);f.scrollTop(g);this.current_height=h.clientY;this.current_x=h.offsetX;var i=Math.round(j/a.viewport_container.width()*(a.high-a.low));a.move_delta(i)});this.top_labeltrack.bind("dragstart",function(f){this.drag_origin_x=f.clientX;this.drag_origin_pos=f.clientX/a.viewport_container.width()*(a.high-a.low)+a.low;this.drag_div=$("<div />").css({height:a.content_div.height()+a.top_labeltrack.height()+a.nav
_labeltrack.height(),top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(j){var g=Math.min(j.clientX,this.drag_origin_x)-a.container.offset().left,f=Math.max(j.clientX,this.drag_origin_x)-a.container.offset().left,i=(a.high-a.low),h=a.viewport_container.width();a.update_location(Math.round(g/h*i)+a.low,Math.round(f/h*i)+a.low);this.drag_div.css({left:g+"px",width:(f-g)+"px"})}).bind("dragend",function(k){var g=Math.min(k.clientX,this.drag_origin_x),f=Math.max(k.clientX,this.drag_origin_x),i=(a.high-a.low),h=a.viewport_container.width(),j=a.low;a.low=Math.round(g/h*i)+j;a.high=Math.round(f/h*i)+j;this.drag_div.remove();a.redraw()});this.add_label_track(new LabelTrack(this,this.top_labeltrack));this.add_label_track(new LabelTrack(this,this.nav_labeltrack));$(window).bind("resize",function(){a.resize_window()});$(document).bind("redraw",function(){a.redraw()});this.reset();$(window).trigger("resize")},upd
ate_location:function(a,b){this.location_span.text(commatize(a)+" - "+commatize(b));this.nav_input.val(this.chrom+":"+commatize(a)+"-"+commatize(b))},change_chrom:function(e,b,g){var d=this;var f=$.grep(d.chrom_data,function(j,k){return j.chrom===e})[0];if(f===undefined){return}if(e!==d.chrom){d.chrom=e;if(!d.chrom){d.intro_div.show()}else{d.intro_div.hide()}d.chrom_select.val(d.chrom);d.max_high=f.len;d.reset();d.redraw(true);for(var h=0,a=d.tracks.length;h<a;h++){var c=d.tracks[h];if(c.init){c.init()}}}if(b!==undefined&&g!==undefined){d.low=Math.max(b,0);d.high=Math.min(g,d.max_high)}d.reset_overview();d.redraw()},go_to:function(f){var j=this,a,d,b=f.split(":"),h=b[0],i=b[1];if(i!==undefined){try{var g=i.split("-");a=parseInt(g[0].replace(/,/g,""),10);d=parseInt(g[1].replace(/,/g,""),10)}catch(c){return false}}j.change_chrom(h,a,d)},move_fraction:function(c){var a=this;var b=a.high-a.low;this.move_delta(c*b)},move_delta:function(c){var a=this;var b=a.high-a.low;if(a.low-c<
a.max_low){a.low=a.max_low;a.high=a.max_low+b}else{if(a.high-c>a.max_high){a.high=a.max_high;a.low=a.max_high-b}else{a.high-=c;a.low-=c}}a.redraw()},add_track:function(a){a.view=this;a.track_id=this.track_id_counter;this.tracks.push(a);if(a.init){a.init()}a.container_div.attr("id","track_"+a.track_id);this.track_id_counter+=1;this.num_tracks+=1},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){this.has_changes=true;a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[this.tracks.indexOf(a)];this.num_tracks-=1},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},redraw:function(h){var g=this.high-this.low,f=this.low,b=this.high;if(f<this.max_low){f=this.max_low}if(b>this.max_high){b=this.max_high}if(this.high!==0&&g<this.min_separation){b=f+this.min_separation}this.low=Math.floor(f);this.high=Math.ceil(b);this.resolution=Math.pow(10,Math.ceil(
Math.log((this.high-this.low)/200)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.max(0,Math.ceil(Math.log(this.resolution,FEATURE_LEVELS)/Math.log(FEATURE_LEVELS))));var a=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var e=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var j=13;this.overview_box.css({left:a,width:Math.max(j,e)}).show();if(e<j){this.overview_box.css("left",a-(j-e)/2)}if(this.overview_highlight){this.overview_highlight.css({left:a,width:e})}this.update_location(this.low,this.high);if(!h){for(var c=0,d=this.tracks.length;c<d;c++){if(this.tracks[c]&&this.tracks[c].enabled){this.tracks[c].draw()}}for(c=0,d=this.label_tracks.length;c<d;c++){this.label_tracks[c].draw()}}},zoom_in:function(b,c){if(this.max_high===0||this.high-this.low<this.min_separation){return}var d=this.high-this.low,e=d/2+this.low,a=(d/this.zoom_factor)/2;if(b){e=b/this.viewport_container.width()*(this.high-this.low)+th
is.low}this.low=Math.round(e-a);this.high=Math.round(e+a);this.redraw()},zoom_out:function(){if(this.max_high===0){return}var b=this.high-this.low,c=b/2+this.low,a=(b*this.zoom_factor)/2;this.low=Math.round(c-a);this.high=Math.round(c+a);this.redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.redraw()},reset_overview:function(){this.overview_viewport.find("canvas").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide()}});var Filter=function(b,a,c){this.name=b;this.index=a;this.value=c};var NumberFilter=function(b,a){this.name=b;this.index=a;this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.slider_min=Number.MAX_VALUE;this.slider_max=-Number.MAX_VALUE;this.slider=null;this.slider_label=null}
;$.extend(NumberFilter.prototype,{applies_to:function(a){if(a.length>this.index){return true}return false},keep:function(a){if(!this.applies_to(a)){return true}return(a[this.index]>=this.low&&a[this.index]<=this.high)},update_attrs:function(b){var a=false;if(!this.applies_to(b)){return a}if(b[this.index]<this.slider_min){this.slider_min=b[this.index];a=true}if(b[this.index]>this.slider_max){this.slider_max=b[this.index];a=false}return a},update_ui_elt:function(){var b=this.slider.slider("option","min"),a=this.slider.slider("option","max");if(this.slider_min<b||this.slider_max>a){this.slider.slider("option","min",this.slider_min);this.slider.slider("option","max",this.slider_max);this.slider.slider("option","values",[this.slider_min,this.slider_max])}}});var get_filters=function(a){var g=[];for(var d=0;d<a.length;d++){var f=a[d];var c=f.name,e=f.type,b=f.index;if(e=="int"||e=="float"){g[d]=new NumberFilter(c,b)}else{g[d]=new Filter(c,b,e)}}return g};var Track=function(b,a,d,c
){this.name=b;this.view=a;this.parent_element=d;this.filters=(c!==undefined?get_filters(c):[]);this.init_global()};$.extend(Track.prototype,{init_global:function(){this.container_div=$("<div />").addClass("track").css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div class='draghandle' />").appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.filtering_div=$("<div class='track-filters'>").appendTo(this.container_div);this.filtering_div.hide();this.filtering_div.bind("drag",function(i){i.stopPropagation()});var b=$("<table class='filters'>").appendTo(this.filtering_div);var c=this;for(var e=0;e<this.filters.length;e++){var a=this.filters[e];var f=$("<tr>").appendTo(b);var g=$("<th cla
ss='filter-info'>").appendTo(f);var j=$("<span class='name'>").appendTo(g);j.text(a.name+" ");var d=$("<span class='values'>").appendTo(g);var h=$("<td>").appendTo(f);a.control_element=$("<div id='"+a.name+"-filter-control' style='width: 200px; position: relative'>").appendTo(h);a.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(k,l){var i=l.values;d.text("["+i[0]+"-"+i[1]+"]");a.low=i[0];a.high=i[1];c.draw(true)},change:function(i,k){a.control_element.slider("option","slide").call(a.control_element,i,k)}});a.slider=a.control_element;a.slider_label=d}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.initial_canvas=undefined;a.content_div.css("height","auto");if(!a.content_div.text()){a.content_div.text(DATA_LOADING)}a.container_div.r
emoveClass("nodata error pending");if(a.view.chrom){$.getJSON(data_url,c,function(d){if(!d||d==="error"||d.kind==="error"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR);if(d.message){var f=a.view.tracks.indexOf(a);var e=$("<a href='javascript:void(0);'></a>").attr("id",f+"_error");e.text("Click to view error");$("#"+f+"_error").live("click",function(){show_modal("Trackster Error","<pre>"+d.message+"</pre>",{Close:hide_modal})});a.content_div.append(e)}}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NOCONVERTER)}else{if(d.data!==undefined&&(d.data===null||d.data.length===0)){a.container_div.addClass("nodata");a.content_div.text(DATA_NONE)}else{if(d==="pending"){a.container_div.addClass("pending");a.content_div.text(DATA_PENDING);setTimeout(function(){a.init()},5000)}else{a.content_div.text("");a.content_div.css("height",a.height_px+"px");a.enabled=true;b(d);a.draw()}}}}})}else{a.container_div.addClass("nodata");a.conte
nt_div.text(DATA_NONE)}}});var TiledTrack=function(){var b=this,j=b.view;if(b.hidden){return}if(b.display_modes!==undefined){if(b.mode_div===undefined){b.mode_div=$("<div class='right-float menubutton popup' />").appendTo(b.header_div);var e=b.display_modes[0];b.mode=e;b.mode_div.text(e);var c=function(i){b.mode_div.text(i);b.mode=i;b.tile_cache.clear();b.draw()};var a={};for(var f=0,h=b.display_modes.length;f<h;f++){var g=b.display_modes[f];a[g]=function(i){return function(){c(i)}}(g)}make_popupmenu(b.mode_div,a)}else{b.mode_div.hide()}}var d={};d["Set as overview"]=function(){j.overview_viewport.find("canvas").remove();b.is_overview=true;b.set_overview();for(var i in j.tracks){if(j.tracks[i]!==b){j.tracks[i].is_overview=false}}};d["Edit configuration"]=function(){var l=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},i=function(){b.update_options(b.track_id);hide_modal();$(window).unbind("keypress.check_enter_esc")},k=function(m){if((m.keyCode||m.which
)===27){l()}else{if((m.keyCode||m.which)===13){i()}}};$(window).bind("keypress.check_enter_esc",k);show_modal("Configure Track",b.gen_options(b.track_id),{Cancel:l,OK:i})};if(b.filters.length>0){d["Show filters"]=function(){var i;if(!b.filtering_div.is(":visible")){i="Hide filters";b.filters_visible=true}else{i="Show filters";b.filters_visible=false}$("#"+b.name_div.attr("id")+"-menu").find("li").eq(2).text(i);b.filtering_div.toggle()}}d.Remove=function(){j.remove_track(b);if(j.num_tracks===0){$("#no-tracks").show()}};b.popup_menu=make_popupmenu(b.name_div,d);show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false)};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(a){var k=this.view.low,g=this.view.high,h=g-k,f=this.view.resolution;var n=$("<div style='position: relative;'></div>"),o=this.content_div.width()/h;this.content_div.append(n);this.max_height=0;var b=Math.floor(k/f/DENSITY);var j={};while((b*DENSITY*f)<g){var l=this.content_div.width()+"_"+
o+"_"+b;var e=this.tile_cache.get(l);if(!a&&e){var i=b*DENSITY*f;var d=(i-k)*o;if(this.left_offset){d-=this.left_offset}e.css({left:d});this.show_tile(e,n)}else{this.delayed_draw(this,l,k,g,b,f,n,o,j)}b+=1}var c=this;var m=setInterval(function(){if(obj_length(j)===0){if(c.content_div.children().length>1){c.content_div.children(":first").remove()}for(var p=0;p<c.filters.length;p++){c.filters[p].update_ui_elt()}clearInterval(m)}},50)},delayed_draw:function(c,h,g,e,b,d,i,j,f){var a=setTimeout(function(){if(g<=c.view.high&&e>=c.view.low){var k=c.draw_tile(d,b,i,j);if(k){if(!c.initial_canvas&&!window.G_vmlCanvasManager){c.initial_canvas=$(k).clone();var n=k.get(0).getContext("2d");var l=c.initial_canvas.get(0).getContext("2d");var m=n.getImageData(0,0,n.canvas.width,n.canvas.height);l.putImageData(m,0,0);c.set_overview()}c.tile_cache.set(h,k);c.show_tile(k,i)}}delete f[a]},50);f[a]=true},show_tile:function(a,c){var b=this;c.append(a);b.max_height=Math.max(b.max_height,a.height())
;b.content_div.css("height",b.max_height+"px");if(a.hasClass(FILTERABLE_CLASS)){show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters");if(b.filters_visible){b.filtering_div.show()}}else{show_hide_popupmenu_options(b.popup_menu,"(Show|Hide) filters",false);b.filtering_div.hide()}},set_overview:function(){var a=this.view;if(this.initial_canvas&&this.is_overview){a.overview_close.show();a.overview_viewport.append(this.initial_canvas);a.overview_highlight.show().height(this.initial_canvas.height());a.overview_viewport.height(this.initial_canvas.height()+a.overview_box.height())}$(window).trigger("resize")}});var LabelTrack=function(a,b){this.track_type="LabelTrack";this.hidden=true;Track.call(this,null,a,b);this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div styl
e='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var ReferenceTrack=function(a){this.track_type="ReferenceTrack";this.hidden=true;Track.call(this,null,a,a.top_labeltrack);TiledTrack.call(this);this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.data_queue={};this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE)};$.extend(ReferenceTrack.prototype,TiledTrack.prototype,{get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:reference_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dbkey:this.view.dbkey},success:function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})
}},draw_tile:function(f,b,k,o){var g=b*DENSITY*f,d=DENSITY*f,j=f+"_"+b;var e=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(e)}e=$(e);var n=e.get(0).getContext("2d");if(o>PX_PER_CHAR){if(this.data_cache.get(j)===undefined){this.get_data(f,b);return}var m=this.data_cache.get(j);if(m===null){this.content_div.css("height","0px");return}e.get(0).width=Math.ceil(d*o+this.left_offset);e.get(0).height=this.height_px;e.css({position:"absolute",top:0,left:(g-this.view.low)*o-this.left_offset});for(var h=0,l=m.length;h<l;h++){var a=Math.round(h*o),i=Math.round(o/2);n.fillText(m[h],a+this.left_offset+i,10)}k.append(e);return e}this.content_div.css("height","0px")}});var LineTrack=function(d,b,a,c){this.track_type="LineTrack";this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";Track.call(this,d,b,b.viewport_container);TiledTrack.call(this);this.height_px=80;this.dataset_id=a;this.data_cache=new Cache(CACHED_DA
TA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={color:"black",min_value:undefined,max_value:undefined,mode:this.mode}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(c){a.container_div.addClass("line-track");var e=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=e.min;a.prefs.max_value=e.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=e.total_frequency;a.container_div.find(".yaxislabel").remove();var f=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(round_1000(a.prefs.min_value));var d=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(round_1000(a.pref
s.max_value));d.css({position:"absolute",top:"24px",left:"10px"});d.prependTo(a.container_div);f.css({position:"absolute",top:a.height_px+12+"px",left:"10px"});f.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){var h=g.data;c.data_cache.set(e,h);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(o,r,c,e){if(this.vertical_range===undefined){return}var s=r*DENSITY*o,a=DENSITY*o,w=o+"_"+r;var b=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(b)}b=$(b);if(this.data_cache.get(w)===undefined){this.get_data(o,r);return}var v=this.data_cache.get(w);if(!v){return}b.css({position:"absolute",top:0,left:(s-this.view.low)*e});b.get(0).width=Mat
h.ceil(a*e);b.get(0).height=this.height_px;var n=b.get(0).getContext("2d"),j=false,k=this.prefs.min_value,g=this.prefs.max_value,m=this.vertical_range,t=this.total_frequency,d=this.height_px,l=this.mode;n.beginPath();n.fillStyle=this.prefs.color;var u,h,f;if(v.length>1){f=Math.ceil((v[1][0]-v[0][0])*e)}else{f=10}for(var p=0,q=v.length;p<q;p++){u=Math.round((v[p][0]-s)*e);h=v[p][1];if(h===null){if(j&&l==="Filled"){n.lineTo(u,d)}j=false;continue}if(h<k){h=k}else{if(h>g){h=g}}if(l==="Histogram"){h=Math.round(d-(h-k)/m*d);n.fillRect(u,h,f,d-h)}else{if(l==="Intensity"){h=255-Math.floor((h-k)/m*255);n.fillStyle="rgb("+h+","+h+","+h+")";n.fillRect(u,0,f,d)}else{h=Math.round(d-(h-k)/m*d);if(j){n.lineTo(u,h)}else{j=true;if(l==="Filled"){n.moveTo(u,d);n.lineTo(u,h)}else{n.moveTo(u,h)}}}}}if(l==="Filled"){if(j){n.lineTo(u,d)}n.fill()}else{n.stroke()}c.append(b);return b},gen_options:function(m){var a=$("<div />").addClass("form-row");var e="track_"+m+"_color",b=$("<label />").attr("for
",e).text("Color:"),c=$("<input />").attr("id",e).attr("name",e).val(this.prefs.color),h="track_"+m+"_minval",l=$("<label></label>").attr("for",h).text("Min value:"),d=(this.prefs.min_value===undefined?"":this.prefs.min_value),k=$("<input></input>").attr("id",h).val(d),j="track_"+m+"_maxval",g=$("<label></label>").attr("for",j).text("Max value:"),i=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",j).val(i);return a.append(l).append(k).append(g).append(f).append(b).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_color").val();if(a!==this.prefs.min_value||c!==this.prefs.max_value||b!==this.prefs.color){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(c);this.prefs.color=b;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_valu
e);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(d,b,a,e,c){this.track_type="FeatureTrack";this.display_modes=["Auto","Dense","Squish","Pack"];Track.call(this,d,b,b.viewport_container,e);TiledTrack.call(this);this.height_px=0;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.summary_draw_height=30;this.default_font="9px Monaco, Lucida Console, monospace";this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.left_offset=200;this.prefs={block_color:"#444",label_color:"black",show_counts:true}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b="initial";this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution,mode:a.mode},fun
ction(c){a.mode_div.show();a.data_cache.set(b,c);a.draw()})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,resolution:this.view.resolution,mode:this.mode},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,g,b,q){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=a;this.inc_slots[a].mode=q;this.s_e_by_tile[a]={}}var m=this.inc_slots[a].w_scale,y=[],h=0,n=this.view.max_low;var A=[];if(this.inc_slots[a].mode!==q){delete this.inc_slots[a];this.inc_slots[a]={mode:q,w_scale:m};delete this.s_e_by_tile[a];this.s_e_by_tile[a]={}}for(var v=0,w=g.length;v<w;v++){var f=g[v],l=f[0];if(this.inc_slots[a][l]!==undefined){h=Math.max(h,this.inc_slots[a][l]);A.push(this.inc_slots[a][l])}else{y.push(v)}}for(var v=0,w=y.length;v<w;v++){var f=g[y[v]],l=f[0],r=f[1],c=f[2],p=f[3],d=Math.floor((r-n)*m),e=Math.ceil((c-n
)*m);if(p!==undefined&&!b){var s=CONTEXT.measureText(p).width;if(d-s<0){e+=s}else{d-=s}}var u=0;while(u<=MAX_FEATURE_DEPTH){var o=true;if(this.s_e_by_tile[a][u]!==undefined){for(var t=0,z=this.s_e_by_tile[a][u].length;t<z;t++){var x=this.s_e_by_tile[a][u][t];if(e>x[0]&&d<x[1]){o=false;break}}}if(o){if(this.s_e_by_tile[a][u]===undefined){this.s_e_by_tile[a][u]=[]}this.s_e_by_tile[a][u].push([d,e]);this.inc_slots[a][l]=u;h=Math.max(h,u);break}u++}}return h},rect_or_text:function(r,l,t,b,q,f,i,e){r.textAlign="center";var k=0,p=Math.round(l/2);for(var m=0,s=i.length;m<s;m++){var j=i[m],d="MIDNSHP"[j[0]],n=j[1];if(d==="H"||d==="S"){k-=n}var g=q+k,w=Math.floor(Math.max(0,(g-t)*l)),h=Math.floor(Math.max(0,(g+n-t)*l));switch(d){case"S":case"H":case"M":var o=f.slice(k,n);if((this.mode==="Pack"||this.mode==="Auto")&&f!==undefined&&l>PX_PER_CHAR){r.fillStyle=this.prefs.block_color;r.fillRect(w+this.left_offset,e+1,h-w,9);r.fillStyle=CONNECTOR_COLOR;for(var u=0,a=o.length;u<a;u++){if(g+
u>=t&&g+u<=b){var v=Math.floor(Math.max(0,(g+u-t)*l));r.fillText(o[u],v+this.left_offset+p,e+9)}}}else{r.fillStyle=this.prefs.block_color;r.fillRect(w+this.left_offset,e+4,h-w,3)}break;case"N":r.fillStyle=CONNECTOR_COLOR;r.fillRect(w+this.left_offset,e+5,h-w,1);break;case"D":r.fillStyle="red";r.fillRect(w+this.left_offset,e+4,h-w,3);break;case"P":case"I":break}k+=n}},draw_tile:function(ag,o,s,av){var N=o*DENSITY*ag,al=(o+1)*DENSITY*ag,M=al-N;var an=(!this.initial_canvas?"initial":N+"_"+al);var I=this.data_cache.get(an);var e;if(I===undefined||(this.mode!=="Auto"&&I.dataset_type==="summary_tree")){this.data_queue[[N,al]]=true;this.get_data(N,al);return}var a=Math.ceil(M*av),ai=this.prefs.label_color,l=this.prefs.block_color,r=this.mode,z=25,ae=(r==="Squish")||(r==="Dense")&&(r!=="Pack")||(r==="Auto"&&(I.extra_info==="no_detail")),W=this.left_offset,au,D,aw;var q=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(q)}q=$(q);if(I.datase
t_type==="summary_tree"){D=this.summary_draw_height}else{if(r==="Dense"){D=z;aw=10}else{aw=(ae?this.vertical_nodetail_px:this.vertical_detail_px);var A=(av<0.0001?1/this.view.zoom_res:av);D=this.incremental_slots(A,I.data,ae,r)*aw+z;au=this.inc_slots[A]}}q.css({position:"absolute",top:0,left:(N-this.view.low)*av-W});q.get(0).width=a+W;q.get(0).height=D;s.parent().css("height",Math.max(this.height_px,D)+"px");var J=q.get(0).getContext("2d");J.fillStyle=l;J.font=this.default_font;J.textAlign="right";this.container_div.find(".yaxislabel").remove();if(I.dataset_type=="summary_tree"){var Y=I.data,L=I.max,b=Math.ceil(I.delta*av);var p=$("<div />").addClass("yaxislabel").text(L);p.css({position:"absolute",top:"22px",left:"10px"});p.prependTo(this.container_div);for(var ap=0,H=Y.length;ap<H;ap++){var aa=Math.floor((Y[ap][0]-N)*av);var Z=Y[ap][1];if(!Z){continue}var am=Z/L*this.summary_draw_height;J.fillStyle="black";J.fillRect(aa+W,this.summary_draw_height-am,b,am);if(this.prefs.sho
w_counts&&J.measureText(Z).width<b){J.fillStyle="#bbb";J.textAlign="center";J.fillText(Z,aa+W+(b/2),this.summary_draw_height-5)}}e="Summary";s.append(q);return q}if(I.message){q.css({border:"solid red","border-width":"2px 2px 2px 0px"});J.fillStyle="red";J.textAlign="left";J.fillText(I.message,100+W,aw)}var ad=false;if(I.data){ad=true;for(var ar=0;ar<this.filters.length;ar++){if(!this.filters[ar].applies_to(I.data[0])){ad=false}}}if(ad){q.addClass(FILTERABLE_CLASS)}var at=I.data;var ao=0;for(var ap=0,H=at.length;ap<H;ap++){var S=at[ap],R=S[0],aq=S[1],ac=S[2],O=S[3];if(au[R]===undefined){continue}var ab=false;var U;for(var ar=0;ar<this.filters.length;ar++){U=this.filters[ar];U.update_attrs(S);if(!U.keep(S)){ab=true;break}}if(ab){continue}if(aq<=al&&ac>=N){var af=Math.floor(Math.max(0,(aq-N)*av)),K=Math.ceil(Math.min(a,Math.max(0,(ac-N)*av))),X=(r==="Dense"?1:(1+au[R]))*aw;var G,aj,P=null,ax=null;if(I.dataset_type==="bai"){var v=S[4];J.fillStyle=l;if(S[5] instanceof Array){var
E=Math.floor(Math.max(0,(S[5][0]-N)*av)),Q=Math.ceil(Math.min(a,Math.max(0,(S[5][1]-N)*av))),C=Math.floor(Math.max(0,(S[6][0]-N)*av)),w=Math.ceil(Math.min(a,Math.max(0,(S[6][1]-N)*av)));if(S[5][1]>=N&&S[5][0]<=al){this.rect_or_text(J,av,N,al,S[5][0],S[5][2],v,X)}if(S[6][1]>=N&&S[6][0]<=al){this.rect_or_text(J,av,N,al,S[6][0],S[6][2],v,X)}if(C>Q){J.fillStyle=CONNECTOR_COLOR;J.fillRect(Q+W,X+5,C-Q,1)}}else{J.fillStyle=l;this.rect_or_text(J,av,N,al,aq,O,v,X)}if(r!=="Dense"&&!ae&&aq>N){J.fillStyle=this.prefs.label_color;if(o===0&&af-J.measureText(O).width<0){J.textAlign="left";J.fillText(R,K+2+W,X+8)}else{J.textAlign="right";J.fillText(R,af-2+W,X+8)}J.fillStyle=l}}else{if(I.dataset_type==="interval_index"){if(ae){J.fillStyle=l;J.fillRect(af+W,X+5,K-af,1)}else{var F=S[4],V=S[5],ah=S[6],h=S[7];if(V&&ah){P=Math.floor(Math.max(0,(V-N)*av));ax=Math.ceil(Math.min(a,Math.max(0,(ah-N)*av)))}if(r!=="Dense"&&O!==undefined&&aq>N){J.fillStyle=ai;if(o===0&&af-J.measureText(O).width<0){J.tex
tAlign="left";J.fillText(O,K+2+W,X+8)}else{J.textAlign="right";J.fillText(O,af-2+W,X+8)}J.fillStyle=l}if(h){if(F){if(F=="+"){J.fillStyle=RIGHT_STRAND}else{if(F=="-"){J.fillStyle=LEFT_STRAND}}J.fillRect(af+W,X,K-af,10);J.fillStyle=l}for(var an=0,g=h.length;an<g;an++){var u=h[an],d=Math.floor(Math.max(0,(u[0]-N)*av)),T=Math.ceil(Math.min(a,Math.max((u[1]-N)*av)));if(d>T){continue}G=5;aj=3;J.fillRect(d+W,X+aj,T-d,G);if(P!==undefined&&!(d>ax||T<P)){G=9;aj=1;var ak=Math.max(d,P),B=Math.min(T,ax);J.fillRect(ak+W,X+aj,B-ak,G)}}}else{G=9;aj=1;J.fillRect(af+W,X+aj,K-af,G);if(S.strand){if(S.strand=="+"){J.fillStyle=RIGHT_STRAND_INV}else{if(S.strand=="-"){J.fillStyle=LEFT_STRAND_INV}}J.fillRect(af+W,X,K-af,10);J.fillStyle=l}}}}else{if(I.dataset_type==="vcf"){if(ae){J.fillStyle=l;J.fillRect(af+W,X+5,K-af,1)}else{var t=S[4],n=S[5],c=S[6];G=9;aj=1;J.fillRect(af+W,X,K-af,G);if(r!=="Dense"&&O!==undefined&&aq>N){J.fillStyle=ai;if(o===0&&af-J.measureText(O).width<0){J.textAlign="left";J.fillT
ext(O,K+2+W,X+8)}else{J.textAlign="right";J.fillText(O,af-2+W,X+8)}J.fillStyle=l}var m=t+" / "+n;if(aq>N&&J.measureText(m).width<(K-af)){J.fillStyle="white";J.textAlign="center";J.fillText(m,W+af+(K-af)/2,X+8);J.fillStyle=l}}}}}ao++}}return q},gen_options:function(i){var a=$("<div />").addClass("form-row");var e="track_"+i+"_block_color",k=$("<label />").attr("for",e).text("Block color:"),l=$("<input />").attr("id",e).attr("name",e).val(this.prefs.block_color),j="track_"+i+"_label_color",g=$("<label />").attr("for",j).text("Text color:"),h=$("<input />").attr("id",j).attr("name",j).val(this.prefs.label_color),f="track_"+i+"_show_count",c=$("<label />").attr("for",f).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",f).attr("name",f).attr("checked",this.prefs.show_counts),d=$("<div />").append(b).append(c);return a.append(k).append(l).append(g).append(h).append(d)},update_options:function(d){var b=$("#track_"+d+"_block_color").va
l(),c=$("#track_"+d+"_label_color").val(),a=$("#track_"+d+"_show_count").attr("checked");if(b!==this.prefs.block_color||c!==this.prefs.label_color||a!==this.prefs.show_counts){this.prefs.block_color=b;this.prefs.label_color=c;this.prefs.show_counts=a;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(d,b,a,e,c){FeatureTrack.call(this,d,b,a,e,c);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
1
0

galaxy-dist commit 2b8161827380: Move gff_util.py from galaxy/tools/util to galaxy/datatypes/util because gff_utils are now used by the framework as well as tools.
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1289752184 18000
# Node ID 2b81618273808135efd9409f953161481944fec2
# Parent 98009db17cb2b21db626fc9c185a8fd22109a4cd
Move gff_util.py from galaxy/tools/util to galaxy/datatypes/util because gff_utils are now used by the framework as well as tools.
--- a/tools/new_operations/gops_subtract.py
+++ b/tools/new_operations/gops_subtract.py
@@ -21,7 +21,7 @@ from bx.intervals.io import *
from bx.intervals.operations.subtract import *
from bx.cookbook import doc_optparse
from galaxy.tools.util.galaxyops import *
-from galaxy.tools.util.gff_util import *
+from galaxy.datatypes.util.gff_util import *
assert sys.version_info[:2] >= ( 2, 4 )
--- a/tools/new_operations/gops_intersect.py
+++ b/tools/new_operations/gops_intersect.py
@@ -21,7 +21,7 @@ from bx.intervals.io import *
from bx.intervals.operations.intersect import *
from bx.cookbook import doc_optparse
from galaxy.tools.util.galaxyops import *
-from galaxy.tools.util.gff_util import *
+from galaxy.datatypes.util.gff_util import *
assert sys.version_info[:2] >= ( 2, 4 )
--- a/tools/extract/extract_genomic_dna.py
+++ b/tools/extract/extract_genomic_dna.py
@@ -15,7 +15,7 @@ from bx.cookbook import doc_optparse
import bx.seq.nib
import bx.seq.twobit
from galaxy.tools.util.galaxyops import *
-from galaxy.tools.util.gff_util import *
+from galaxy.datatypes.util.gff_util import *
assert sys.version_info[:2] >= ( 2, 4 )
--- a/lib/galaxy/datatypes/converters/interval_to_interval_index_converter.py
+++ b/lib/galaxy/datatypes/converters/interval_to_interval_index_converter.py
@@ -14,7 +14,7 @@ from galaxy import eggs
import pkg_resources; pkg_resources.require( "bx-python" )
from galaxy.visualization.tracks.summary import *
from bx.cookbook import doc_optparse
-from galaxy.tools.util.gff_util import convert_gff_coords_to_bed
+from galaxy.datatypes.util.gff_util import convert_gff_coords_to_bed
from bx.interval_index_file import Indexes
def main():
--- a/tools/filters/gff/gff_filter_by_feature_count.py
+++ b/tools/filters/gff/gff_filter_by_feature_count.py
@@ -7,7 +7,7 @@ Usage:
"""
import sys
from galaxy import eggs
-from galaxy.tools.util.gff_util import parse_gff_attributes
+from galaxy.datatypes.util.gff_util import parse_gff_attributes
assert sys.version_info[:2] >= ( 2, 4 )
--- a/tools/filters/gff_to_bed_converter.py
+++ b/tools/filters/gff_to_bed_converter.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
import sys
from galaxy import eggs
-from galaxy.tools.util.gff_util import parse_gff_attributes
+from galaxy.datatypes.util.gff_util import parse_gff_attributes
assert sys.version_info[:2] >= ( 2, 4 )
--- /dev/null
+++ b/lib/galaxy/datatypes/util/gff_util.py
@@ -0,0 +1,226 @@
+"""
+Provides utilities for working with GFF files.
+"""
+
+from bx.intervals.io import *
+
+class GFFInterval( GenomicInterval ):
+ """
+ A GFF interval, including attributes. If file is strictly a GFF file,
+ only attribute is 'group.'
+ """
+ def __init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, default_strand, \
+ fix_strand=False, raw_line='' ):
+ GenomicInterval.__init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, \
+ default_strand, fix_strand=fix_strand )
+ self.raw_line = raw_line
+ self.attributes = parse_gff_attributes( fields[8] )
+
+class GFFFeature( GenomicInterval ):
+ """
+ A GFF feature, which can include multiple intervals.
+ """
+ def __init__( self, reader, chrom_col, start_col, end_col, strand_col, default_strand, \
+ fix_strand=False, intervals=[] ):
+ GenomicInterval.__init__( self, reader, intervals[0].fields, chrom_col, start_col, end_col, \
+ strand_col, default_strand, fix_strand=fix_strand )
+ self.intervals = intervals
+ # Use intervals to set feature attributes.
+ for interval in self.intervals:
+ # Error checking.
+ if interval.chrom != self.chrom:
+ raise ValueError( "interval chrom does not match self chrom: %i != %i" % \
+ ( interval.chrom, self.chrom ) )
+ if interval.strand != self.strand:
+ raise ValueError( "interval strand does not match self strand: %s != %s" % \
+ ( interval.strand, self.strand ) )
+ # Set start, end of interval.
+ if interval.start < self.start:
+ self.start = interval.start
+ if interval.end > self.end:
+ self.end = interval.end
+
+class GFFIntervalToBEDReaderWrapper( NiceReaderWrapper ):
+ """
+ Reader wrapper that reads GFF intervals/lines and automatically converts
+ them to BED format.
+ """
+
+ def parse_row( self, line ):
+ # HACK: this should return a GFF interval, but bx-python operations
+ # require GenomicInterval objects and subclasses will not work.
+ interval = GenomicInterval( self, line.split( "\t" ), self.chrom_col, self.start_col, \
+ self.end_col, self.strand_col, self.default_strand, \
+ fix_strand=self.fix_strand )
+ interval = convert_gff_coords_to_bed( interval )
+ return interval
+
+class GFFReaderWrapper( NiceReaderWrapper ):
+ """
+ Reader wrapper for GFF files.
+
+ Wrapper has two major functions:
+ (1) group entries for GFF file (via group column), GFF3 (via id attribute ),
+ or GTF (via gene_id/transcript id);
+ (2) convert coordinates from GFF format--starting and ending coordinates
+ are 1-based, closed--to the 'traditional'/BED interval format--0 based,
+ half-open. This is useful when using GFF files as inputs to tools that
+ expect traditional interval format.
+ """
+
+ def __init__( self, reader, **kwargs ):
+ """
+ Create wrapper. Defaults are group_entries=False and
+ convert_coords_to_bed=True to support backward compatibility.
+ """
+ NiceReaderWrapper.__init__( self, reader, **kwargs )
+ self.group_entries = kwargs.get( 'group_entries', False )
+ self.convert_coords_to_bed = kwargs.get( 'convert_coords_to_bed', True )
+ self.last_line = None
+ self.cur_offset = 0
+ self.seed_interval = None
+
+ def parse_row( self, line ):
+ interval = GFFInterval( self, line.split( "\t" ), self.chrom_col, self.start_col, \
+ self.end_col, self.strand_col, self.default_strand, \
+ fix_strand=self.fix_strand, raw_line=line )
+ if self.convert_coords_to_bed:
+ interval = convert_gff_coords_to_bed( interval )
+ return interval
+
+ def next( self ):
+ """ Returns next GFFFeature. """
+
+ #
+ # Helper function.
+ #
+
+ def handle_parse_error( parse_error ):
+ """ Actions to take when ParseError found. """
+ if self.outstream:
+ if self.print_delegate and hasattr(self.print_delegate,"__call__"):
+ self.print_delegate( self.outstream, e, self )
+ self.skipped += 1
+ # no reason to stuff an entire bad file into memmory
+ if self.skipped < 10:
+ self.skipped_lines.append( ( self.linenum, self.current_line, str( e ) ) )
+
+ #
+ # Get next GFFFeature
+ #
+
+ # If there is no seed interval, set one. Also, if there are no more
+ # intervals to read, this is where iterator dies.
+ if not self.seed_interval:
+ while not self.seed_interval:
+ try:
+ self.seed_interval = GenomicIntervalReader.next( self )
+ except ParseError, e:
+ handle_parse_error( e )
+
+ # Initialize feature name from seed.
+ feature_group = self.seed_interval.attributes.get( 'group', None ) # For GFF
+ feature_id = self.seed_interval.attributes.get( 'id', None ) # For GFF3
+ feature_gene_id = self.seed_interval.attributes.get( 'gene_id', None ) # For GTF
+ feature_transcript_id = self.seed_interval.attributes.get( 'transcript_id', None ) # For GTF
+
+ # Read all intervals associated with seed.
+ feature_intervals = []
+ feature_intervals.append( self.seed_interval )
+ while True:
+ try:
+ interval = GenomicIntervalReader.next( self )
+ except StopIteration, e:
+ # No more intervals to read, but last feature needs to be
+ # returned.
+ interval = None
+ break
+ except ParseError, e:
+ handle_parse_error( e )
+
+ # If interval not associated with feature, break.
+ group = interval.attributes.get( 'group', None )
+ if group and feature_group != group:
+ break
+ id = interval.attributes.get( 'id', None )
+ if id and feature_id != id:
+ break
+ gene_id = interval.attributes.get( 'gene_id', None )
+ transcript_id = interval.attributes.get( 'transcript_id', None )
+ if transcript_id and transcript_id != feature_transcript_id and gene_id and \
+ gene_id != feature_gene_id:
+ break
+
+ # Interval associated with feature.
+ feature_intervals.append( interval )
+
+ # Last interval read is the seed for the next interval.
+ self.seed_interval = interval
+
+ # Return GFF feature with all intervals.
+ return GFFFeature( self, self.chrom_col, self.start_col, self.end_col, self.strand_col, \
+ self.default_strand, fix_strand=self.fix_strand, \
+ intervals=feature_intervals )
+
+
+def convert_bed_coords_to_gff( interval ):
+ """
+ Converts an interval object's coordinates from BED format to GFF format.
+ Accepted object types include GenomicInterval and list (where the first
+ element in the list is the interval's start, and the second element is
+ the interval's end).
+ """
+ if type( interval ) is GenomicInterval:
+ interval.start += 1
+ elif type ( interval ) is list:
+ interval[ 0 ] += 1
+ return interval
+
+def convert_gff_coords_to_bed( interval ):
+ """
+ Converts an interval object's coordinates from GFF format to BED format.
+ Accepted object types include GenomicInterval and list (where the first
+ element in the list is the interval's start, and the second element is
+ the interval's end).
+ """
+ if type( interval ) is GenomicInterval:
+ interval.start -= 1
+ elif type ( interval ) is list:
+ interval[ 0 ] -= 1
+ return interval
+
+def parse_gff_attributes( attr_str ):
+ """
+ Parses a GFF/GTF attribute string and returns a dictionary of name-value
+ pairs. The general format for a GFF3 attributes string is
+ name1=value1;name2=value2
+ The general format for a GTF attribute string is
+ name1 "value1" ; name2 "value2"
+ The general format for a GFF attribute string is a single string that
+ denotes the interval's group; in this case, method returns a dictionary
+ with a single key-value pair, and key name is 'group'
+ """
+ attributes_list = attr_str.split(";")
+ attributes = {}
+ for name_value_pair in attributes_list:
+ # Try splitting by space and, if necessary, by '=' sign.
+ pair = name_value_pair.strip().split(" ")
+ if len( pair ) == 1:
+ pair = name_value_pair.strip().split("=")
+ if len( pair ) == 1:
+ # Could not split for some reason -- raise exception?
+ continue
+ if pair == '':
+ continue
+ name = pair[0].strip()
+ if name == '':
+ continue
+ # Need to strip double quote from values
+ value = pair[1].strip(" \"")
+ attributes[ name ] = value
+
+ if len( attributes ) == 0:
+ # Could not split attributes string, so entire string must be
+ # 'group' attribute. This is the case for strictly GFF files.
+ attributes['group'] = attr_str
+ return attributes
--- a/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.py
+++ b/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.py
@@ -12,7 +12,7 @@ from __future__ import division
import sys, fileinput
from galaxy import eggs
import pkg_resources; pkg_resources.require( "bx-python" )
-from galaxy.tools.util.gff_util import *
+from galaxy.datatypes.util.gff_util import *
from bx.interval_index_file import Indexes
def main():
--- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
+++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
@@ -14,7 +14,7 @@ import pkg_resources; pkg_resources.requ
from galaxy.visualization.tracks.summary import *
from bx.intervals.io import *
from bx.cookbook import doc_optparse
-from galaxy.tools.util.gff_util import *
+from galaxy.datatypes.util.gff_util import *
def main():
# Read options, args.
--- a/tools/new_operations/flanking_features.py
+++ b/tools/new_operations/flanking_features.py
@@ -18,7 +18,7 @@ from bx.cookbook import doc_optparse
from galaxy.tools.util.galaxyops import *
from bx.intervals.io import *
from bx.intervals.operations import quicksect
-from galaxy.tools.util.gff_util import *
+from galaxy.datatypes.util.gff_util import *
assert sys.version_info[:2] >= ( 2, 4 )
--- a/lib/galaxy/tools/util/gff_util.py
+++ /dev/null
@@ -1,226 +0,0 @@
-"""
-Provides utilities for working with GFF files.
-"""
-
-from bx.intervals.io import *
-
-class GFFInterval( GenomicInterval ):
- """
- A GFF interval, including attributes. If file is strictly a GFF file,
- only attribute is 'group.'
- """
- def __init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, default_strand, \
- fix_strand=False, raw_line='' ):
- GenomicInterval.__init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, \
- default_strand, fix_strand=fix_strand )
- self.raw_line = raw_line
- self.attributes = parse_gff_attributes( fields[8] )
-
-class GFFFeature( GenomicInterval ):
- """
- A GFF feature, which can include multiple intervals.
- """
- def __init__( self, reader, chrom_col, start_col, end_col, strand_col, default_strand, \
- fix_strand=False, intervals=[] ):
- GenomicInterval.__init__( self, reader, intervals[0].fields, chrom_col, start_col, end_col, \
- strand_col, default_strand, fix_strand=fix_strand )
- self.intervals = intervals
- # Use intervals to set feature attributes.
- for interval in self.intervals:
- # Error checking.
- if interval.chrom != self.chrom:
- raise ValueError( "interval chrom does not match self chrom: %i != %i" % \
- ( interval.chrom, self.chrom ) )
- if interval.strand != self.strand:
- raise ValueError( "interval strand does not match self strand: %s != %s" % \
- ( interval.strand, self.strand ) )
- # Set start, end of interval.
- if interval.start < self.start:
- self.start = interval.start
- if interval.end > self.end:
- self.end = interval.end
-
-class GFFIntervalToBEDReaderWrapper( NiceReaderWrapper ):
- """
- Reader wrapper that reads GFF intervals/lines and automatically converts
- them to BED format.
- """
-
- def parse_row( self, line ):
- # HACK: this should return a GFF interval, but bx-python operations
- # require GenomicInterval objects and subclasses will not work.
- interval = GenomicInterval( self, line.split( "\t" ), self.chrom_col, self.start_col, \
- self.end_col, self.strand_col, self.default_strand, \
- fix_strand=self.fix_strand )
- interval = convert_gff_coords_to_bed( interval )
- return interval
-
-class GFFReaderWrapper( NiceReaderWrapper ):
- """
- Reader wrapper for GFF files.
-
- Wrapper has two major functions:
- (1) group entries for GFF file (via group column), GFF3 (via id attribute ),
- or GTF (via gene_id/transcript id);
- (2) convert coordinates from GFF format--starting and ending coordinates
- are 1-based, closed--to the 'traditional'/BED interval format--0 based,
- half-open. This is useful when using GFF files as inputs to tools that
- expect traditional interval format.
- """
-
- def __init__( self, reader, **kwargs ):
- """
- Create wrapper. Defaults are group_entries=False and
- convert_coords_to_bed=True to support backward compatibility.
- """
- NiceReaderWrapper.__init__( self, reader, **kwargs )
- self.group_entries = kwargs.get( 'group_entries', False )
- self.convert_coords_to_bed = kwargs.get( 'convert_coords_to_bed', True )
- self.last_line = None
- self.cur_offset = 0
- self.seed_interval = None
-
- def parse_row( self, line ):
- interval = GFFInterval( self, line.split( "\t" ), self.chrom_col, self.start_col, \
- self.end_col, self.strand_col, self.default_strand, \
- fix_strand=self.fix_strand, raw_line=line )
- if self.convert_coords_to_bed:
- interval = convert_gff_coords_to_bed( interval )
- return interval
-
- def next( self ):
- """ Returns next GFFFeature. """
-
- #
- # Helper function.
- #
-
- def handle_parse_error( parse_error ):
- """ Actions to take when ParseError found. """
- if self.outstream:
- if self.print_delegate and hasattr(self.print_delegate,"__call__"):
- self.print_delegate( self.outstream, e, self )
- self.skipped += 1
- # no reason to stuff an entire bad file into memmory
- if self.skipped < 10:
- self.skipped_lines.append( ( self.linenum, self.current_line, str( e ) ) )
-
- #
- # Get next GFFFeature
- #
-
- # If there is no seed interval, set one. Also, if there are no more
- # intervals to read, this is where iterator dies.
- if not self.seed_interval:
- while not self.seed_interval:
- try:
- self.seed_interval = GenomicIntervalReader.next( self )
- except ParseError, e:
- handle_parse_error( e )
-
- # Initialize feature name from seed.
- feature_group = self.seed_interval.attributes.get( 'group', None ) # For GFF
- feature_id = self.seed_interval.attributes.get( 'id', None ) # For GFF3
- feature_gene_id = self.seed_interval.attributes.get( 'gene_id', None ) # For GTF
- feature_transcript_id = self.seed_interval.attributes.get( 'transcript_id', None ) # For GTF
-
- # Read all intervals associated with seed.
- feature_intervals = []
- feature_intervals.append( self.seed_interval )
- while True:
- try:
- interval = GenomicIntervalReader.next( self )
- except StopIteration, e:
- # No more intervals to read, but last feature needs to be
- # returned.
- interval = None
- break
- except ParseError, e:
- handle_parse_error( e )
-
- # If interval not associated with feature, break.
- group = interval.attributes.get( 'group', None )
- if group and feature_group != group:
- break
- id = interval.attributes.get( 'id', None )
- if id and feature_id != id:
- break
- gene_id = interval.attributes.get( 'gene_id', None )
- transcript_id = interval.attributes.get( 'transcript_id', None )
- if transcript_id and transcript_id != feature_transcript_id and gene_id and \
- gene_id != feature_gene_id:
- break
-
- # Interval associated with feature.
- feature_intervals.append( interval )
-
- # Last interval read is the seed for the next interval.
- self.seed_interval = interval
-
- # Return GFF feature with all intervals.
- return GFFFeature( self, self.chrom_col, self.start_col, self.end_col, self.strand_col, \
- self.default_strand, fix_strand=self.fix_strand, \
- intervals=feature_intervals )
-
-
-def convert_bed_coords_to_gff( interval ):
- """
- Converts an interval object's coordinates from BED format to GFF format.
- Accepted object types include GenomicInterval and list (where the first
- element in the list is the interval's start, and the second element is
- the interval's end).
- """
- if type( interval ) is GenomicInterval:
- interval.start += 1
- elif type ( interval ) is list:
- interval[ 0 ] += 1
- return interval
-
-def convert_gff_coords_to_bed( interval ):
- """
- Converts an interval object's coordinates from GFF format to BED format.
- Accepted object types include GenomicInterval and list (where the first
- element in the list is the interval's start, and the second element is
- the interval's end).
- """
- if type( interval ) is GenomicInterval:
- interval.start -= 1
- elif type ( interval ) is list:
- interval[ 0 ] -= 1
- return interval
-
-def parse_gff_attributes( attr_str ):
- """
- Parses a GFF/GTF attribute string and returns a dictionary of name-value
- pairs. The general format for a GFF3 attributes string is
- name1=value1;name2=value2
- The general format for a GTF attribute string is
- name1 "value1" ; name2 "value2"
- The general format for a GFF attribute string is a single string that
- denotes the interval's group; in this case, method returns a dictionary
- with a single key-value pair, and key name is 'group'
- """
- attributes_list = attr_str.split(";")
- attributes = {}
- for name_value_pair in attributes_list:
- # Try splitting by space and, if necessary, by '=' sign.
- pair = name_value_pair.strip().split(" ")
- if len( pair ) == 1:
- pair = name_value_pair.strip().split("=")
- if len( pair ) == 1:
- # Could not split for some reason -- raise exception?
- continue
- if pair == '':
- continue
- name = pair[0].strip()
- if name == '':
- continue
- # Need to strip double quote from values
- value = pair[1].strip(" \"")
- attributes[ name ] = value
-
- if len( attributes ) == 0:
- # Could not split attributes string, so entire string must be
- # 'group' attribute. This is the case for strictly GFF files.
- attributes['group'] = attr_str
- return attributes
1
0

galaxy-dist commit 1449307bdaf7: Data libraries: 'Delete template' renamed to 'Unuse template', 'Add template' renamed to 'Use template' as these are more semantically correct. Checkbox form fields now have 'id' attribute as well. Fix bug when adding a template when no templates exist.
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1289758795 18000
# Node ID 1449307bdaf7671bea8a879a6c0990bc0c3b7aa7
# Parent 0171a44ec8268209b762965d7a66a928e077e1d4
Data libraries: 'Delete template' renamed to 'Unuse template', 'Add template' renamed to 'Use template' as these are more semantically correct. Checkbox form fields now have 'id' attribute as well. Fix bug when adding a template when no templates exist.
--- a/templates/library/common/library_info.mako
+++ b/templates/library/common/library_info.mako
@@ -41,7 +41,7 @@
<div popupmenu="library-${library.id}-popup">
%if not library.deleted:
%if can_add and not library.info_association:
- <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Add template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Use template</a>
%endif
%if can_manage:
<a class="action-button" href="${h.url_for( controller='library_common', action='library_permissions', cntrller=cntrller, id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit permissions</a>
--- a/lib/galaxy/web/form_builder.py
+++ b/lib/galaxy/web/form_builder.py
@@ -90,25 +90,26 @@ class CheckboxField(BaseField):
A checkbox (boolean input)
>>> print CheckboxField( "foo" ).get_html()
- <input type="checkbox" name="foo" value="true" ><input type="hidden" name="foo" value="true">
+ <input type="checkbox" id="foo" name="foo" value="true"><input type="hidden" name="foo" value="true">
>>> print CheckboxField( "bar", checked="yes" ).get_html()
- <input type="checkbox" name="bar" value="true" checked><input type="hidden" name="bar" value="true">
+ <input type="checkbox" id="bar" name="bar" value="true" checked="checked"><input type="hidden" name="bar" value="true">
"""
def __init__( self, name, checked=None ):
self.name = name
self.checked = ( checked == True ) or ( isinstance( checked, basestring ) and ( checked.lower() in ( "yes", "true", "on" ) ) )
def get_html( self, prefix="", disabled=False ):
if self.checked:
- checked_text = "checked"
+ checked_text = ' checked="checked"'
else:
checked_text = ""
+ id_name = prefix + self.name
# The hidden field is necessary because if the check box is not checked on the form, it will
# not be included in the request params. The hidden field ensure that this will happen. When
# parsing the request, the value 'true' in the hidden field actually means it is NOT checked.
# See the is_checked() method below. The prefix is necessary in each case to ensure functional
# correctness when the param is inside a conditional.
- return '<input type="checkbox" name="%s%s" value="true" %s%s><input type="hidden" name="%s%s" value="true"%s>' \
- % ( prefix, self.name, checked_text, self.get_disabled_str( disabled ), prefix, self.name, self.get_disabled_str( disabled ) )
+ return '<input type="checkbox" id="%s" name="%s" value="true"%s%s><input type="hidden" name="%s%s" value="true"%s>' \
+ % ( id_name, id_name, checked_text, self.get_disabled_str( disabled ), prefix, self.name, self.get_disabled_str( disabled ) )
@staticmethod
def is_checked( value ):
if value == True:
--- a/templates/library/common/browse_library.mako
+++ b/templates/library/common/browse_library.mako
@@ -152,16 +152,6 @@
});
});
- // For view info links, use a modal popup
- /*$(".view-info").live("click", function() {
- $.get( $(this).attr("href"), function(info) {
- show_modal("View Information", info, {
- "Close": function() { hide_modal(); }
- });
- });
- return false;
- });*/
-
function checkForm() {
if ( $("select#action_on_datasets_select option:selected").text() == "delete" ) {
if ( confirm( "Click OK to delete these datasets?" ) ) {
@@ -276,14 +266,14 @@
%if not branch_deleted( folder ) and not ldda.library_dataset.deleted and can_modify:
<a class="action-button" href="${h.url_for( controller='library_common', action='ldda_edit_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a>
%else:
- <a class="action-button" class="view-info" href="${h.url_for( controller='library_common', action='ldda_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">View information</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='ldda_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">View information</a>
%endif
%if not branch_deleted( folder ) and not ldda.library_dataset.deleted and can_modify and not info_association:
- <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Add template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Use template</a>
%endif
%if not branch_deleted( folder ) and not ldda.library_dataset.deleted and can_modify and info_association:
<a class="action-button" href="${h.url_for( controller='library_common', action='edit_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit template</a>
- <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Delete template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Unuse template</a>
%endif
%if not branch_deleted( folder ) and not ldda.library_dataset.deleted and can_manage:
%if not trans.app.security_agent.dataset_is_public( ldda.dataset ):
@@ -393,11 +383,11 @@
%endif
%endif
%if not branch_deleted( folder ) and can_modify and not info_association:
- <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='folder', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), use_panels=use_panels, show_deleted=show_deleted )}">Add template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='folder', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), use_panels=use_panels, show_deleted=show_deleted )}">Use template</a>
%endif
%if not branch_deleted( folder ) and can_modify and info_association:
<a class="action-button" href="${h.url_for( controller='library_common', action='edit_template', cntrller=cntrller, item_type='folder', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit template</a>
- <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type='folder', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), use_panels=use_panels, show_deleted=show_deleted )}">Delete template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type='folder', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), use_panels=use_panels, show_deleted=show_deleted )}">Unuse template</a>
%endif
%if not branch_deleted( folder ) and can_manage:
%if not trans.app.security_agent.folder_is_public( folder ):
@@ -509,11 +499,11 @@
%endif
%endif
%if can_modify and not library.info_association:
- <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Add template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Use template</a>
%endif
%if can_modify and info_association:
<a class="action-button" href="${h.url_for( controller='library_common', action='edit_template', cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit template</a>
- <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Delete template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Unuse template</a>
%endif
%if can_manage:
%if not trans.app.security_agent.library_is_public( library, contents=True ):
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -270,7 +270,7 @@ class BooleanToolParameter( ToolParamete
>>> print p.name
blah
>>> print p.get_html()
- <input type="checkbox" name="blah" value="true" checked><input type="hidden" name="blah" value="true">
+ <input type="checkbox" id="blah" name="blah" value="true" checked="checked"><input type="hidden" name="blah" value="true">
>>> print p.from_html( ["true","true"] )
True
>>> print p.to_param_dict_string( True )
--- a/templates/library/common/common.mako
+++ b/templates/library/common/common.mako
@@ -92,7 +92,7 @@
<a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type=item_type, library_id=library_id, folder_id=folder_id, ldda_id=ldda_id, show_deleted=show_deleted )}">Select a different template</a>
%elif info_association and not inherited and can_modify:
<a class="action-button" href="${h.url_for( controller='library_common', action='edit_template', cntrller=cntrller, item_type=item_type, library_id=library_id, folder_id=folder_id, ldda_id=ldda_id, show_deleted=show_deleted )}">Edit template</a>
- <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type=item_type, library_id=library_id, folder_id=folder_id, ldda_id=ldda_id, show_deleted=show_deleted )}">Delete template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type=item_type, library_id=library_id, folder_id=folder_id, ldda_id=ldda_id, show_deleted=show_deleted )}">Unuse template</a>
%if item_type not in [ 'ldda', 'library_dataset' ]:
%if info_association.inheritable:
<a class="action-button" href="${h.url_for( controller='library_common', action='manage_template_inheritance', cntrller=cntrller, item_type=item_type, library_id=library_id, folder_id=folder_id, ldda_id=ldda_id, show_deleted=show_deleted )}">Dis-inherit template</a>
@@ -110,7 +110,7 @@
<b>
This is an inherited template and is not required to be used with this ${item_type}. You can
<a href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type=item_type, library_id=library_id, folder_id=folder_id, ldda_id=ldda_id, show_deleted=show_deleted )}"><font color="red">select a different template</font></a>
- or fill in the desired fields and save this one. This template will not be assocaiated with this ${item_type} until you click the Save button.
+ or fill in the desired fields and save this one. This template will not be associated with this ${item_type} until you click the Save button.
</b></font></div>
--- a/lib/galaxy/web/controllers/library_common.py
+++ b/lib/galaxy/web/controllers/library_common.py
@@ -1781,7 +1781,8 @@ class LibraryCommon( BaseController, Use
if not forms:
message = "There are no forms on which to base the template, so create a form and then add the template."
return trans.response.send_redirect( web.url_for( controller='forms',
- action='create_request',
+ action='create_form',
+ cntrller='library',
message=message,
status='done',
form_type=trans.app.model.FormDefinition.types.LIBRARY_INFO_TEMPLATE ) )
--- a/templates/library/common/select_template.mako
+++ b/templates/library/common/select_template.mako
@@ -28,18 +28,18 @@
</div>
% if item_type in [ 'library', 'folder' ]:
<div class="form-row">
- <label>Inherit template to contained folders and datasets?</label>
%if inheritable_checked:
<% inheritable_check_box.checked = True %>
%endif
${inheritable_check_box.get_html()}
+ <label for="inheritable" style="display:inline;">Inherit template to contained folders and datasets?</label><div class="toolParamHelp" style="clear: both;">
Check if you want this template to be used by other folders and datasets contained within this ${item_desc}
</div></div>
%endif
<div class="form-row">
- <input type="submit" name="add_template_button" value="Add template to ${item_desc}"/>
+ <input type="submit" name="add_template_button" value="Use this template"/></div></form></div>
--- a/templates/library/common/ldda_info.mako
+++ b/templates/library/common/ldda_info.mako
@@ -52,10 +52,10 @@
%if can_modify:
<a class="action-button" href="${h.url_for( controller='library_common', action='ldda_edit_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a>
%if not info_association:
- <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Add template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='add_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Use template</a>
%else:
<a class="action-button" href="${h.url_for( controller='library_common', action='edit_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit template</a>
- <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Delete template</a>
+ <a class="action-button" href="${h.url_for( controller='library_common', action='delete_template', cntrller=cntrller, item_type='ldda', library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Unuse template</a>
%endif
%endif
%if can_manage:
1
0

galaxy-dist commit 98009db17cb2: Refactor sam_bitwise_flag_filter tool, simplifying it and making it faster, especially when there are multiple flag criteria
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1289677046 18000
# Node ID 98009db17cb2b21db626fc9c185a8fd22109a4cd
# Parent cadf13f67c6593d99f8134ba10baa211a026439b
Refactor sam_bitwise_flag_filter tool, simplifying it and making it faster, especially when there are multiple flag criteria
--- a/tools/samtools/sam_bitwise_flag_filter.py
+++ b/tools/samtools/sam_bitwise_flag_filter.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# Refactored on 11/13/2010 by Kanwei Li
import sys
import optparse
@@ -104,74 +105,45 @@ options (listed below) default to 'None'
default = '2',
help='Column containing SAM bitwise flag. 1-based')
- parser.add_option(
- '-d','--debug',
- dest='debug',
- action='store_true',
- default = False,
- help='Print debugging info')
-
options, args = parser.parse_args()
if options.input_sam:
infile = open ( options.input_sam, 'r')
else:
infile = sys.stdin
-
- option_values = { '0': False, '1': True, None: None }
-
- states = [];
- states.append( option_values[ options.is_paired ] )
- states.append( option_values[ options.is_proper_pair ] )
- states.append( option_values[ options.is_unmapped ] )
- states.append( option_values[ options.mate_is_unmapped ] )
- states.append( option_values[ options.query_strand ] )
- states.append( option_values[ options.mate_strand ] )
- states.append( option_values[ options.is_first ] )
- states.append( option_values[ options.is_second ] )
- states.append( option_values[ options.is_not_primary ] )
- states.append( option_values[ options.is_bad_quality ] )
- states.append( option_values[ options.is_duplicate ] )
-
+
+ opt_ary = [
+ options.is_paired,
+ options.is_proper_pair,
+ options.is_unmapped,
+ options.mate_is_unmapped,
+ options.query_strand,
+ options.mate_strand,
+ options.is_first,
+ options.is_second,
+ options.is_not_primary,
+ options.is_bad_quality,
+ options.is_duplicate
+ ]
+
+ opt_map = { '0': False, '1': True }
+ used_indices = [(index, opt_map[opt]) for index, opt in enumerate(opt_ary) if opt is not None]
+ flag_col = int( options.flag_col ) - 1
+
for line in infile:
line = line.rstrip( '\r\n' )
if line and not line.startswith( '#' ) and not line.startswith( '@' ) :
fields = line.split( '\t' )
- sam_states = []
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0001 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0002 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0004 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0008 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0010 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0020 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0040 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0080 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0100 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0200 ) )
- sam_states.append( bool( int( fields[ int( options.flag_col ) - 1 ] ) & 0x0400 ) )
-
- joined_states = zip(states,sam_states)
- searchable_fields = []
-
- for i in range( len( joined_states ) ):
- if joined_states[i][0] != None:
- searchable_fields.append( joined_states[ i ] )
+ flags = int( fields[flag_col] )
valid_line = True
-
- for i in range( len( searchable_fields ) ):
- if searchable_fields[i][0] != searchable_fields[i][1]:
+ for index, opt_bool in used_indices:
+ if bool(flags & 0x0001 << index) != opt_bool:
valid_line = False
+ break
if valid_line:
print line
- if options.debug:
- for i in range( len( joined_states ) ):
- print i, joined_states[i][0], joined_states[i][1]
-
-# if skipped_lines > 0:
-# print 'Skipped %d invalid lines' % skipped_lines
-
if __name__ == "__main__": main()
1
0

galaxy-dist commit 9b2bc4d4d6ca: Add full GFF support to trackster: GFF features blocks are now displayed correctly, along with name, strand, and score information. Added score column to GFFReaderWrapper as well.
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1289766276 18000
# Node ID 9b2bc4d4d6ca9b1f4275cb335460c8d570c7eeaf
# Parent 1449307bdaf7671bea8a879a6c0990bc0c3b7aa7
Add full GFF support to trackster: GFF features blocks are now displayed correctly, along with name, strand, and score information. Added score column to GFFReaderWrapper as well.
--- a/lib/galaxy/visualization/tracks/data_providers.py
+++ b/lib/galaxy/visualization/tracks/data_providers.py
@@ -5,6 +5,7 @@ Data providers for tracks visualizations
from math import floor, ceil, log, pow
import pkg_resources
pkg_resources.require( "bx-python" ); pkg_resources.require( "pysam" ); pkg_resources.require( "numpy" )
+from galaxy.datatypes.util.gff_util import *
from bx.interval_index_file import Indexes
from bx.arrays.array_tree import FileArrayTreeDict
from galaxy.util.lrucache import LRUCache
@@ -330,25 +331,43 @@ class IntervalIndexDataProvider( TracksD
break
count += 1
source.seek(offset)
- feature = source.readline().split()
payload = [ offset, start, end ]
# TODO: can we use column metadata to fill out payload?
# TODO: use function to set payload data
if "no_detail" not in kwargs:
- length = len(feature)
if isinstance( self.original_dataset.datatype, Gff ):
# GFF dataset.
- if length >= 3:
- payload.append( feature[2] ) # name
- if length >= 7:
- payload.append( feature[6] ) # strand
+ reader = GFFReaderWrapper( source )
+ feature = reader.next()
+
+ payload.append( feature.name() )
+ # Strand:
+ payload.append( feature.strand )
+
+ # No notion of thick start, end in GFF, so make everything
+ # thick.
+ payload.append( start )
+ payload.append( end )
+
+ # Add blocks.
+ feature = convert_gff_coords_to_bed( feature )
+ block_sizes = [ (interval.end - interval.start ) for interval in feature.intervals ]
+ block_starts = [ ( interval.start - feature.start ) for interval in feature.intervals ]
+ blocks = zip( block_sizes, block_starts )
+ payload.append( [ ( start + block[1], start + block[1] + block[0] ) for block in blocks ] )
+
+ # Score.
+ payload.append( feature.score )
elif isinstance( self.original_dataset.datatype, Bed ):
# BED dataset.
+ feature = source.readline().split()
+ length = len(feature)
if length >= 4:
payload.append(feature[3]) # name
if length >= 6: # strand
payload.append(feature[5])
+ # Thick start, end.
if length >= 8:
payload.append(int(feature[6]))
payload.append(int(feature[7]))
@@ -356,8 +375,8 @@ class IntervalIndexDataProvider( TracksD
if length >= 12:
block_sizes = [ int(n) for n in feature[10].split(',') if n != '']
block_starts = [ int(n) for n in feature[11].split(',') if n != '' ]
- blocks = zip(block_sizes, block_starts)
- payload.append( [ (start + block[1], start + block[1] + block[0]) for block in blocks] )
+ blocks = zip( block_sizes, block_starts )
+ payload.append( [ ( start + block[1], start + block[1] + block[0] ) for block in blocks ] )
if length >= 5:
payload.append( int(feature[4]) ) # score
--- a/lib/galaxy/datatypes/util/gff_util.py
+++ b/lib/galaxy/datatypes/util/gff_util.py
@@ -9,21 +9,28 @@ class GFFInterval( GenomicInterval ):
A GFF interval, including attributes. If file is strictly a GFF file,
only attribute is 'group.'
"""
- def __init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, default_strand, \
- fix_strand=False, raw_line='' ):
+ def __init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, \
+ score_col, default_strand, fix_strand=False, raw_line='' ):
GenomicInterval.__init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, \
default_strand, fix_strand=fix_strand )
+ # Handle score column.
+ self.score_col = score_col
+ if self.score_col >= self.nfields:
+ raise MissingFieldError( "No field for score_col (%d)" % score_col )
+ self.score = self.fields[ self.score_col ]
+
+ # Attributes specific to GFF.
self.raw_line = raw_line
self.attributes = parse_gff_attributes( fields[8] )
-class GFFFeature( GenomicInterval ):
+class GFFFeature( GFFInterval ):
"""
A GFF feature, which can include multiple intervals.
"""
- def __init__( self, reader, chrom_col, start_col, end_col, strand_col, default_strand, \
+ def __init__( self, reader, chrom_col, start_col, end_col, strand_col, score_col, default_strand, \
fix_strand=False, intervals=[] ):
- GenomicInterval.__init__( self, reader, intervals[0].fields, chrom_col, start_col, end_col, \
- strand_col, default_strand, fix_strand=fix_strand )
+ GFFInterval.__init__( self, reader, intervals[0].fields, chrom_col, start_col, end_col, \
+ strand_col, score_col, default_strand, fix_strand=fix_strand )
self.intervals = intervals
# Use intervals to set feature attributes.
for interval in self.intervals:
@@ -40,6 +47,15 @@ class GFFFeature( GenomicInterval ):
if interval.end > self.end:
self.end = interval.end
+ def name( self ):
+ """ Returns feature's name. """
+ name = self.attributes.get( 'transcript_id', None )
+ if not name:
+ name = self.attributes.get( 'id', None )
+ if not name:
+ name = self.attributes.get( 'group', None )
+ return name
+
class GFFIntervalToBEDReaderWrapper( NiceReaderWrapper ):
"""
Reader wrapper that reads GFF intervals/lines and automatically converts
@@ -60,7 +76,7 @@ class GFFReaderWrapper( NiceReaderWrappe
Reader wrapper for GFF files.
Wrapper has two major functions:
- (1) group entries for GFF file (via group column), GFF3 (via id attribute ),
+ (1) group entries for GFF file (via group column), GFF3 (via id attribute),
or GTF (via gene_id/transcript id);
(2) convert coordinates from GFF format--starting and ending coordinates
are 1-based, closed--to the 'traditional'/BED interval format--0 based,
@@ -68,24 +84,29 @@ class GFFReaderWrapper( NiceReaderWrappe
expect traditional interval format.
"""
- def __init__( self, reader, **kwargs ):
+ def __init__( self, reader, chrom_col=0, start_col=3, end_col=4, strand_col=6, score_col=5, **kwargs ):
"""
Create wrapper. Defaults are group_entries=False and
convert_coords_to_bed=True to support backward compatibility.
"""
+
+ # Add columns to kwargs here so that defaults can be used rather than
+ # requiring them to be passed in.
+ kwargs[ 'chrom_col' ] = chrom_col
+ kwargs[ 'start_col' ] = start_col
+ kwargs[ 'end_col' ] = end_col
+ kwargs[ 'strand_col' ] = strand_col
NiceReaderWrapper.__init__( self, reader, **kwargs )
- self.group_entries = kwargs.get( 'group_entries', False )
- self.convert_coords_to_bed = kwargs.get( 'convert_coords_to_bed', True )
+ # HACK: NiceReaderWrapper (bx-python) does not handle score_col yet, so store ourselves.
+ self.score_col = score_col
self.last_line = None
self.cur_offset = 0
self.seed_interval = None
def parse_row( self, line ):
interval = GFFInterval( self, line.split( "\t" ), self.chrom_col, self.start_col, \
- self.end_col, self.strand_col, self.default_strand, \
+ self.end_col, self.strand_col, self.score_col, self.default_strand, \
fix_strand=self.fix_strand, raw_line=line )
- if self.convert_coords_to_bed:
- interval = convert_gff_coords_to_bed( interval )
return interval
def next( self ):
@@ -105,6 +126,9 @@ class GFFReaderWrapper( NiceReaderWrappe
if self.skipped < 10:
self.skipped_lines.append( ( self.linenum, self.current_line, str( e ) ) )
+ # For debugging, uncomment this to propogate parsing exceptions up.
+ # raise e
+
#
# Get next GFFFeature
#
@@ -159,7 +183,7 @@ class GFFReaderWrapper( NiceReaderWrappe
# Return GFF feature with all intervals.
return GFFFeature( self, self.chrom_col, self.start_col, self.end_col, self.strand_col, \
- self.default_strand, fix_strand=self.fix_strand, \
+ self.score_col, self.default_strand, fix_strand=self.fix_strand, \
intervals=feature_intervals )
@@ -179,12 +203,15 @@ def convert_bed_coords_to_gff( interval
def convert_gff_coords_to_bed( interval ):
"""
Converts an interval object's coordinates from GFF format to BED format.
- Accepted object types include GenomicInterval and list (where the first
- element in the list is the interval's start, and the second element is
- the interval's end).
+ Accepted object types include GFFFeature, GenomicInterval, and list (where
+ the first element in the list is the interval's start, and the second
+ element is the interval's end).
"""
- if type( interval ) is GenomicInterval:
+ if isinstance( interval, GenomicInterval ):
interval.start -= 1
+ if isinstance( interval, GFFFeature ):
+ for subinterval in interval:
+ convert_gff_coords_to_bed( subinterval )
elif type ( interval ) is list:
interval[ 0 ] -= 1
return interval
--- a/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.py
+++ b/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.py
@@ -20,15 +20,9 @@ def main():
input_fname, out_fname = sys.argv[1:]
# Do conversion.
- chr_col, start_col, end_col, strand_col = ( 0, 3, 4, 6 )
index = Indexes()
offset = 0
- reader_wrapper = GFFReaderWrapper( fileinput.FileInput( input_fname ),
- chrom_col=chr_col,
- start_col=start_col,
- end_col=end_col,
- strand_col=strand_col,
- fix_strand=True )
+ reader_wrapper = GFFReaderWrapper( fileinput.FileInput( input_fname ), fix_strand=True )
for feature in list( reader_wrapper ):
# TODO: need to address comments:
# if comment:
@@ -49,7 +43,7 @@ def main():
offset += feature_len
index.write( open(out_fname, "w") )
-
+
if __name__ == "__main__":
main()
1
0

galaxy-dist commit 0171a44ec826: Add necessary file for commit 4602:2b8161827380
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1289752267 18000
# Node ID 0171a44ec8268209b762965d7a66a928e077e1d4
# Parent 2b81618273808135efd9409f953161481944fec2
Add necessary file for commit 4602:2b8161827380
--- /dev/null
+++ b/lib/galaxy/datatypes/util/__init__.py
@@ -0,0 +1,3 @@
+"""
+Utilities for Galaxy datatypes.
+"""
1
0

galaxy-dist commit 47d6c393f4cf: Add necessary import statement to gff_util module.
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1289785639 18000
# Node ID 47d6c393f4cf9562e4e3e10211389f84bf0a2f24
# Parent fd4a22ba5b57a48a2bed45333c2dfddaec61c359
Add necessary import statement to gff_util module.
--- a/lib/galaxy/datatypes/util/gff_util.py
+++ b/lib/galaxy/datatypes/util/gff_util.py
@@ -1,7 +1,7 @@
"""
Provides utilities for working with GFF files.
"""
-
+import pkg_resources; pkg_resources.require( "bx-python" )
from bx.intervals.io import *
class GFFInterval( GenomicInterval ):
1
0

galaxy-dist commit ecc1cefbccba: Enhance GFFReader to read and return complete features (genes/transcripts), which are composed of multiple intervals/blocks. This required hacking around a couple limitations of bx-python, but these can be easily fixed when bx-python is updated. Use enhanced functionality to correctly create converted datasets for visualizing GFF files.
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User jeremy goecks <jeremy.goecks(a)emory.edu>
# Date 1289591537 18000
# Node ID ecc1cefbccba6135f824f9573f06c130fd6d08b4
# Parent b124f54952dee106f4ca87ea89a7f828c41562c3
Enhance GFFReader to read and return complete features (genes/transcripts), which are composed of multiple intervals/blocks. This required hacking around a couple limitations of bx-python, but these can be easily fixed when bx-python is updated. Use enhanced functionality to correctly create converted datasets for visualizing GFF files.
Also updated GOPS tools to use a simpler GFF reader wrapper to read in intervals and convert to BED coordinates.
--- a/tools/new_operations/gops_subtract.py
+++ b/tools/new_operations/gops_subtract.py
@@ -44,11 +44,11 @@ def main():
# Set readers to handle either GFF or default format.
if in1_gff_format:
- in1_reader_wrapper = GFFReaderWrapper
+ in1_reader_wrapper = GFFIntervalToBEDReaderWrapper
else:
in1_reader_wrapper = NiceReaderWrapper
if in2_gff_format:
- in2_reader_wrapper = GFFReaderWrapper
+ in2_reader_wrapper = GFFIntervalToBEDReaderWrapper
else:
in2_reader_wrapper = NiceReaderWrapper
--- a/tools/new_operations/gops_intersect.py
+++ b/tools/new_operations/gops_intersect.py
@@ -44,11 +44,11 @@ def main():
# Set readers to handle either GFF or default format.
if in1_gff_format:
- in1_reader_wrapper = GFFReaderWrapper
+ in1_reader_wrapper = GFFIntervalToBEDReaderWrapper
else:
in1_reader_wrapper = NiceReaderWrapper
if in2_gff_format:
- in2_reader_wrapper = GFFReaderWrapper
+ in2_reader_wrapper = GFFIntervalToBEDReaderWrapper
else:
in2_reader_wrapper = NiceReaderWrapper
@@ -66,10 +66,10 @@ def main():
fix_strand=True )
out_file = open( out_fname, "w" )
-
+
try:
for line in intersect( [g1,g2], pieces=pieces, mincols=mincols ):
- if type( line ) == GenomicInterval:
+ if isinstance( line, GenomicInterval ):
if in1_gff_format:
line = convert_bed_coords_to_gff( line )
out_file.write( "%s\n" % "\t".join( line.fields ) )
--- /dev/null
+++ b/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+"""
+Convert from GFF file to interval index file.
+
+usage:
+ python gff_to_interval_index_converter.py [input] [output]
+"""
+
+from __future__ import division
+
+import sys, fileinput
+from galaxy import eggs
+import pkg_resources; pkg_resources.require( "bx-python" )
+from galaxy.tools.util.gff_util import *
+from bx.interval_index_file import Indexes
+
+def main():
+ # Arguments
+ input_fname, out_fname = sys.argv[1:]
+
+ # Do conversion.
+ chr_col, start_col, end_col, strand_col = ( 0, 3, 4, 6 )
+ index = Indexes()
+ offset = 0
+ reader_wrapper = GFFReaderWrapper( fileinput.FileInput( input_fname ),
+ chrom_col=chr_col,
+ start_col=start_col,
+ end_col=end_col,
+ strand_col=strand_col,
+ fix_strand=True )
+ for feature in list( reader_wrapper ):
+ # TODO: need to address comments:
+ # if comment:
+ # increment_offset.
+
+ # Add feature; index expects BED coordinates.
+ convert_gff_coords_to_bed( feature )
+ index.add( feature.chrom, feature.start, feature.end, offset )
+
+ # Increment offset by feature length; feature length is all
+ # intervals/lines that comprise feature.
+ feature_len = 0
+ for interval in feature.intervals:
+ # HACK: +1 for EOL char. Need bx-python to provide raw_line itself
+ # b/c TableReader strips EOL characters, thus changing the line
+ # length.
+ feature_len += len( interval.raw_line ) + 1
+ offset += feature_len
+
+ index.write( open(out_fname, "w") )
+
+if __name__ == "__main__":
+ main()
+
--- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
+++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py
@@ -14,7 +14,7 @@ import pkg_resources; pkg_resources.requ
from galaxy.visualization.tracks.summary import *
from bx.intervals.io import *
from bx.cookbook import doc_optparse
-from galaxy.tools.util.gff_util import GFFReaderWrapper
+from galaxy.tools.util.gff_util import *
def main():
# Read options, args.
@@ -40,9 +40,12 @@ def main():
strand_col=strand_col,
fix_strand=True )
st = SummaryTree(block_size=25, levels=6, draw_cutoff=150, detail_cutoff=30)
- for line in list( reader_wrapper ):
- if type( line ) is GenomicInterval:
- st.insert_range( line.chrom, long( line.start ), long( line.end ) )
+ for feature in list( reader_wrapper ):
+ if isinstance( feature, GenomicInterval ):
+ # Tree expects BED coordinates.
+ if type( feature ) is GFFFeature:
+ convert_gff_coords_to_bed( feature )
+ st.insert_range( feature.chrom, long( feature.start ), long( feature.end ) )
st.write(out_fname)
--- a/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.xml
+++ b/lib/galaxy/datatypes/converters/gff_to_interval_index_converter.xml
@@ -1,6 +1,6 @@
-<tool id="CONVERTER_gff_to_interval_index_0" name="Convert BED to Interval Index" version="1.0.0" hidden="true">
+<tool id="CONVERTER_gff_to_interval_index_0" name="Convert GFF to Interval Index" version="1.0.0" hidden="true"><!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
- <command interpreter="python">interval_to_interval_index_converter.py $input1 $output1 --gff</command>
+ <command interpreter="python">gff_to_interval_index_converter.py $input1 $output1</command><inputs><page><param format="gff" name="input1" type="data" label="Choose GFF file"/>
--- a/tools/new_operations/flanking_features.py
+++ b/tools/new_operations/flanking_features.py
@@ -153,11 +153,11 @@ def main():
# Set readers to handle either GFF or default format.
if in1_gff_format:
- in1_reader_wrapper = GFFReaderWrapper
+ in1_reader_wrapper = GFFIntervalToBEDReaderWrapper
else:
in1_reader_wrapper = NiceReaderWrapper
if in2_gff_format:
- in2_reader_wrapper = GFFReaderWrapper
+ in2_reader_wrapper = GFFIntervalToBEDReaderWrapper
else:
in2_reader_wrapper = NiceReaderWrapper
--- a/lib/galaxy/tools/util/gff_util.py
+++ b/lib/galaxy/tools/util/gff_util.py
@@ -2,25 +2,173 @@
Provides utilities for working with GFF files.
"""
-from bx.intervals.io import NiceReaderWrapper, GenomicInterval
+from bx.intervals.io import *
+
+class GFFInterval( GenomicInterval ):
+ """
+ A GFF interval, including attributes. If file is strictly a GFF file,
+ only attribute is 'group.'
+ """
+ def __init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, default_strand, \
+ fix_strand=False, raw_line='' ):
+ GenomicInterval.__init__( self, reader, fields, chrom_col, start_col, end_col, strand_col, \
+ default_strand, fix_strand=fix_strand )
+ self.raw_line = raw_line
+ self.attributes = parse_gff_attributes( fields[8] )
+
+class GFFFeature( GenomicInterval ):
+ """
+ A GFF feature, which can include multiple intervals.
+ """
+ def __init__( self, reader, chrom_col, start_col, end_col, strand_col, default_strand, \
+ fix_strand=False, intervals=[] ):
+ GenomicInterval.__init__( self, reader, intervals[0].fields, chrom_col, start_col, end_col, \
+ strand_col, default_strand, fix_strand=fix_strand )
+ self.intervals = intervals
+ # Use intervals to set feature attributes.
+ for interval in self.intervals:
+ # Error checking.
+ if interval.chrom != self.chrom:
+ raise ValueError( "interval chrom does not match self chrom: %i != %i" % \
+ ( interval.chrom, self.chrom ) )
+ if interval.strand != self.strand:
+ raise ValueError( "interval strand does not match self strand: %s != %s" % \
+ ( interval.strand, self.strand ) )
+ # Set start, end of interval.
+ if interval.start < self.start:
+ self.start = interval.start
+ if interval.end > self.end:
+ self.end = interval.end
+
+class GFFIntervalToBEDReaderWrapper( NiceReaderWrapper ):
+ """
+ Reader wrapper that reads GFF intervals/lines and automatically converts
+ them to BED format.
+ """
+
+ def parse_row( self, line ):
+ # HACK: this should return a GFF interval, but bx-python operations
+ # require GenomicInterval objects and subclasses will not work.
+ interval = GenomicInterval( self, line.split( "\t" ), self.chrom_col, self.start_col, \
+ self.end_col, self.strand_col, self.default_strand, \
+ fix_strand=self.fix_strand )
+ interval = convert_gff_coords_to_bed( interval )
+ return interval
class GFFReaderWrapper( NiceReaderWrapper ):
"""
- Reader wrapper converts GFF format--starting and ending coordinates are 1-based, closed--to the
- 'traditional'/BED interval format--0 based, half-open. This is useful when using GFF files as inputs
- to tools that expect traditional interval format.
+ Reader wrapper for GFF files.
+
+ Wrapper has two major functions:
+ (1) group entries for GFF file (via group column), GFF3 (via id attribute ),
+ or GTF (via gene_id/transcript id);
+ (2) convert coordinates from GFF format--starting and ending coordinates
+ are 1-based, closed--to the 'traditional'/BED interval format--0 based,
+ half-open. This is useful when using GFF files as inputs to tools that
+ expect traditional interval format.
"""
+
+ def __init__( self, reader, **kwargs ):
+ """
+ Create wrapper. Defaults are group_entries=False and
+ convert_coords_to_bed=True to support backward compatibility.
+ """
+ NiceReaderWrapper.__init__( self, reader, **kwargs )
+ self.group_entries = kwargs.get( 'group_entries', False )
+ self.convert_coords_to_bed = kwargs.get( 'convert_coords_to_bed', True )
+ self.last_line = None
+ self.cur_offset = 0
+ self.seed_interval = None
+
def parse_row( self, line ):
- interval = GenomicInterval( self, line.split( "\t" ), self.chrom_col, self.start_col, self.end_col, \
- self.strand_col, self.default_strand, fix_strand=self.fix_strand )
- interval = convert_gff_coords_to_bed( interval )
+ interval = GFFInterval( self, line.split( "\t" ), self.chrom_col, self.start_col, \
+ self.end_col, self.strand_col, self.default_strand, \
+ fix_strand=self.fix_strand, raw_line=line )
+ if self.convert_coords_to_bed:
+ interval = convert_gff_coords_to_bed( interval )
return interval
+ def next( self ):
+ """ Returns next GFFFeature. """
+
+ #
+ # Helper function.
+ #
+
+ def handle_parse_error( parse_error ):
+ """ Actions to take when ParseError found. """
+ if self.outstream:
+ if self.print_delegate and hasattr(self.print_delegate,"__call__"):
+ self.print_delegate( self.outstream, e, self )
+ self.skipped += 1
+ # no reason to stuff an entire bad file into memmory
+ if self.skipped < 10:
+ self.skipped_lines.append( ( self.linenum, self.current_line, str( e ) ) )
+
+ #
+ # Get next GFFFeature
+ #
+
+ # If there is no seed interval, set one. Also, if there are no more
+ # intervals to read, this is where iterator dies.
+ if not self.seed_interval:
+ while not self.seed_interval:
+ try:
+ self.seed_interval = GenomicIntervalReader.next( self )
+ except ParseError, e:
+ handle_parse_error( e )
+
+ # Initialize feature name from seed.
+ feature_group = self.seed_interval.attributes.get( 'group', None ) # For GFF
+ feature_id = self.seed_interval.attributes.get( 'id', None ) # For GFF3
+ feature_gene_id = self.seed_interval.attributes.get( 'gene_id', None ) # For GTF
+ feature_transcript_id = self.seed_interval.attributes.get( 'transcript_id', None ) # For GTF
+
+ # Read all intervals associated with seed.
+ feature_intervals = []
+ feature_intervals.append( self.seed_interval )
+ while True:
+ try:
+ interval = GenomicIntervalReader.next( self )
+ except StopIteration, e:
+ # No more intervals to read, but last feature needs to be
+ # returned.
+ interval = None
+ break
+ except ParseError, e:
+ handle_parse_error( e )
+
+ # If interval not associated with feature, break.
+ group = interval.attributes.get( 'group', None )
+ if group and feature_group != group:
+ break
+ id = interval.attributes.get( 'id', None )
+ if id and feature_id != id:
+ break
+ gene_id = interval.attributes.get( 'gene_id', None )
+ transcript_id = interval.attributes.get( 'transcript_id', None )
+ if transcript_id and transcript_id != feature_transcript_id and gene_id and \
+ gene_id != feature_gene_id:
+ break
+
+ # Interval associated with feature.
+ feature_intervals.append( interval )
+
+ # Last interval read is the seed for the next interval.
+ self.seed_interval = interval
+
+ # Return GFF feature with all intervals.
+ return GFFFeature( self, self.chrom_col, self.start_col, self.end_col, self.strand_col, \
+ self.default_strand, fix_strand=self.fix_strand, \
+ intervals=feature_intervals )
+
+
def convert_bed_coords_to_gff( interval ):
"""
- Converts an interval object's coordinates from BED format to GFF format. Accepted object types include
- GenomicInterval and list (where the first element in the list is the interval's start, and the second
- element is the interval's end).
+ Converts an interval object's coordinates from BED format to GFF format.
+ Accepted object types include GenomicInterval and list (where the first
+ element in the list is the interval's start, and the second element is
+ the interval's end).
"""
if type( interval ) is GenomicInterval:
interval.start += 1
@@ -30,9 +178,10 @@ def convert_bed_coords_to_gff( interval
def convert_gff_coords_to_bed( interval ):
"""
- Converts an interval object's coordinates from GFF format to BED format. Accepted object types include
- GenomicInterval and list (where the first element in the list is the interval's start, and the second
- element is the interval's end).
+ Converts an interval object's coordinates from GFF format to BED format.
+ Accepted object types include GenomicInterval and list (where the first
+ element in the list is the interval's start, and the second element is
+ the interval's end).
"""
if type( interval ) is GenomicInterval:
interval.start -= 1
@@ -42,10 +191,15 @@ def convert_gff_coords_to_bed( interval
def parse_gff_attributes( attr_str ):
"""
- Parses a GFF/GTF attribute string and returns a dictionary of name-value pairs.
- The general format for a GFF3 attributes string is name1=value1;name2=value2
- The general format for a GTF attribute string is name1 "value1" ; name2 "value2"
- """
+ Parses a GFF/GTF attribute string and returns a dictionary of name-value
+ pairs. The general format for a GFF3 attributes string is
+ name1=value1;name2=value2
+ The general format for a GTF attribute string is
+ name1 "value1" ; name2 "value2"
+ The general format for a GFF attribute string is a single string that
+ denotes the interval's group; in this case, method returns a dictionary
+ with a single key-value pair, and key name is 'group'
+ """
attributes_list = attr_str.split(";")
attributes = {}
for name_value_pair in attributes_list:
@@ -53,6 +207,9 @@ def parse_gff_attributes( attr_str ):
pair = name_value_pair.strip().split(" ")
if len( pair ) == 1:
pair = name_value_pair.strip().split("=")
+ if len( pair ) == 1:
+ # Could not split for some reason -- raise exception?
+ continue
if pair == '':
continue
name = pair[0].strip()
@@ -61,4 +218,9 @@ def parse_gff_attributes( attr_str ):
# Need to strip double quote from values
value = pair[1].strip(" \"")
attributes[ name ] = value
+
+ if len( attributes ) == 0:
+ # Could not split attributes string, so entire string must be
+ # 'group' attribute. This is the case for strictly GFF files.
+ attributes['group'] = attr_str
return attributes
1
0

galaxy-dist commit cadf13f67c65: More changes to sample tracking functional tests
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User rc
# Date 1289597856 18000
# Node ID cadf13f67c6593d99f8134ba10baa211a026439b
# Parent ecc1cefbccba6135f824f9573f06c130fd6d08b4
More changes to sample tracking functional tests
- assign target data library, editing samples, assign sample barcode
--- a/test/functional/test_sample_tracking.py
+++ b/test/functional/test_sample_tracking.py
@@ -4,7 +4,9 @@ from base.twilltestcase import *
from base.test_db_util import *
sample_states = [ ( 'New', 'Sample entered into the system' ),
- ( 'Received', 'Sample tube received' ),
+ ( 'Received', 'Sample tube received' ),
+ ( 'Library Started', 'Sample library preparation' ),
+ ( 'Run Started', 'Sequence run in progress' ),
( 'Done', 'Sequence run complete' ) ]
address_dict = dict( short_desc="Office",
name="James Bond",
@@ -93,6 +95,49 @@ class TestFormsAndRequests( TwillTestCas
global role2
role2 = get_role_by_name( name )
assert role2 is not None, 'Problem retrieving role named "Role2" from the database'
+ def test_006_create_library_and_folder( self ):
+ """Testing creating the target data library and folder"""
+ # Logged in as admin_user
+ for index in range( 0, 2 ):
+ name = 'library%s' % str( index + 1 )
+ description = '%s description' % name
+ synopsis = '%s synopsis' % name
+ self.create_library( name=name, description=description, synopsis=synopsis )
+ # Get the libraries for later use
+ global library1
+ library1 = get_library( 'library1', 'library1 description', 'library1 synopsis' )
+ assert library1 is not None, 'Problem retrieving library (library1) from the database'
+ global library2
+ library2 = get_library( 'library2', 'library2 description', 'library2 synopsis' )
+ assert library2 is not None, 'Problem retrieving library (library2) from the database'
+ # setup add_library_item permission to regular_user1
+ # Set permissions on the library, sort for later testing.
+ permissions_in = [ 'LIBRARY_ACCESS' ]
+ permissions_out = []
+ # Role1 members are: admin_user, regular_user1, regular_user3.
+ # Each of these users will be permitted for LIBRARY_ACCESS, LIBRARY_ADD on
+ # library1 and library2.
+ for library in [ library1, library2 ]:
+ self.library_permissions( self.security.encode_id( library.id ),
+ library.name,
+ str( role1.id ),
+ permissions_in,
+ permissions_out )
+ # adding a folder
+ for library in [ library1, library2 ]:
+ name = "%s_folder1" % library.name
+ description = "%s description" % name
+ self.add_folder( 'library_admin',
+ self.security.encode_id( library.id ),
+ self.security.encode_id( library.root_folder.id ),
+ name=name,
+ description=description )
+ global library1_folder1
+ library1_folder1 = get_folder( library1.root_folder.id, 'library1_folder1', 'library1_folder1 description' )
+ assert library1_folder1 is not None, 'Problem retrieving library folder named "library1_folder1" from the database'
+ global library2_folder1
+ library2_folder1 = get_folder( library2.root_folder.id, 'library2_folder1', 'library2_folder1 description' )
+ assert library2_folder1 is not None, 'Problem retrieving library folder named "library2_folder1" from the database'
#
# ====== Form definition test methods ================================================
#
@@ -283,25 +328,25 @@ class TestFormsAndRequests( TwillTestCas
self.view_request( cntrller='requests',
request_id=self.security.encode_id( request1.id ),
strings_displayed=[ 'Sequencing request "%s"' % request1.name,
- 'There are no samples.',
- sample_form_layout_grid_name ],
+ 'There are no samples.' ],
strings_not_displayed=[ request1.states.SUBMITTED,
request1.states.COMPLETE,
- request1.states.REJECTED ] )
+ request1.states.REJECTED,
+ 'Submit request' ] ) # this button should NOT show up as there are no samples yet
# check if the request is showing in the 'new' filter
self.check_request_grid( cntrller='requests',
state=request1.states.NEW,
strings_displayed=[ request1.name ] )
self.view_request_history( cntrller='requests',
request_id=self.security.encode_id( request1.id ),
- strings_displayed=[ 'History of Sequencing Request "%s"' % request1.name,
+ strings_displayed=[ 'History of sequencing request "%s"' % request1.name,
request1.states.NEW,
'Request created' ],
strings_not_displayed=[ request1.states.SUBMITTED,
request1.states.COMPLETE,
request1.states.REJECTED ] )
def test_030_edit_basic_request_info( self ):
- """Testing editing the basic information of a sequencing request"""
+ """Testing editing the basic information and email settings of a sequencing request"""
# logged in as regular_user1
fields = [ 'option2', str( user_address1.id ), 'field3 value (edited)' ]
new_name=request1.name + ' (Renamed)'
@@ -315,43 +360,186 @@ class TestFormsAndRequests( TwillTestCas
strings_displayed=[ 'Edit sequencing request "%s"' % request1.name ],
strings_displayed_after_submit=[ new_name, new_desc ] )
refresh( request1 )
+ # now check email notification settings
+ check_sample_states = [ ( request1.type.states[0].name, request1.type.states[0].id, True ),
+ ( request1.type.states[2].name, request1.type.states[2].id, True ),
+ ( request1.type.states[4].name, request1.type.states[4].id, True ) ]#[ ( state.id, True ) for state in request1.type.states ]
+ strings_displayed = [ 'Edit sequencing request "%s"' % request1.name,
+ 'Email notification settings' ]
+ additional_emails = [ 'test@.bx.psu.edu', 'test2@.bx.psu.edu' ]
+ strings_displayed_after_submit = [ "The changes made to the email notification settings have been saved",
+ '\r\n'.join( additional_emails ) ]
+ self.edit_request_email_settings( cntrller='requests',
+ request_id=self.security.encode_id( request1.id ),
+ check_request_owner=True,
+ additional_emails='\r\n'.join( additional_emails ),
+ check_sample_states=check_sample_states,
+ strings_displayed=strings_displayed,
+ strings_displayed_after_submit=strings_displayed_after_submit )
+ # lastly check the details in the request page
+ strings_displayed = [ 'Sequencing request "%s"' % new_name,
+ new_desc ]
+ for field in fields:
+ strings_displayed.append( field )
+ for state_name, id, is_checked in check_sample_states:
+ strings_displayed.append( state_name )
+ for email in additional_emails:
+ strings_displayed.append( email )
+ self.view_request( cntrller='requests',
+ request_id=self.security.encode_id( request1.id ),
+ strings_displayed=strings_displayed,
+ strings_not_displayed=[] )
def test_035_add_samples_to_request( self ):
"""Testing adding samples to request"""
# logged in as regular_user1
# Sample fields - the tuple represents a sample name and a list of sample form field values
- sample_value_tuples = [ ( 'Sample1', [ 'option1', 'sample1 field2 value', 'sample1 field3 value' ] ),
- ( 'Sample2', [ 'option2', 'sample2 field2 value', 'sample2 field3 value' ] ),
- ( 'Sample3', [ 'option1', 'sample3 field2 value', 'sample3 field3 value' ] ) ]
+ target_library_info = dict(library=self.security.encode_id(library2.id),
+ folder=self.security.encode_id(library2_folder1.id) )
+ sample_value_tuples = \
+ [ ( 'Sample1', target_library_info, [ 'option1', 'sample1 field2 value', 'sample1 field3 value' ] ),
+ ( 'Sample2', target_library_info, [ 'option2', 'sample2 field2 value', 'sample2 field3 value' ] ),
+ ( 'Sample3', target_library_info, [ 'option1', 'sample3 field2 value', 'sample3 field3 value' ] ) ]
strings_displayed_after_submit = [ 'Unsubmitted' ]
- for sample_name, field_values in sample_value_tuples:
+ for sample_name, lib_info, field_values in sample_value_tuples:
strings_displayed_after_submit.append( sample_name )
+ # add the sample values too
+ for values in field_values:
+ strings_displayed_after_submit.append( values )
# Add samples to the request
self.add_samples( cntrller='requests',
request_id=self.security.encode_id( request1.id ),
- request_name=request1.name,
sample_value_tuples=sample_value_tuples,
strings_displayed=[ 'Add Samples to Request "%s"' % request1.name,
'<input type="text" name="sample_0_name" value="Sample_1" size="10"/>' ], # sample name input field
strings_displayed_after_submit=strings_displayed_after_submit )
-# def test_040_edit_samples_of_new_request( self ):
-# """Testing editing the sample information of new request1"""
-# # logged in as regular_user1
-# pass
-# def test_035_submit_request( self ):
-# """Testing editing a sequence run request"""
-# # logged in as regular_user1
-# self.submit_request( cntrller='requests',
-# request_id=self.security.encode_id( request1.id ),
-# request_name=request1.name,
-# strings_displayed_after_submit=[ 'The request has been submitted.' ] )
-# refresh( request1 )
-# # Make sure the request is showing in the 'submitted' filter
-# self.check_request_grid( cntrller='requests',
-# state=request1.states.SUBMITTED,
-# strings_displayed=[ request1.name ] )
-# # Make sure the request's state is now set to 'submitted'
-# assert request1.state is not request1.states.SUBMITTED, "The state of the request '%s' should be set to '%s'" \
-# % ( request1.name, request1.states.SUBMITTED )
+ # check the new sample field values on the request page
+ strings_displayed = [ 'Sequencing request "%s"' % request1.name,
+ 'Submit request' ] # this button should appear now
+ strings_displayed.extend( strings_displayed_after_submit )
+ strings_displayed_count = []
+ strings_displayed_count.append( ( library2.name, len( sample_value_tuples ) ) )
+ strings_displayed_count.append( ( library2_folder1.name, len( sample_value_tuples ) ) )
+ self.view_request( cntrller='requests',
+ request_id=self.security.encode_id( request1.id ),
+ strings_displayed=strings_displayed,
+ strings_displayed_count=strings_displayed_count )
+ def test_040_edit_samples_of_new_request( self ):
+ """Testing editing the sample information of new request1"""
+ # logged in as regular_user1
+ # target data library - change it to library1
+ target_library_info = dict(library=self.security.encode_id(library1.id),
+ folder=self.security.encode_id(library1_folder1.id) )
+ new_sample_value_tuples = \
+ [ ( 'Sample1_renamed', target_library_info, [ 'option2', 'sample1 field2 value edited', 'sample1 field3 value edited' ] ),
+ ( 'Sample2_renamed', target_library_info, [ 'option1', 'sample2 field2 value edited', 'sample2 field3 value edited' ] ),
+ ( 'Sample3_renamed', target_library_info, [ 'option2', 'sample3 field2 value edited', 'sample3 field3 value edited' ] ) ]
+ strings_displayed_after_submit = [ 'Unsubmitted' ]
+ for sample_name, lib_info, field_values in new_sample_value_tuples:
+ strings_displayed_after_submit.append( sample_name )
+ # add the sample values too
+ for values in field_values:
+ strings_displayed_after_submit.append( values )
+ # Add samples to the request
+ self.edit_samples( cntrller='requests',
+ request_id=self.security.encode_id( request1.id ),
+ sample_value_tuples=new_sample_value_tuples,
+ strings_displayed=[ 'Edit Current Samples of Request "%s"' % request1.name,
+ '<input type="text" name="sample_0_name" value="Sample1" size="10"/>' ], # sample name input field
+ strings_displayed_after_submit=strings_displayed_after_submit )
+ # check the changed sample field values on the request page
+ strings_displayed = [ 'Sequencing request "%s"' % request1.name ]
+ strings_displayed.extend( strings_displayed_after_submit )
+ strings_displayed_count = []
+ strings_displayed_count.append( ( library1.name, len( new_sample_value_tuples ) ) )
+ strings_displayed_count.append( ( library1_folder1.name, len( new_sample_value_tuples ) ) )
+ self.view_request( cntrller='requests',
+ request_id=self.security.encode_id( request1.id ),
+ strings_displayed=strings_displayed,
+ strings_displayed_count=strings_displayed_count )
+ def test_045_submit_request( self ):
+ """Testing submitting a sequencing request"""
+ # logged in as regular_user1
+ self.submit_request( cntrller='requests',
+ request_id=self.security.encode_id( request1.id ),
+ request_name=request1.name,
+ strings_displayed_after_submit=[ 'The request has been submitted.' ] )
+ refresh( request1 )
+ # Make sure the request is showing in the 'submitted' filter
+ self.check_request_grid( cntrller='requests',
+ state=request1.states.SUBMITTED,
+ strings_displayed=[ request1.name ] )
+ # Make sure the request's state is now set to 'submitted'
+ assert request1.state is not request1.states.SUBMITTED, "The state of the request '%s' should be set to '%s'" \
+ % ( request1.name, request1.states.SUBMITTED )
+ # the sample state should appear once for each sample
+ strings_displayed_count = [ ( request1.type.states[0].name, len( request1.samples ) ) ]
+ # after submission, these buttons should not appear
+ strings_not_displayed = [ 'Add sample', 'Submit request' ]
+ # check the request page
+ self.view_request( cntrller='requests',
+ request_id=self.security.encode_id( request1.id ),
+ strings_displayed=[ request1.states.SUBMITTED ],
+ strings_displayed_count=strings_displayed_count,
+ strings_not_displayed=strings_not_displayed )
+ strings_displayed=[ 'History of sequencing request "%s"' % request1.name,
+ 'Request submitted by %s' % regular_user1.email,
+ 'Request created' ]
+ strings_displayed_count = [ ( request1.states.SUBMITTED, 1 ) ]
+ self.view_request_history( cntrller='requests',
+ request_id=self.security.encode_id( request1.id ),
+ strings_displayed=strings_displayed,
+ strings_displayed_count=strings_displayed_count,
+ strings_not_displayed=[ request1.states.COMPLETE,
+ request1.states.REJECTED ] )
+ #
+ # ====== Sequencing request test methods - Admin perspective ================
+ #
+ def test_050_receive_request_as_admin( self ):
+ """Testing receiving a sequencing request and assigning it barcodes"""
+ self.logout()
+ self.login( email=admin_user.email )
+ self.check_request_grid( cntrller='requests_admin',
+ state=request1.states.SUBMITTED,
+ strings_displayed=[ request1.name ] )
+ strings_displayed = [ request1.states.SUBMITTED,
+ 'Reject this request' ]
+ strings_not_displayed = [ 'Add sample' ]
+ self.view_request( cntrller='requests_admin',
+ request_id=self.security.encode_id( request1.id ),
+ strings_not_displayed=strings_not_displayed )
+ # Set bar codes for the samples
+ bar_codes = [ '10001', '10002', '10003' ]
+ strings_displayed_after_submit = [ 'Changes made to the samples have been saved.' ]
+ strings_displayed_after_submit.extend( bar_codes )
+ self.add_bar_codes( cntrller='requests_admin',
+ request_id=self.security.encode_id( request1.id ),
+ bar_codes=bar_codes,
+ strings_displayed=[ 'Edit Current Samples of Request "%s"' % request1.name ],
+ strings_displayed_after_submit=strings_displayed_after_submit )
+ # the second sample state should appear once for each sample
+ strings_displayed_count = [ ( request1.type.states[1].name, len( request1.samples ) ),
+ ( request1.type.states[0].name, 0 ) ]
+ # check the request page
+ self.view_request( cntrller='requests_admin',
+ request_id=self.security.encode_id( request1.id ),
+ strings_displayed=bar_codes,
+ strings_displayed_count=strings_displayed_count )
+ # the sample state descriptions of the future states should not appear
+ # here the state names are not checked as all of them appear at the top of
+ # the page like: state1 > state2 > state3
+ strings_not_displayed=[ request1.type.states[2].desc,
+ request1.type.states[3].desc,
+ request1.type.states[4].desc ]
+ # check history of each sample
+ for sample in request1.samples:
+ strings_displayed = [ 'Events for Sample "%s"' % sample.name,
+ 'Request submitted and sample state set to %s' % request1.type.states[0].name,
+ request1.type.states[0].name,
+ request1.type.states[1].name ]
+ self.view_sample_history( cntrller='requests_admin',
+ sample_id=self.security.encode_id( sample.id ),
+ strings_displayed=strings_displayed,
+ strings_not_displayed=strings_not_displayed )
# def test_040_request_lifecycle( self ):
# """Testing request life-cycle as it goes through all the states"""
# # logged in as regular_user1
@@ -478,6 +666,17 @@ class TestFormsAndRequests( TwillTestCas
self.logout()
self.login( email=admin_user.email )
##################
+ # Purge all libraries
+ ##################
+ for library in [ library1, library2 ]:
+ self.delete_library_item( 'library_admin',
+ self.security.encode_id( library.id ),
+ self.security.encode_id( library.id ),
+ library.name,
+ item_type='library' )
+ self.purge_library( self.security.encode_id( library.id ), library.name )
+
+ ##################
# Delete request_type permissions
##################
for request_type in [ request_type1 ]:
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -861,16 +861,26 @@ class TwillTestCase( unittest.TestCase )
self.home()
# Functions associated with browsers, cookies, HTML forms and page visits
-
+
def check_page_for_string( self, patt ):
"""Looks for 'patt' in the current browser page"""
page = self.last_page()
- for subpatt in patt.split():
- if page.find( patt ) == -1:
- fname = self.write_temp_file( page )
- errmsg = "no match to '%s'\npage content written to '%s'" % ( patt, fname )
- raise AssertionError( errmsg )
-
+ if page.find( patt ) == -1:
+ fname = self.write_temp_file( page )
+ errmsg = "no match to '%s'\npage content written to '%s'" % ( patt, fname )
+ raise AssertionError( errmsg )
+
+ def check_string_count_in_page( self, patt, min_count ):
+ """Checks the number of 'patt' occurrences in the current browser page"""
+ page = self.last_page()
+ patt_count = page.count( patt )
+ # The number of occurrences of patt in the page should be at least min_count
+ # so show error if patt_count is less than min_count
+ if patt_count < min_count:
+ fname = self.write_temp_file( page )
+ errmsg = "%i occurrences of '%s' found instead of %i.\npage content written to '%s' " % ( min_count, patt, patt_count, fname )
+ raise AssertionError( errmsg )
+
def check_string_not_in_page( self, patt ):
"""Checks to make sure 'patt' is NOT in the page."""
page = self.last_page()
@@ -878,6 +888,16 @@ class TwillTestCase( unittest.TestCase )
fname = self.write_temp_file( page )
errmsg = "string (%s) incorrectly displayed in page.\npage content written to '%s'" % ( patt, fname )
raise AssertionError( errmsg )
+
+ def check_page(self, strings_displayed, strings_displayed_count, strings_not_displayed):
+ """Checks a page for strings displayed, not displayed and number of occurrences of a string"""
+ for check_str in strings_displayed:
+ self.check_page_for_string(check_str)
+ for check_str, count in strings_displayed_count:
+ self.check_string_count_in_page(check_str, count)
+ for check_str in strings_not_displayed:
+ self.check_string_not_in_page(check_str)
+
def write_temp_file( self, content, suffix='.html' ):
fd, fname = tempfile.mkstemp( suffix=suffix, prefix='twilltestcase-' )
@@ -1435,7 +1455,7 @@ class TwillTestCase( unittest.TestCase )
self.check_page_for_string( check_str )
self.home()
- # Requests stuff
+ # Sample tracking stuff
def check_request_grid( self, cntrller, state, deleted=False, strings_displayed=[] ):
self.visit_url( '%s/%s/browse_requests?sort=create_time&f-state=%s&f-deleted=%s' % \
( self.url, cntrller, state.replace( ' ', '+' ), str( deleted ) ) )
@@ -1510,24 +1530,20 @@ class TwillTestCase( unittest.TestCase )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
self.home()
- def view_request( self, cntrller, request_id, strings_displayed=[], strings_not_displayed=[] ):
+ def view_request( self, cntrller, request_id, strings_displayed=[], strings_displayed_count=[], strings_not_displayed=[] ):
self.visit_url( "%s/%s/browse_requests?operation=view_request&id=%s" % ( self.url, cntrller, request_id ) )
- for check_str in strings_displayed:
- self.check_page_for_string( check_str )
- for check_str in strings_not_displayed:
- self.check_string_not_in_page( check_str )
- def view_request_history( self, cntrller, request_id, strings_displayed=[], strings_not_displayed=[] ):
+ self.check_page( strings_displayed, strings_displayed_count, strings_not_displayed )
+ def view_request_history( self, cntrller, request_id, strings_displayed=[], strings_displayed_count=[], strings_not_displayed=[] ):
self.visit_url( "%s/requests_common/view_request_history?cntrller=%s&id=%s" % ( self.url, cntrller, request_id ) )
- for check_str in strings_displayed:
- self.check_page_for_string( check_str )
- for check_str in strings_not_displayed:
- self.check_string_not_in_page( check_str )
+ self.check_page( strings_displayed, strings_displayed_count, strings_not_displayed )
+ def view_sample_history( self, cntrller, sample_id, strings_displayed=[], strings_displayed_count=[], strings_not_displayed=[] ):
+ self.visit_url( "%s/requests_common/sample_events?cntrller=%s&sample_id=%s" % ( self.url, cntrller, sample_id ) )
+ self.check_page( strings_displayed, strings_displayed_count, strings_not_displayed )
def edit_basic_request_info( self, cntrller, request_id, name, new_name='', new_desc='', new_fields=[],
strings_displayed=[], strings_displayed_after_submit=[] ):
self.visit_url( "%s/requests_common/edit_basic_request_info?cntrller=%s&id=%s" % ( self.url, cntrller, request_id ) )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- self.check_page_for_string( 'Edit sequencing request "%s"' % name )
if new_name:
tc.fv( "1", "name", new_name )
if new_desc:
@@ -1537,15 +1553,29 @@ class TwillTestCase( unittest.TestCase )
tc.submit( "edit_basic_request_info_button" )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
- def add_samples( self, cntrller, request_id, request_name, sample_value_tuples, strings_displayed=[], strings_displayed_after_submit=[] ):
+ def edit_request_email_settings( self, cntrller, request_id, check_request_owner=True, additional_emails='',
+ check_sample_states=[], strings_displayed=[], strings_displayed_after_submit=[] ):
+ self.visit_url( "%s/requests_common/edit_basic_request_info?cntrller=%s&id=%s" % ( self.url, cntrller, request_id ) )
+ for check_str in strings_displayed:
+ self.check_page_for_string( check_str )
+ tc.fv( "2", "email_address", check_request_owner )
+ tc.fv( "2", "additional_email_addresses", additional_emails )
+ for state_name, state_id, is_checked in check_sample_states:
+ tc.fv( "2", "sample_state_%i" % state_id, is_checked )
+ tc.submit( "edit_email_settings_button" )
+ for check_str in strings_displayed_after_submit:
+ self.check_page_for_string( check_str )
+ def add_samples( self, cntrller, request_id, sample_value_tuples, strings_displayed=[], strings_displayed_after_submit=[] ):
url = "%s/requests_common/add_sample?cntrller=%s&request_id=%s&add_sample_button=Add+sample" % ( self.url, cntrller, request_id )
self.visit_url( url )
for check_str in strings_displayed:
self.check_page_for_string( check_str )
- for sample_index, sample_info in enumerate( sample_value_tuples ):
- sample_name = sample_info[0]
- sample_field_values = sample_info[1]
+ for sample_index, ( sample_name, target_library_info, sample_field_values ) in enumerate( sample_value_tuples ):
tc.fv( "1", "sample_%i_name" % sample_index, sample_name )
+ lib_widget_index = sample_index + 1
+ tc.fv( "1", "sample_%i_library_id" % lib_widget_index, target_library_info[ 'library' ] )
+ self.refresh_form( "sample_%i_library_id" % lib_widget_index, target_library_info[ 'library' ] )
+ tc.fv( "1", "sample_%i_folder_id" % lib_widget_index, target_library_info[ 'folder' ] )
for field_index, field_value in enumerate( sample_field_values ):
tc.fv( "1", "sample_%i_field_%i" % ( sample_index, field_index ), field_value )
# Do not click on Add sample button when all the sample have been added
@@ -1556,6 +1586,32 @@ class TwillTestCase( unittest.TestCase )
tc.submit( "save_samples_button" )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
+ def edit_samples( self, cntrller, request_id, sample_value_tuples, strings_displayed=[], strings_displayed_after_submit=[] ):
+ url = "%s/requests_common/edit_samples?cntrller=%s&id=%s&editing_samples=True" % ( self.url, cntrller, request_id )
+ self.visit_url( url )
+ for check_str in strings_displayed:
+ self.check_page_for_string( check_str )
+ for sample_index, ( sample_name, target_library_info, sample_field_values ) in enumerate( sample_value_tuples ):
+ tc.fv( "1", "sample_%i_name" % sample_index, sample_name )
+ lib_widget_index = sample_index + 1
+ tc.fv( "1", "sample_%i_library_id" % lib_widget_index, target_library_info[ 'library' ] )
+ self.refresh_form( "sample_%i_library_id" % lib_widget_index, target_library_info[ 'library' ] )
+ tc.fv( "1", "sample_%i_folder_id" % lib_widget_index, target_library_info[ 'folder' ] )
+ for field_index, field_value in enumerate( sample_field_values ):
+ tc.fv( "1", "sample_%i_field_%i" % ( sample_index, field_index ), field_value )
+ tc.submit( "save_samples_button" )
+ for check_str in strings_displayed_after_submit:
+ self.check_page_for_string( check_str )
+ def add_bar_codes( self, cntrller, request_id, bar_codes, strings_displayed=[], strings_displayed_after_submit=[] ):
+ url = "%s/requests_common/edit_samples?cntrller=%s&id=%s&editing_samples=True" % ( self.url, cntrller, request_id )
+ self.visit_url( url )
+ for check_str in strings_displayed:
+ self.check_page_for_string( check_str )
+ for sample_index, bar_code in enumerate( bar_codes ):
+ tc.fv( "1", "sample_%i_bar_code" % sample_index, bar_code )
+ tc.submit( "save_samples_button" )
+ for check_str in strings_displayed_after_submit:
+ self.check_page_for_string( check_str )
def submit_request( self, cntrller, request_id, request_name, strings_displayed_after_submit=[] ):
self.visit_url( "%s/requests_common/submit_request?cntrller=%s&id=%s" % ( self.url, cntrller, request_id ) )
for check_str in strings_displayed_after_submit:
@@ -1568,20 +1624,6 @@ class TwillTestCase( unittest.TestCase )
tc.submit( "reject_button" )
for check_str in strings_displayed_after_submit:
self.check_page_for_string( check_str )
- def add_bar_codes( self, request_id, request_name, bar_codes, samples, strings_displayed_after_submit=[] ):
- # We have to simulate the form submission here since twill barfs on the page
- # gvk - 9/22/10 - TODO: make sure the mako template produces valid html
- url = "%s/requests_common/edit_samples?cntrller=requests_admin&id=%s&editing_samples=True" % ( self.url, request_id )
- for index, field_value in enumerate( bar_codes ):
- sample_field_name = "sample_%i_name" % index
- sample_field_value = samples[ index ].name.replace( ' ', '+' )
- field_name = "sample_%i_bar_code" % index
- url += "&%s=%s" % ( field_name, field_value )
- url += "&%s=%s" % ( sample_field_name, sample_field_value )
- url += "&save_samples_button=Save"
- self.visit_url( url )
- for check_str in strings_displayed_after_submit:
- self.check_page_for_string( check_str )
def change_sample_state( self, request_id, request_name, sample_names, sample_ids, new_sample_state_id, new_state_name, comment='',
strings_displayed=[], strings_displayed_after_submit=[] ):
# We have to simulate the form submission here since twill barfs on the page
--- a/templates/requests/common/edit_samples.mako
+++ b/templates/requests/common/edit_samples.mako
@@ -155,6 +155,8 @@
%elif editing_samples:
<p/><div class="form-row">
+ ## hidden element to make twill work.
+ <input type="hidden" name="hidden_input" value=""/><input type="submit" name="save_samples_button" value="Save"/><input type="submit" name="cancel_changes_button" value="Cancel"/><div class="toolParamHelp" style="clear: both;">
1
0

galaxy-dist commit dc4af741ffc4: Fixed missing substitution of get_id_tag for a galaxy_job_id in drmaa runner.
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Dannon Baker <dannonbaker(a)me.com>
# Date 1289573664 18000
# Node ID dc4af741ffc455c4737aff67c7d7de48c8628392
# Parent dbe6ab1eaa7ca7f9754c22bb2f6edd3fc26e3432
Fixed missing substitution of get_id_tag for a galaxy_job_id in drmaa runner.
--- a/lib/galaxy/jobs/runners/drmaa.py
+++ b/lib/galaxy/jobs/runners/drmaa.py
@@ -175,7 +175,7 @@ class DRMAAJobRunner( BaseJobRunner ):
log.debug("(%s) command is: %s" % ( galaxy_id_tag, command_line ) )
# runJob will raise if there's a submit problem
job_id = self.ds.runJob(jt)
- log.info("(%s) queued as %s" % ( galaxy_job_id, job_id ) )
+ log.info("(%s) queued as %s" % ( galaxy_id_tag, job_id ) )
# store runner information for tracking if Galaxy restarts
job_wrapper.set_runner( runner_url, job_id )
1
0

galaxy-dist commit fc1f67023d86: Fixes for building target library and folder SelectFields for transferring sample datasets. All folders are now present in the target folder SelectField. Move security-related methods from the model's User class to the security agent where they belong.
by commits-noreplyï¼ bitbucket.org 20 Nov '10
by commits-noreplyï¼ bitbucket.org 20 Nov '10
20 Nov '10
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1289574787 18000
# Node ID fc1f67023d86a69ea7229501b093d61748630f4c
# Parent dc4af741ffc455c4737aff67c7d7de48c8628392
Fixes for building target library and folder SelectFields for transferring sample datasets. All folders are now present in the target folder SelectField. Move security-related methods from the model's User class to the security agent where they belong.
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -52,40 +52,6 @@ class User( object ):
if role not in roles:
roles.append( role )
return roles
- def accessible_libraries( self, trans, actions ):
- # TODO: eliminate this method - instead use
- # trans.app.security_agent.get_accessible_libraries().
- # Get all permitted libraries for this user
- all_libraries = trans.sa_session.query( trans.app.model.Library ) \
- .filter( trans.app.model.Library.table.c.deleted == False ) \
- .order_by( trans.app.model.Library.name )
- roles = self.all_roles()
- actions_to_check = actions
- # The libraries dictionary looks like: { library : '1,2' }, library : '3' }
- # Its keys are the libraries that should be displayed for the current user and whose values are a
- # string of comma-separated folder ids, of the associated folders the should NOT be displayed.
- # The folders that should not be displayed may not be a complete list, but it is ultimately passed
- # to the calling method to keep from re-checking the same folders when the library / folder
- # select lists are rendered.
- libraries = {}
- for library in all_libraries:
- can_show, hidden_folder_ids = trans.app.security_agent.show_library_item( self, roles, library, actions_to_check )
- if can_show:
- libraries[ library ] = hidden_folder_ids
- return libraries
- def accessible_request_types( self, trans ):
- active_request_types = trans.sa_session.query( trans.app.model.RequestType ) \
- .filter( trans.app.model.RequestType.table.c.deleted == False ) \
- .order_by( trans.app.model.RequestType.name )
- # Filter active_request_types to those that can be accessed by this user
- role_ids = [ r.id for r in self.all_roles() ]
- accessible_request_types = set()
- for request_type in active_request_types:
- for permission in request_type.actions:
- if permission.role.id in role_ids:
- accessible_request_types.add( request_type )
- accessible_request_types = [ request_type for request_type in accessible_request_types ]
- return accessible_request_types
class Job( object ):
"""
--- a/lib/galaxy/web/controllers/requests.py
+++ b/lib/galaxy/web/controllers/requests.py
@@ -77,7 +77,8 @@ class Requests( BaseController ):
kwd[ 'message' ] = message
# Allow the user to create a new request only if they have permission to access a
# (sequencer configuration) request type.
- if len( trans.user.accessible_request_types( trans ) ):
+ accessible_request_types = trans.app.security_agent.get_accessible_request_types( trans, trans.user )
+ if accessible_request_types:
self.request_grid.global_actions = [ grids.GridAction( "Create new request", dict( controller='requests_common',
action='create_request',
cntrller='requests' ) ) ]
--- a/lib/galaxy/web/controllers/requests_common.py
+++ b/lib/galaxy/web/controllers/requests_common.py
@@ -414,7 +414,7 @@ class RequestsCommon( BaseController, Us
cntrller=cntrller,
id=request_id,
editing_samples=editing_samples ) )
- libraries = self.__get_accessible_libraries( trans, request.user )
+ libraries = trans.app.security_agent.get_accessible_libraries( trans, request.user )
# Build a list of sample widgets (based on the attributes of each sample) for display.
displayable_sample_widgets = self.__get_sample_widgets( trans, request, request.samples, **kwd )
encoded_selected_sample_ids = self.__get_encoded_selected_sample_ids( trans, request, **kwd )
@@ -815,7 +815,7 @@ class RequestsCommon( BaseController, Us
else:
sample_index = len( displayable_sample_widgets )
if params.get( 'add_sample_button', False ):
- libraries = self.__get_accessible_libraries( trans, request.user )
+ libraries = trans.app.security_agent.get_accessible_libraries( trans, request.user )
num_samples_to_add = int( params.get( 'num_sample_to_copy', 1 ) )
# See if the user has selected a sample to copy.
copy_sample_index = int( params.get( 'copy_sample_index', -1 ) )
@@ -1214,20 +1214,14 @@ class RequestsCommon( BaseController, Us
else:
folder = None
return library, folder
+ def __get_active_folders( self, library ):
+ """Return all of the active folders for the received library"""
+ root_folder = library.root_folder
+ active_folders = [ root_folder ]
+ for folder in root_folder.active_folders:
+ active_folders.append( folder )
+ return active_folders
# ===== Methods for handling form definition widgets =====
- def __get_accessible_libraries( self, trans, user ):
- # Return a dictionary whose keys are libraries that user can
- # access and whose values are empty string ''. This is because
- # methods expect the dictionary instead of a simple list because
- # this method replaces the deprecated model.User.accessible_libraries()
- # method. TODO: fix methods that call this method to expect the list
- # returne dby trans.app.securoty_agent.get_accessible_libraries() and
- # then eliminate this method.
- accessible_libraries = trans.app.security_agent.get_accessible_libraries( trans, user )
- accessible_libraries_dict = odict()
- for library in accessible_libraries:
- accessible_libraries_dict[ library ] = ''
- return accessible_libraries_dict
def __get_request_widgets( self, trans, id ):
"""Get the widgets for the request"""
request = trans.sa_session.query( trans.model.Request ).get( id )
@@ -1275,7 +1269,7 @@ class RequestsCommon( BaseController, Us
# Build the list of widgets which will be used to render each sample row on the request page
if not request:
return sample_widgets
- libraries = self.__get_accessible_libraries( trans, request.user )
+ libraries = trans.app.security_agent.get_accessible_libraries( trans, request.user )
# Build the list if sample widgets, populating the values from kwd.
for index, sample in enumerate( samples ):
id_index = index + 1
@@ -1361,7 +1355,7 @@ class RequestsCommon( BaseController, Us
copy_sample_index_select_field.add_option( sample_dict[ 'name' ], index )
return copy_sample_index_select_field
def __build_request_type_id_select_field( self, trans, selected_value='none' ):
- accessible_request_types = trans.user.accessible_request_types( trans )
+ accessible_request_types = trans.app.security_agent.get_accessible_request_types( trans, trans.user )
return build_select_field( trans, accessible_request_types, 'name', 'request_type_id', selected_value=selected_value, refresh_on_change=True )
def __build_user_id_select_field( self, trans, selected_value='none' ):
active_users = trans.sa_session.query( trans.model.User ) \
@@ -1388,11 +1382,9 @@ class RequestsCommon( BaseController, Us
def __build_library_and_folder_select_fields( self, trans, user, sample_index, libraries, sample=None, library_id=None, folder_id=None, **kwd ):
# Create the library_id SelectField for a specific sample. The received libraries param is a list of all the libraries
# accessible to the current user, and we add them as options to the library_select_field. If the user has selected an
- # existing library then display all the accessible folders of the selected library in the folder_select_field.
- #
- # The libraries dictionary looks like: { library : '1,2' }, library : '3' }. Its keys are the libraries that
- # should be displayed for the current user and its values are strings of comma-separated folder ids that should
- # NOT be displayed.
+ # existing library then display all the folders of the selected library in the folder_select_field. Library folders do
+ # not have ACCESS permissions associated with them (only LIBRARY_ADD, LIBRARY_MODIFY, LIBRARY_MANAGE), so all folders will
+ # be present in the folder_select_field for each library selected.
params = util.Params( kwd )
library_select_field_name= "sample_%i_library_id" % sample_index
folder_select_field_name = "sample_%i_folder_id" % sample_index
@@ -1401,15 +1393,11 @@ class RequestsCommon( BaseController, Us
if not folder_id:
folder_id = params.get( folder_select_field_name, None )
selected_library = None
- selected_hidden_folder_ids = []
- showable_folders = []
if library_id not in [ None, 'none' ]:
- # If we have a selected library, get the list of it's folders that are not accessible to the current user
- for library, hidden_folder_ids in libraries.items():
+ for library in libraries:
encoded_id = trans.security.encode_id( library.id )
if encoded_id == str( library_id ):
selected_library = library
- selected_hidden_folder_ids = hidden_folder_ids.split( ',' )
break
elif sample and sample.library and library_id == 'none':
# The user previously selected a library but is now resetting the selection to 'none'
@@ -1417,21 +1405,17 @@ class RequestsCommon( BaseController, Us
elif sample and sample.library:
library_id = trans.security.encode_id( sample.library.id )
selected_library = sample.library
- # sample_%i_library_id SelectField with refresh on change enabled
+ # Build the sample_%i_library_id SelectField with refresh on change enabled
library_select_field = build_select_field( trans,
- libraries.keys(),
+ libraries,
'name',
library_select_field_name,
initial_value='none',
selected_value=str( library_id ).lower(),
refresh_on_change=True )
- # Get all accessible folders for the selected library, if one is indeed selected
+ # Get all folders for the selected library, if one is indeed selected
if selected_library:
- showable_folders = trans.app.security_agent.get_showable_folders( user,
- user.all_roles(),
- selected_library,
- [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ],
- selected_hidden_folder_ids )
+ folders = self.__get_active_folders( selected_library )
if folder_id:
selected_folder_id = folder_id
elif sample and sample.folder:
@@ -1440,11 +1424,12 @@ class RequestsCommon( BaseController, Us
selected_folder_id = trans.security.encode_id( selected_library.root_folder.id )
else:
selected_folder_id = 'none'
+ folders = []
# TODO: Change the name of the library root folder to "Library root" to clarify to the
# user that it is the root folder. We probably should just change this in the Library code,
# and update the data in the db.
folder_select_field = build_select_field( trans,
- showable_folders,
+ folders,
'name',
folder_select_field_name,
initial_value='none',
--- a/templates/webapps/galaxy/base_panels.mako
+++ b/templates/webapps/galaxy/base_panels.mako
@@ -84,7 +84,7 @@
[ 'Find Samples', h.url_for( controller='/requests', action='find_samples_index' ) ],
[ 'Help', app.config.get( "lims_doc_url", "http://main.g2.bx.psu.edu/u/rkchak/p/sts" ), "galaxy_main" ]
]
- tab( "lab", "Lab", None, menu_options=menu_options, visible=( trans.user and ( trans.user.requests or trans.user.accessible_request_types( trans ) ) ) )
+ tab( "lab", "Lab", None, menu_options=menu_options, visible=( trans.user and ( trans.user.requests or trans.app.security_agent.get_accessible_request_types( trans, trans.user ) ) ) )
%>
## Visualization menu.
--- a/lib/galaxy/security/__init__.py
+++ b/lib/galaxy/security/__init__.py
@@ -60,6 +60,8 @@ class RBACAgent:
raise "Unimplemented Method"
def get_private_user_role( self, user ):
raise "Unimplemented Method"
+ def get_accessible_request_types( self, trans, user ):
+ raise "Unimplemented Method"
def user_set_default_permissions( self, user, permissions={}, history=False, dataset=False ):
raise "Unimplemented Method"
def history_set_default_permissions( self, history, permissions=None, dataset=False, bypass_manage_permission=False ):
@@ -76,6 +78,8 @@ class RBACAgent:
raise "Unimplemented Method"
def get_accessible_libraries( self, trans, user ):
raise "Unimplemented Method"
+ def get_permitted_libraries( self, trans, user, actions ):
+ raise "Unimplemented Method"
def folder_is_public( self, library ):
raise "Unimplemented Method"
def make_folder_public( self, folder, count=0 ):
@@ -247,7 +251,7 @@ class GalaxyRBACAgent( RBACAgent ):
def can_access_library( self, roles, library ):
return self.library_is_public( library ) or self.allow_action( roles, self.permitted_actions.LIBRARY_ACCESS, library )
def get_accessible_libraries( self, trans, user ):
- """Return all data libraries that user can access"""
+ """Return all data libraries that the received user can access"""
accessible_libraries = []
current_user_role_ids = [ role.id for role in user.all_roles() ]
library_access_action = self.permitted_actions.LIBRARY_ACCESS.action
@@ -499,6 +503,20 @@ class GalaxyRBACAgent( RBACAgent ):
else:
permissions[ action ] = [ item_permission.role ]
return permissions
+ def get_accessible_request_types( self, trans, user ):
+ """Return all ReqquestTypes that the received user has permission to access."""
+ active_request_types = trans.sa_session.query( trans.app.model.RequestType ) \
+ .filter( trans.app.model.RequestType.table.c.deleted == False ) \
+ .order_by( trans.app.model.RequestType.name )
+ # Filter active_request_types to those that can be accessed by the received user
+ role_ids = [ r.id for r in user.all_roles() ]
+ accessible_request_types = set()
+ for request_type in active_request_types:
+ for permission in request_type.actions:
+ if permission.role.id in role_ids:
+ accessible_request_types.add( request_type )
+ accessible_request_types = [ request_type for request_type in accessible_request_types ]
+ return accessible_request_types
def copy_dataset_permissions( self, src, dst ):
if not isinstance( src, self.model.Dataset ):
src = src.dataset
@@ -731,6 +749,34 @@ class GalaxyRBACAgent( RBACAgent ):
else:
raise 'Invalid class (%s) specified for target_library_item (%s)' % \
( target_library_item.__class__, target_library_item.__class__.__name__ )
+ def get_permitted_libraries( self, trans, user, actions ):
+ """
+ This method is historical (it is not currently used), but may be useful again at some
+ point. It returns a dictionary whose keys are library objects and whose values are a
+ comma-separated string of folder ids. This method works with the show_library_item()
+ method below, and it returns libraries for which the received user has permission to
+ perform the received actions. Here is an example call to this method to return all
+ libraries for which the received user has LIBRARY_ADD permission:
+ libraries = trans.app.security_agent.get_permitted_libraries( trans, user,
+ [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] )
+ """
+ all_libraries = trans.sa_session.query( trans.app.model.Library ) \
+ .filter( trans.app.model.Library.table.c.deleted == False ) \
+ .order_by( trans.app.model.Library.name )
+ roles = user.all_roles()
+ actions_to_check = actions
+ # The libraries dictionary looks like: { library : '1,2' }, library : '3' }
+ # Its keys are the libraries that should be displayed for the current user and whose values are a
+ # string of comma-separated folder ids, of the associated folders the should NOT be displayed.
+ # The folders that should not be displayed may not be a complete list, but it is ultimately passed
+ # to the calling method to keep from re-checking the same folders when the library / folder
+ # select lists are rendered.
+ libraries = {}
+ for library in all_libraries:
+ can_show, hidden_folder_ids = self.show_library_item( self, roles, library, actions_to_check )
+ if can_show:
+ libraries[ library ] = hidden_folder_ids
+ return libraries
def show_library_item( self, user, roles, library_item, actions_to_check, hidden_folder_ids='' ):
"""
This method must be sent an instance of Library() or LibraryFolder(). Recursive execution produces a
1
0