galaxy-commits
Threads by month
- ----- 2025 -----
- 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
May 2010
- 2 participants
- 158 discussions

10 May '10
details: http://www.bx.psu.edu/hg/galaxy/rev/20ba52b9d504
changeset: 3720:20ba52b9d504
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Fri Apr 30 13:08:33 2010 -0400
description:
Remove headers from SAM file so that output matches new Tophat wrapper.
diffstat:
test-data/tophat_out1.sam | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diffs (9 lines):
diff -r 436c9d1c5e64 -r 20ba52b9d504 test-data/tophat_out1.sam
--- a/test-data/tophat_out1.sam Wed Apr 28 17:35:02 2010 -0400
+++ b/test-data/tophat_out1.sam Fri Apr 30 13:08:33 2010 -0400
@@ -1,5 +1,3 @@
-@HD VN:1.0 SO:sorted
-@PG TopHat VN:1.0.13 CL:/Users/jeremy/projects/bx_tools/tophat-1.0.13/bin/tophat -r 20 test_ref reads_1.fq reads_2.fq
test_mRNA_3_187_51 99 test_chromosome 53 255 75M = 163 0 TACTATTTGACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTCGGACTACG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
test_mRNA_4_191_5d 163 test_chromosome 54 255 75M = 167 0 ACTATCTGACGAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTACCATTACGCGGATGACGACTAGGACTACGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4
test_mRNA_5_197_46 97 test_chromosome 55 255 75M = 173 0 CTATCTGACTAGACTCGAGGCGCTTGCGTCTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/34c3789c86ef
changeset: 3719:34c3789c86ef
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Fri Apr 30 12:34:48 2010 -0400
description:
Make GTF type subclass from GFF type.
diffstat:
lib/galaxy/datatypes/interval.py | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diffs (17 lines):
diff -r 853046b87a5c -r 34c3789c86ef lib/galaxy/datatypes/interval.py
--- a/lib/galaxy/datatypes/interval.py Fri Apr 30 10:15:42 2010 -0400
+++ b/lib/galaxy/datatypes/interval.py Fri Apr 30 12:34:48 2010 -0400
@@ -831,9 +831,12 @@
except:
return False
-class Gtf( Tabular ):
+class Gtf( Gff ):
"""Tab delimited data in Gtf format"""
file_ext = "gtf"
+
+ def sniff( self, filename ):
+ return False
class Wiggle( Tabular, _RemoteCallMixin ):
"""Tab delimited data in wiggle format"""
1
0

10 May '10
details: http://www.bx.psu.edu/hg/galaxy/rev/853046b87a5c
changeset: 3718:853046b87a5c
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Fri Apr 30 10:15:42 2010 -0400
description:
Fix for backwards compatibility of HDAs being referenced as an integer. A hash that happened to be an integer would previously cause error.
diffstat:
lib/galaxy/web/base/controller.py | 12 ++++++++----
lib/galaxy/web/controllers/dataset.py | 12 ++++++++----
2 files changed, 16 insertions(+), 8 deletions(-)
diffs (44 lines):
diff -r c09a8456b63e -r 853046b87a5c lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py Thu Apr 29 19:57:00 2010 -0400
+++ b/lib/galaxy/web/base/controller.py Fri Apr 30 10:15:42 2010 -0400
@@ -122,10 +122,14 @@
""" Get an HDA object by id. """
# DEPRECATION: We still support unencoded ids for backward compatibility
try:
- dataset_id = int( dataset_id )
- except ValueError:
- dataset_id = trans.security.decode_id( dataset_id )
- data = trans.sa_session.query( trans.model.HistoryDatasetAssociation ).get( dataset_id )
+ data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.security.decode_id( dataset_id ) )
+ if data is None:
+ raise ValueError( 'Invalid reference dataset id: %s.' % dataset_id )
+ except:
+ try:
+ data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( int( dataset_id ) )
+ except:
+ data = None
if not data:
raise paste.httpexceptions.HTTPRequestRangeNotSatisfiable( "Invalid dataset id: %s." % str( dataset_id ) )
if check_ownership:
diff -r c09a8456b63e -r 853046b87a5c lib/galaxy/web/controllers/dataset.py
--- a/lib/galaxy/web/controllers/dataset.py Thu Apr 29 19:57:00 2010 -0400
+++ b/lib/galaxy/web/controllers/dataset.py Fri Apr 30 10:15:42 2010 -0400
@@ -307,10 +307,14 @@
composite_extensions.append('html') # for archiving composite datatypes
# DEPRECATION: We still support unencoded ids for backward compatibility
try:
- dataset_id = int( dataset_id )
- except ValueError:
- dataset_id = trans.security.decode_id( dataset_id )
- data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( dataset_id )
+ data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.security.decode_id( dataset_id ) )
+ if data is None:
+ raise ValueError( 'Invalid reference dataset id: %s.' % dataset_id )
+ except:
+ try:
+ data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( int( dataset_id ) )
+ except:
+ data = None
if not data:
raise paste.httpexceptions.HTTPRequestRangeNotSatisfiable( "Invalid reference dataset id: %s." % str( dataset_id ) )
current_user_roles = trans.get_current_user_roles()
1
0

10 May '10
details: http://www.bx.psu.edu/hg/galaxy/rev/c09a8456b63e
changeset: 3717:c09a8456b63e
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Thu Apr 29 19:57:00 2010 -0400
description:
Full Tophat wrapper. All options are implemented, but additional tests are needed.
diffstat:
tools/ngs_rna/tophat_wrapper.py | 216 +++++++++++++++++-----
tools/ngs_rna/tophat_wrapper.xml | 364 ++++++++++++++++++++++++++++++++++----
2 files changed, 483 insertions(+), 97 deletions(-)
diffs (672 lines):
diff -r 436c9d1c5e64 -r c09a8456b63e tools/ngs_rna/tophat_wrapper.py
--- a/tools/ngs_rna/tophat_wrapper.py Wed Apr 28 17:35:02 2010 -0400
+++ b/tools/ngs_rna/tophat_wrapper.py Thu Apr 29 19:57:00 2010 -0400
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-import optparse, os, shutil, sys, tempfile
+import optparse, os, shutil, subprocess, sys, tempfile, fileinput
def stop_err( msg ):
sys.stderr.write( "%s\n" % msg )
@@ -9,72 +9,184 @@
def __main__():
#Parse Command Line
parser = optparse.OptionParser()
- parser.add_option( '-1', '--input1', dest='input1', help='The (forward or single-end) reads file in Sanger FASTQ format' )
- parser.add_option( '-2', '--input2', dest='input2', help='The reverse reads file in Sanger FASTQ format' )
+ parser.add_option( '-p', '--num-threads', dest='num_threads', help='Use this many threads to align reads. The default is 1.' )
+ parser.add_option( '-C', '--coverage-output', dest='coverage_output_file', help='Coverage output file; formate is WIG.' )
+ parser.add_option( '-J', '--junctions-output', dest='junctions_output_file', help='Junctions output file; formate is BED.' )
+ parser.add_option( '-H', '--hits-output', dest='accepted_hits_output_file', help='Accepted hits output file; formate is SAM.' )
+ parser.add_option( '', '--own-file', dest='own_file', help='' )
+ parser.add_option( '-D', '--indexes-path', dest='index_path', help='Indexes directory; location of .ebwt and .fa files.' )
+ parser.add_option( '-r', '--mate-inner-dist', dest='mate_inner_dist', help='This is the expected (mean) inner distance between mate pairs. \
+ For, example, for paired end runs with fragments selected at 300bp, \
+ where each end is 50bp, you should set -r to be 200. There is no default, \
+ and this parameter is required for paired end runs.')
+ parser.add_option( '', '--mate-std-dev', dest='mate_std_dev', help='Standard deviation of distribution on inner distances between male pairs.' )
parser.add_option( '-a', '--min-anchor-length', dest='min_anchor_length',
help='The "anchor length". TopHat will report junctions spanned by reads with at least this many bases on each side of the junction.' )
+ parser.add_option( '-m', '--splice-mismatches', dest='splice_mismatches', help='The maximum number of mismatches that can appear in the anchor region of a spliced alignment.' )
parser.add_option( '-i', '--min-intron-length', dest='min_intron_length',
help='The minimum intron length. TopHat will ignore donor/acceptor pairs closer than this many bases apart.' )
parser.add_option( '-I', '--max-intron-length', dest='max_intron_length',
help='The maximum intron length. When searching for junctions ab initio, TopHat will ignore donor/acceptor pairs farther than this many bases apart, except when such a pair is supported by a split segment alignment of a long read.' )
- parser.add_option( '-s', '--solexa-quals', dest='solexa_quals', help='Use the Solexa scale for quality values in FASTQ files.' )
- parser.add_option( '-S', '--solexa.3-quals', dest='solexa_quals',
- help='As of the Illumina GA pipeline version 1.3, quality scores are encoded in Phred-scaled base-64. Use this option for FASTQ files from pipeline 1.3 or later.' )
- parser.add_option( '-p', '--num-threads', dest='num_threads', help='Use this many threads to align reads. The default is 1.' )
- parser.add_option( '-C', '--coverage-output', dest='coverage_output_file', help='Coverage output file; formate is WIG.' )
- parser.add_option( '-J', '--junctions-output', dest='junctions_output_file', help='Junctions output file; formate is BED.' )
- parser.add_option( '-H', '--hits-output', dest='accepted_hits_output_file', help='Accepted hits output file; formate is SAM.' )
- parser.add_option( '-D', '--indexes-dir', dest='indexes_directory', help='Indexes directory; location of .ebwt and .fa files.' )
- parser.add_option( '-r', '--mate-inner-dist', dest='mate_inner_dist', help='This is the expected (mean) inner distance between mate pairs. \
- For, example, for paired end runs with fragments selected at 300bp, \
- where each end is 50bp, you should set -r to be 200. There is no default, \
- and this parameter is required for paired end runs.')
+ parser.add_option( '-F', '--junction_filter', dest='junction_filter', help='Filter out junctions supported by too few alignments (number of reads divided by average depth of coverage)' )
+ parser.add_option( '-g', '--max_multihits', dest='max_multihits', help='Maximum number of alignments to be allowed' )
+ parser.add_option( '', '--microexon-search', action="store_true", dest='microexon_search', help='With this option, the pipeline will attempt to find alignments incident to microexons. Works only for reads 50bp or longer.')
+ parser.add_option( '', '--closure-search', action="store_true", dest='closure_search', help='Enables the mate pair closure-based search for junctions. Closure-based search should only be used when the expected inner distance between mates is small (<= 50bp)')
+ parser.add_option( '', '--no-closure-search', action="store_false", dest='closure_search' )
+ parser.add_option( '', '--coverage-search', action="store_true", dest='coverage_search', help='Enables the coverage based search for junctions. Use when coverage search is disabled by default (such as for reads 75bp or longer), for maximum sensitivity.')
+ parser.add_option( '', '--no-coverage-search', action="store_false", dest='coverage_search' )
+ parser.add_option( '', '--min-segment-intron', dest='min_segment_intron', help='Minimum intron length that may be found during split-segment search' )
+ parser.add_option( '', '--max-segment-intron', dest='max_segment_intron', help='Maximum intron length that may be found during split-segment search' )
+ parser.add_option( '', '--min-closure-exon', dest='min_closure_exon', help='Minimum length for exonic hops in potential splice graph' )
+ parser.add_option( '', '--min-closure-intron', dest='min_closure_intron', help='Minimum intron length that may be found during closure search' )
+ parser.add_option( '', '--max-closure-intron', dest='max_closure_intron', help='Maximum intron length that may be found during closure search' )
+ parser.add_option( '', '--min-coverage-intron', dest='min_coverage_intron', help='Minimum intron length that may be found during coverage search' )
+ parser.add_option( '', '--max-coverage-intron', dest='max_coverage_intron', help='Maximum intron length that may be found during coverage search' )
+ parser.add_option( '', '--seg-mismatches', dest='seg_mismatches', help='Number of mismatches allowed in each segment alignment for reads mapped independently' )
+ parser.add_option( '', '--seg-length', dest='seg_length', help='Minimum length of read segments' )
+
+ # Wrapper options.
+ parser.add_option( '-1', '--input1', dest='input1', help='The (forward or single-end) reads file in Sanger FASTQ format' )
+ parser.add_option( '-2', '--input2', dest='input2', help='The reverse reads file in Sanger FASTQ format' )
+ parser.add_option( '', '--single-paired', dest='single_paired', help='' )
+ parser.add_option( '', '--settings', dest='settings', help='' )
+
(options, args) = parser.parse_args()
- # Make temp directory for output.
+ #sys.stderr.write('*'*50+'\n'+str(options)+'\n'+'*'*50+'\n')
+
+ # Creat bowtie index if necessary.
+ tmp_index_dir = tempfile.mkdtemp()
+ if options.own_file != 'None':
+ index_path = os.path.join( tmp_index_dir, os.path.split( options.own_file )[1] )
+ cmd_index = 'bowtie-build -f %s %s' % ( options.own_file, index_path )
+ try:
+ tmp = tempfile.NamedTemporaryFile( dir=tmp_index_dir ).name
+ tmp_stderr = open( tmp, 'wb' )
+ proc = subprocess.Popen( args=cmd_index, shell=True, cwd=tmp_index_dir, stderr=tmp_stderr.fileno() )
+ returncode = proc.wait()
+ tmp_stderr.close()
+ # get stderr, allowing for case where it's very large
+ tmp_stderr = open( tmp, 'rb' )
+ stderr = ''
+ buffsize = 1048576
+ try:
+ while True:
+ stderr += tmp_stderr.read( buffsize )
+ if not stderr or len( stderr ) % buffsize != 0:
+ break
+ except OverflowError:
+ pass
+ tmp_stderr.close()
+ if returncode != 0:
+ raise Exception, stderr
+ except Exception, e:
+ if os.path.exists( tmp_index_dir ):
+ shutil.rmtree( tmp_index_dir )
+ stop_err( 'Error indexing reference sequence\n' + str( e ) )
+ else:
+ index_path = options.index_path
+
+ # Build tophat command.
tmp_output_dir = tempfile.mkdtemp()
-
- # Build command.
-
- # Base.
- cmd = "tophat -o %s " % ( tmp_output_dir )
-
- # Add options.
- if options.mate_inner_dist:
- cmd += ( " -r %i" % int ( options.mate_inner_dist ) )
-
- # Add index prefix.
- cmd += " " + options.indexes_directory
-
- # Add input files.
- cmd += " " + options.input1
- if options.mate_inner_dist:
- # Using paired-end reads.
- cmd += " " + options.input2
-
- # Route program output to file.
- cmd += " > %s" % tmp_output_dir + "/std_out.txt"
- # Route program error output to file.
- cmd += " 2> %s" % tmp_output_dir + "/std_err.txt"
-
- # Run.
+ cmd = 'tophat -o %s %s %s %s'
+ reads = options.input1
+ if options.input2 != 'None':
+ reads += ' ' + options.input2
+ opts = '-p %s' % options.num_threads
+ if options.single_paired == 'paired':
+ opts += ' -r %s' % options.mate_inner_dist
+ if options.settings == 'preSet':
+ cmd = cmd % ( tmp_output_dir, opts, index_path, reads )
+ else:
+ try:
+ if int( options.min_anchor_length ) >= 3:
+ opts += ' -a %s' % options.min_anchor_length
+ else:
+ raise Exception, 'Minimum anchor length must be 3 or greater'
+ opts += ' -m %s' % options.splice_mismatches
+ opts += ' -i %s' % options.min_intron_length
+ opts += ' -I %s' % options.max_intron_length
+ if float( options.junction_filter ) != 0.0:
+ opts += ' -F %s' % options.junction_filter
+ opts += ' -g %s' % options.max_multihits
+ if options.coverage_search:
+ opts += ' --coverage-search --min-coverage-intron %s --max-coverage-intron %s' % ( options.min_coverage_intron, options.max_coverage_intron )
+ else:
+ opts += ' --no-coverage-search'
+ if options.closure_search:
+ opts += ' --closure-search --min-closure-exon %s --min-closure-intron %s --max-closure-intron %s' % ( options.min_closure_exon, options.min_closure_intron, options.max_closure_intron )
+ else:
+ opts += ' --no-closure-search'
+ if options.microexon_search:
+ opts += ' --microexon-search'
+ if options.single_paired == 'paired':
+ opts += ' --mate-std-dev %s' % options.mate_std_dev
+ cmd = cmd % ( tmp_output_dir, opts, index_path, reads )
+ except Exception, e:
+ # Clean up temp dirs
+ if os.path.exists( tmp_index_dir ):
+ shutil.rmtree( tmp_index_dir )
+ if os.path.exists( tmp_output_dir ):
+ shutil.rmtree( tmp_output_dir )
+ stop_err( 'Something is wrong with the alignment parameters and the alignment could not be run\n' + str( e ) )
+ print cmd
+
+ # Run
try:
- os.system( cmd )
+ tmp_out = tempfile.NamedTemporaryFile( dir=tmp_output_dir ).name
+ tmp_stdout = open( tmp_out, 'wb' )
+ tmp_err = tempfile.NamedTemporaryFile( dir=tmp_output_dir ).name
+ tmp_stderr = open( tmp_err, 'wb' )
+ proc = subprocess.Popen( args=cmd, shell=True, cwd=tmp_output_dir, stdout=tmp_stdout, stderr=tmp_stderr )
+ returncode = proc.wait()
+ tmp_stderr.close()
+ # get stderr, allowing for case where it's very large
+ tmp_stderr = open( tmp_err, 'rb' )
+ stderr = ''
+ buffsize = 1048576
+ try:
+ while True:
+ stderr += tmp_stderr.read( buffsize )
+ if not stderr or len( stderr ) % buffsize != 0:
+ break
+ except OverflowError:
+ pass
+ tmp_stdout.close()
+ tmp_stderr.close()
+ if returncode != 0:
+ raise Exception, stderr
except Exception, e:
+ # Clean up temp dirs
+ if os.path.exists( tmp_output_dir ):
+ shutil.rmtree( tmp_output_dir )
stop_err( 'Error in tophat:\n' + str( e ) )
# TODO: look for errors in program output.
- # Copy output files from tmp directory to specified files.
+ # Postprocessing: copy output files from tmp directory to specified files. Also need to remove header lines from SAM file.
try:
- shutil.copyfile( tmp_output_dir + "/coverage.wig", options.coverage_output_file )
- shutil.copyfile( tmp_output_dir + "/junctions.bed", options.junctions_output_file )
- shutil.copyfile( tmp_output_dir + "/accepted_hits.sam", options.accepted_hits_output_file )
- except Exception, e:
- stop_err( 'Error in tophat:\n' + str( e ) )
-
- # Clean up temp dirs
- if os.path.exists( tmp_output_dir ):
- shutil.rmtree( tmp_output_dir )
+ try:
+ shutil.copyfile( tmp_output_dir + "/coverage.wig", options.coverage_output_file )
+ shutil.copyfile( tmp_output_dir + "/junctions.bed", options.junctions_output_file )
+
+ # Remove headers from SAM file in place.
+ in_header = True # Headers always at start of file.
+ for line in fileinput.input( tmp_output_dir + "/accepted_hits.sam", inplace=1 ):
+ if in_header and line.startswith("@"):
+ continue
+ else:
+ in_header = False
+ sys.stdout.write( line )
+
+ # Copy SAM File.
+ shutil.copyfile( tmp_output_dir + "/accepted_hits.sam", options.accepted_hits_output_file )
+ except Exception, e:
+ stop_err( 'Error in tophat:\n' + str( e ) )
+ finally:
+ # Clean up temp dirs
+ if os.path.exists( tmp_index_dir ):
+ shutil.rmtree( tmp_index_dir )
+ if os.path.exists( tmp_output_dir ):
+ shutil.rmtree( tmp_output_dir )
if __name__=="__main__": __main__()
diff -r 436c9d1c5e64 -r c09a8456b63e tools/ngs_rna/tophat_wrapper.xml
--- a/tools/ngs_rna/tophat_wrapper.xml Wed Apr 28 17:35:02 2010 -0400
+++ b/tools/ngs_rna/tophat_wrapper.xml Thu Apr 29 19:57:00 2010 -0400
@@ -1,24 +1,104 @@
-<tool id="tophat" name="Tophat" version="1.0.13">
+<tool id="tophat" name="Tophat" version="1.0.0">
<description>Find splice junctions using RNA-seq data</description>
<command interpreter="python">
- tophat_wrapper.py
+ tophat_wrapper.py
+ ## Change this to accomodate the number of threads you have available.
--num-threads="4"
- --coverage-output=$coverage
- --junctions-output=$junctions
+
+ ## Provide outputs.
+ --coverage-output=$coverage
+ --junctions-output=$junctions
--hits-output=$accepted_hits
+
+ ## Handle reference file.
#if $refGenomeSource.genomeSource == "history":
- --indexes-dir=$refGenomeSource.ownFile
+ --own-file=$refGenomeSource.ownFile
+ --indexes-path="None"
#else:
- --indexes-dir=$refGenomeSource.index.value
+ --own-file="None"
+ --indexes-path=$refGenomeSource.index.value
#end if
+
+ ## Are reads single-end or paired?
+ --single-paired=$singlePaired.sPaired
+
+ ## First input file always required.
+ --input1=$singlePaired.input1
+
+ ## Set parms based on whether reads are single-end or paired.
#if $singlePaired.sPaired == "single":
- --input1=$singlePaired.input1
--input2="None"
- #else:
- -r $singlePaired.mean_inner_distance
- --input1=$singlePaired.input1
- --input2=$singlePaired.input2
- #end if
+ -r "None"
+ --settings=$singlePaired.sParams.sSettingsType
+ #if $singlePaired.sParams.sSettingsType == "full":
+ --mate-std-dev="None"
+ -a $singlePaired.sParams.anchor_length
+ -m $singlePaired.sParams.splice_mismatches
+ -i $singlePaired.sParams.min_intron_length
+ -I $singlePaired.sParams.max_intron_length
+ -F $singlePaired.sParams.junction_filter
+ -g $singlePaired.sParams.max_multihits
+ --min-segment-intron $singlePaired.sParams.min_segment_intron
+ --max-segment-intron $singlePaired.sParams.max_segment_intron
+ --seg-mismatches=$singlePaired.sParams.seg_mismatches
+ --seg-length=$singlePaired.sParams.seg_length
+ #if $singlePaired.sParams.closure_search.use_search == "Yes":
+ --closure-search
+ --min-closure-exon $singlePaired.sParams.closure_search.min_closure_exon
+ --min-closure-intron $singlePaired.sParams.closure_search.min_closure_intron
+ --max-closure-intron $singlePaired.sParams.closure_search.max_closure_intron
+ #else:
+ --no-closure-search
+ #end if
+ #if $singlePaired.sParams.coverage_search.use_search == "Yes":
+ --coverage-search
+ --min-coverage-intron $singlePaired.sParams.coverage_search.min_coverage_intron
+ --max-coverage-intron $singlePaired.sParams.coverage_search.max_coverage_intron
+ #else:
+ --no-coverage-search
+ #end if
+ ## No idea why the type conversion is necessary, but it seems to be.
+ #if str ($singlePaired.sParams.microexon_search) == "Yes":
+ --microexon-search
+ #end if
+ #end if
+ #else:
+ --input2=$singlePaired.input2
+ -r $singlePaired.mate_inner_distance
+ --settings=$singlePaired.pParams.pSettingsType
+ #if $singlePaired.pParams.pSettingsType == "full":
+ --mate-std-dev=$singlePaired.pParams.mate_std_dev
+ -a $singlePaired.pParams.anchor_length
+ -m $singlePaired.pParams.splice_mismatches
+ -i $singlePaired.pParams.min_intron_length
+ -I $singlePaired.pParams.max_intron_length
+ -F $singlePaired.pParams.junction_filter
+ -g $singlePaired.pParams.max_multihits
+ --min-segment-intron $singlePaired.pParams.min_segment_intron
+ --max-segment-intron $singlePaired.pParams.max_segment_intron
+ --seg-mismatches=$singlePaired.pParams.seg_mismatches
+ --seg-length=$singlePaired.pParams.seg_length
+ #if $singlePaired.pParams.closure_search.use_search == "Yes":
+ --closure-search
+ --min-closure-exon $singlePaired.pParams.closure_search.min_closure_exon
+ --min-closure-intron $singlePaired.pParams.closure_search.min_closure_intron
+ --max-closure-intron $singlePaired.pParams.closure_search.max_closure_intron
+ #else:
+ --no-closure-search
+ #end if
+ #if $singlePaired.pParams.coverage_search.use_search == "Yes":
+ --coverage-search
+ --min-coverage-intron $singlePaired.pParams.coverage_search.min_coverage_intron
+ --max-coverage-intron $singlePaired.pParams.coverage_search.max_coverage_intron
+ #else:
+ --no-coverage-search
+ #end if
+ ## No idea why the type conversion is necessary, but it seems to be.
+ #if str ($singlePaired.pParams.microexon_search) == "Yes":
+ --microexon-search
+ #end if
+ #end if
+ #end if
</command>
<inputs>
<conditional name="refGenomeSource">
@@ -27,56 +107,219 @@
<option value="history">Use one from the history</option>
</param>
<when value="indexed">
- <param name="index" type="select" label="Select a reference genome" help="If your genome of interest is not listed, contact the Galaxy team">
- <options from_file="bowtie_indices.loc">
- <column name="value" index="1" />
- <column name="name" index="0" />
- </options>
- </param>
- </when>
+ <param name="index" type="select" label="Select a reference genome" help="If your genome of interest is not listed, contact the Galaxy team">
+ <options from_file="bowtie_indices.loc">
+ <column name="value" index="1" />
+ <column name="name" index="0" />
+ </options>
+ </param>
+ </when>
<when value="history">
<param name="ownFile" type="data" format="fasta" metadata_name="dbkey" label="Select the reference genome" />
</when> <!-- history -->
- </conditional> <!-- refGenomeSource -->
+ </conditional> <!-- refGenomeSource -->
<conditional name="singlePaired">
<param name="sPaired" type="select" label="Is this library mate-paired?">
- <option value="single">Single-end</option>
- <option value="paired">Paired-end</option>
+ <option value="single">Single-end</option>
+ <option value="paired">Paired-end</option>
</param>
<when value="single">
- <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/>
+ <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/>
+ <conditional name="sParams">
+ <param name="sSettingsType" type="select" label="TopHat settings to use" help="You can use the default settings or set custom values for any of Tophat's parameters.">
+ <option value="preSet">Use Defaults</option>
+ <option value="full">Full parameter list</option>
+ </param>
+ <when value="preSet" />
+ <!-- Full/advanced parms. -->
+ <when value="full">
+ <param name="anchor_length" type="integer" value="8" label="Anchor length (at least 3)" help="Report junctions spanned by reads with at least this many bases on each side of the junction." />
+ <param name="splice_mismatches" type="integer" value="0" label="Maximum number of mismatches that can appear in the anchor region of spliced alignment" />
+ <param name="min_intron_length" type="integer" value="70" label="The minimum intron length" help="TopHat will ignore donor/acceptor pairs closer than this many bases apart." />
+ <param name="max_intron_length" type="integer" value="500000" label="The maximum intron length" help="When searching for junctions ab initio, TopHat will ignore donor/acceptor pairs farther than this many bases apart, except when such a pair is supported by a split segment alignment of a long read." />
+ <param name="junction_filter" type="float" value="0.15" label="Minimum isoform fraction: filter out junctions supported by too few alignments (number of reads divided by average depth of coverage)" help="0.0 to 1.0 (0 to turn off)" />
+ <param name="max_multihits" type="integer" value="40" label="Maximum number of alignments to be allowed" />
+ <param name="min_segment_intron" type="integer" value="50" label="Minimum intron length that may be found during split-segment (default) search" />
+ <param name="max_segment_intron" type="integer" value="500000" label="Maximum intron length that may be found during split-segment (default) search" />
+ <param name="seg_mismatches" type="integer" value="2" label="Number of mismatches allowed in each segment alignment for reads mapped independently" />
+ <param name="seg_length" type="integer" value="25" label="Minimum length of read segments" />
+ <!-- Closure search. -->
+ <conditional name="closure_search">
+ <param name="use_search" type="select" label="Use Closure Search">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="Yes">
+ <param name="min_closure_exon" type="integer" value="50" label="During closure search for paired end reads, exonic hops in the potential splice graph must be at least this long. The default is 50." />
+ <param name="min_closure_intron" type="integer" value="50" label="Minimum intron length that may be found during closure search" />
+ <param name="max_closure_intron" type="integer" value="5000" label="Maximum intron length that may be found during closure search" />
+ </when>
+ <when value="No" />
+ </conditional>
+ <!-- Coverage search. -->
+ <conditional name="coverage_search">
+ <param name="use_search" type="select" label="Use Coverage Search">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="Yes">
+ <param name="min_coverage_intron" type="integer" value="50" label="Minimum intron length that may be found during coverage search" />
+ <param name="max_coverage_intron" type="integer" value="20000" label="Maximum intron length that may be found during coverage search" />
+ </when>
+ <when value="No" />
+ </conditional>
+ <param name="microexon_search" type="select" label="Use Microexon Search" help="With this option, the pipeline will attempt to find alignments incident to microexons. Works only for reads 50bp or longer.">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ </when> <!-- full -->
+ </conditional> <!-- sParams -->
</when>
<when value="paired">
- <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/>
- <param format="fastqsanger" name="input2" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/>
- <param format="fastqsanger" name="mean_inner_distance" type="integer" value="20" label="Mean Inner Distance between Mate Pairs"/>
+ <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/>
+ <param format="fastqsanger" name="input2" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/>
+ <param name="mate_inner_distance" type="integer" value="20" label="Mean Inner Distance between Mate Pairs" />
+ <conditional name="pParams">
+ <param name="pSettingsType" type="select" label="TopHat settings to use" help="For most mapping needs use Commonly used settings. If you want full control use Full parameter list">
+ <option value="preSet">Commonly used</option>
+ <option value="full">Full parameter list</option>
+ </param>
+ <when value="preSet" />
+ <!-- Full/advanced parms. -->
+ <when value="full">
+ <param name="mate_std_dev" type="integer" value="20" label="Std. Dev for Distance between Mate Pairs" help="The standard deviation for the distribution on inner distances between mate pairs."/>
+ <param name="anchor_length" type="integer" value="8" label="Anchor length (at least 3)" help="Report junctions spanned by reads with at least this many bases on each side of the junction." />
+ <param name="splice_mismatches" type="integer" value="0" label="Maximum number of mismatches that can appear in the anchor region of spliced alignment" />
+ <param name="min_intron_length" type="integer" value="70" label="The minimum intron length" help="TopHat will ignore donor/acceptor pairs closer than this many bases apart." />
+ <param name="max_intron_length" type="integer" value="500000" label="The maximum intron length" help="When searching for junctions ab initio, TopHat will ignore donor/acceptor pairs farther than this many bases apart, except when such a pair is supported by a split segment alignment of a long read." />
+ <param name="junction_filter" type="float" value="0.15" label="Minimum isoform fraction: filter out junctions supported by too few alignments (number of reads divided by average depth of coverage)" help="0.0 to 1.0 (0 to turn off)" />
+ <param name="max_multihits" type="integer" value="40" label="Maximum number of alignments to be allowed" />
+ <param name="min_segment_intron" type="integer" value="50" label="Minimum intron length that may be found during split-segment (default) search" />
+ <param name="max_segment_intron" type="integer" value="500000" label="Maximum intron length that may be found during split-segment (default) search" />
+ <param name="seg_mismatches" type="integer" value="2" label="Number of mismatches allowed in each segment alignment for reads mapped independently" />
+ <param name="seg_length" type="integer" value="25" label="Minimum length of read segments" />
+ <!-- Closure search. -->
+ <conditional name="closure_search">
+ <param name="use_search" type="select" label="Use Closure Search">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="Yes">
+ <param name="min_closure_exon" type="integer" value="50" label="During closure search for paired end reads, exonic hops in the potential splice graph must be at least this long. The default is 50." />
+ <param name="min_closure_intron" type="integer" value="50" label="Minimum intron length that may be found during closure search" />
+ <param name="max_closure_intron" type="integer" value="5000" label="Maximum intron length that may be found during closure search" />
+ </when>
+ <when value="No" />
+ </conditional>
+ <!-- Coverage search. -->
+ <conditional name="coverage_search">
+ <param name="use_search" type="select" label="Use Coverage Search">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="Yes">
+ <param name="min_coverage_intron" type="integer" value="50" label="Minimum intron length that may be found during coverage search" />
+ <param name="max_coverage_intron" type="integer" value="20000" label="Maximum intron length that may be found during coverage search" />
+ </when>
+ <when value="No" />
+ </conditional>
+ <param name="microexon_search" type="select" label="Use Microexon Search" help="With this option, the pipeline will attempt to find alignments incident to microexons. Works only for reads 50bp or longer.">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ </when> <!-- full -->
+ </conditional> <!-- pParams -->
</when>
</conditional>
</inputs>
-
+
<outputs>
- <data format="sam" name="accepted_hits" label="${tool.name} on ${on_string}: accepted_hits"/>
- <data format="wig" name="coverage" label="${tool.name} on ${on_string}: coverage"/>
+ <data format="sam" name="accepted_hits" label="${tool.name} on ${on_string}: accepted_hits"/>
+ <data format="bedgraph" name="coverage" label="${tool.name} on ${on_string}: coverage"/>
<data format="bed" name="junctions" label="${tool.name} on ${on_string}: splice junctions"/>
</outputs>
-
+
<tests>
+<!-- <test>
+ <param name="genomeSource" value="indexed"/>
+ <param name="index" value="equCab2chrM"/>
+ <param name="sPaired" value="single"/>
+ <param name="input1" ftype="fastqsanger" value="tophat_in1.fq"/>
+ <param name="sSettingsType" value="preSet"/>
+--> <!--
+ Can't test this right now because first lines of file are run-specific.
+ <output name="accepted_hits" file="tophat_out1.sam"/>
+ -->
+<!-- <output name="coverage" file="tophat_out2.wig"/>
+ <output name="junctions" file="tophat_out3.bed"/>
+ </test>
+-->
+ <!-- Test using test data: paired-end reads, index from history. -->
<test>
- <param name="genomeSource" value="indexed"/>
- <param name="index" value="test_ref"/>
+ <param name="genomeSource" value="history"/>
+ <param name="ownFile" ftype="fasta" value="tophat_in3.fa"/>
<param name="sPaired" value="paired"/>
<param name="input1" ftype="fastqsanger" value="tophat_in1.fq"/>
<param name="input2" ftype="fastqsanger" value="tophat_in2.fq"/>
- <param name="mean_inner_distance" value="20"/>
- <!--
- Can't test this right now because first lines of file are run-specific.
+ <param name="mate_inner_distance" value="20"/>
+ <param name="pSettingsType" value="preSet"/>
<output name="accepted_hits" file="tophat_out1.sam"/>
- -->
<output name="coverage" file="tophat_out2.wig"/>
<output name="junctions" file="tophat_out3.bed"/>
</test>
- </tests>
-
+<!-- <test>
+ <param name="genomeSource" value="history"/>
+ <param name="ownFile" value="phiX.fasta"/>
+ <param name="sPaired" value="single"/>
+ <param name="input1" ftype="fastqsanger" value="tophat_in1.fq"/>
+ <param name="sSettingsType" value="full"/>
+ <param name="anchor_length" value="8"/>
+ <param name="splice_mismatches" value="0"/>
+ <param name="min_intron_length" value="70"/>
+ <param name="max_intron_length" value="500000"/>
+ <param name="quals_scale" value="default"/>
+ <param name="junction_filter" value="0.15"/>
+ <param name="max_multihits" value="40"/>
+ <param name="min_segment_intron" value="50" />
+ <param name="max_segment_intron" value="500000" />
+ <param name="seg_mismatches" value="2"/>
+ <param name="seg_length" value="25"/>
+--> <!--
+ Can't test this right now because first lines of file are run-specific.
+ <output name="accepted_hits" file="tophat_out1.sam"/>
+ -->
+<!-- <output name="coverage" file="tophat_out2.wig"/>
+ <output name="junctions" file="tophat_out3.bed"/>
+ </test>
+ <test>
+ <param name="genomeSource" value="indexed"/>
+ <param name="index" value="equCab2chrM"/>
+ <param name="sPaired" value="paired"/>
+ <param name="input1" ftype="fastqsanger" value="tophat_in1.fq"/>
+ <param name="input2" ftype="fastqsanger" value="tophat_in2.fq"/>
+ <param name="mate_inner_distance" value="20"/>
+ <param name="pSettingsType" value="full"/>
+ <param name="mate_std_dev" value="20"/>
+ <param name="anchor_length" value="8"/>
+ <param name="splice_mismatches" value="0"/>
+ <param name="min_intron_length" value="70"/>
+ <param name="max_intron_length" value="500000"/>
+ <param name="quals_scale" value="default"/>
+ <param name="junction_filter" value="0.15"/>
+ <param name="max_multihits" value="40"/>
+ <param name="min_coverage_intron" value="50" />
+ <param name="max_coverage_intron" value="20000" />
+ <param name="seg_mismatches" value="2"/>
+ <param name="seg_length" value="25"/>
+--> <!--
+ Can't test this right now because first lines of file are run-specific.
+ <output name="accepted_hits" file="tophat_out1.sam"/>
+ -->
+<!-- <output name="coverage" file="tophat_out2.wig"/>
+ <output name="junctions" file="tophat_out3.bed"/>
+ </test>
+--> </tests>
+
<help>
**Tophat Overview**
@@ -104,11 +347,15 @@
**Outputs**
-Tophat produces three output files::
+Tophat produces three output files:
- coverage.wig -- coverage of reads
- accepted_hits.sam -- reads that were mapped onto genome
- junctions.bed -- splice junctions identified by Tophat
+- coverage.wig -- A UCSC BedGraph_ wigglegram track, showing the depth of coverage at each position, including the spliced read alignments.
+- accepted_hits.sam -- A list of read alignments in SAM_ format.
+- junctions.bed -- A UCSC BED_ track of junctions reported by TopHat. Each junction consists of two connected BED blocks, where each block is as long as the maximal overhang of any read spanning the junction. The score is the number of alignments spanning the junction.
+
+.. _BedGraph: http://genome.ucsc.edu/goldenPath/help/bedgraph.html
+.. _SAM: http://samtools.sourceforge.net/
+.. _BED: http://genome.ucsc.edu/FAQ/FAQformat.html#format1
-------
@@ -122,8 +369,35 @@
This is a list of implemented Tophat options::
- -r This is the expected (mean) inner distance between mate pairs. For, example, for paired end runs with fragments
- selected at 300bp, where each end is 50bp, you should set -r to be 200. There is no default, and this parameter
- is required for paired end runs.
+ -r This is the expected (mean) inner distance between mate pairs. For, example, for paired end runs with fragments
+ selected at 300bp, where each end is 50bp, you should set -r to be 200. There is no default, and this parameter
+ is required for paired end runs.
+ --mate-std-dev INT The standard deviation for the distribution on inner distances between mate pairs. The default is 20bp.
+ -a/--min-anchor-length INT The "anchor length". TopHat will report junctions spanned by reads with at least this many bases on each side of the junction. Note that individual spliced
+ alignments may span a junction with fewer than this many bases on one side. However, every junction involved in spliced alignments is supported by at least one
+ read with this many bases on each side. This must be at least 3 and the default is 8.
+ -m/--splice-mismatches INT The maximum number of mismatches that may appear in the "anchor" region of a spliced alignment. The default is 0.
+ -i/--min-intron-length INT The minimum intron length. TopHat will ignore donor/acceptor pairs closer than this many bases apart. The default is 70.
+ -I/--max-intron-length INT The maximum intron length. When searching for junctions ab initio, TopHat will ignore donor/acceptor pairs farther than this many bases apart, except when such a pair is supported by a split segment alignment of a long read. The default is 500000.
+ -F/--min-isoform-fraction 0.0-1.0 TopHat filters out junctions supported by too few alignments. Suppose a junction spanning two exons, is supported by S reads. Let the average depth of coverage of
+ exon A be D, and assume that it is higher than B. If S / D is less than the minimum isoform fraction, the junction is not reported. A value of zero disables the
+ filter. The default is 0.15.
+ -g/--max-multihits INT Instructs TopHat to allow up to this many alignments to the reference for a given read, and suppresses all alignments for reads with more than this many
+ alignments. The default is 40.
+ --no-closure-search Disables the mate pair closure-based search for junctions. Currently, has no effect - closure search is off by default.
+ --closure-search Enables the mate pair closure-based search for junctions. Closure-based search should only be used when the expected inner distance between mates is small (about or less than 50bp)
+ --no-coverage-search Disables the coverage based search for junctions.
+ --coverage-search Enables the coverage based search for junctions. Use when coverage search is disabled by default (such as for reads 75bp or longer), for maximum sensitivity.
+ --microexon-search With this option, the pipeline will attempt to find alignments incident to microexons. Works only for reads 50bp or longer.
+ --butterfly-search TopHat will use a slower but potentially more sensitive algorithm to find junctions in addition to its standard search. Consider using this if you expect that your experiment produced a lot of reads from pre-mRNA, that fall within the introns of your transcripts.
+ --segment-mismatches Read segments are mapped independently, allowing up to this many mismatches in each segment alignment. The default is 2.
+ --segment-length Each read is cut up into segments, each at least this long. These segments are mapped independently. The default is 25.
+ --min-closure-exon During closure search for paired end reads, exonic hops in the potential splice graph must be at least this long. The default is 50.
+ --min-closure-intron The minimum intron length that may be found during closure search. The default is 50.
+ --max-closure-intron The maximum intron length that may be found during closure search. The default is 5000.
+ --min-coverage-intron The minimum intron length that may be found during coverage search. The default is 50.
+ --max-coverage-intron The maximum intron length that may be found during coverage search. The default is 20000.
+ --min-segment-intron The minimum intron length that may be found during split-segment search. The default is 50.
+ --max-segment-intron The maximum intron length that may be found during split-segment search. The default is 500000.
</help>
</tool>
1
0

10 May '10
details: http://www.bx.psu.edu/hg/galaxy/rev/436c9d1c5e64
changeset: 3716:436c9d1c5e64
user: Kanwei Li <kanwei(a)gmail.com>
date: Wed Apr 28 17:35:02 2010 -0400
description:
trackster: BAM display supports paired-end reads, displays sequence when possible
diffstat:
lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py | 2 +-
lib/galaxy/visualization/tracks/data/bam.py | 34 +-
lib/galaxy/visualization/tracks/data/summary_tree.py | 4 +-
lib/galaxy/visualization/tracks/summary.py | 6 +-
lib/galaxy/web/controllers/tracks.py | 8 +-
static/scripts/packed/trackster.js | 2 +-
static/scripts/trackster.js | 284 +++++----
7 files changed, 185 insertions(+), 155 deletions(-)
diffs (524 lines):
diff -r a5ccb2ba4c74 -r 436c9d1c5e64 lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py
--- a/lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py Wed Apr 28 16:06:58 2010 -0400
+++ b/lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py Wed Apr 28 17:35:02 2010 -0400
@@ -17,7 +17,7 @@
bamfile = csamtools.Samfile( filename=input_fname, mode='rb', index_filename=index_fname )
- st = SummaryTree(block_size=100, levels=4, draw_cutoff=100, detail_cutoff=20)
+ st = SummaryTree(block_size=25, levels=6, draw_cutoff=150, detail_cutoff=30)
for read in bamfile.fetch():
st.insert_range(bamfile.getrname(read.rname), read.pos, read.pos + read.rlen)
diff -r a5ccb2ba4c74 -r 436c9d1c5e64 lib/galaxy/visualization/tracks/data/bam.py
--- a/lib/galaxy/visualization/tracks/data/bam.py Wed Apr 28 16:06:58 2010 -0400
+++ b/lib/galaxy/visualization/tracks/data/bam.py Wed Apr 28 17:35:02 2010 -0400
@@ -33,12 +33,36 @@
if chrom.startswith( 'chr' ):
data = bamfile.fetch( start=start, end=end, reference=chrom[3:] )
else:
- raise
+ return None
# Encode reads as list of dictionaries
results = []
+ paired_pending = {}
for read in data:
- payload = [ str(read.pos) + str(read.seq), read.pos, read.pos + read.rlen, read.seq ]
- results.append(payload)
+ qname = read.qname
+ if read.is_proper_pair:
+ if qname in paired_pending: # one in dict is always first
+ pair = paired_pending[qname]
+ results.append( [ qname, pair['start'], read.pos + read.rlen, read.seq, [pair['start'], pair['end'], pair['seq']], [read.pos, read.pos + read.rlen, read.seq] ] )
+ # results.append( [read.qname, pair['start'], read.pos + read.rlen, qname, [pair['start'], pair['end']], [read.pos, read.pos + read.rlen] ] )
+ del paired_pending[qname]
+ else:
+ paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read.rlen, 'seq': read.seq, 'mate_start': read.mpos, 'rlen': read.rlen }
+ else:
+ results.append( [qname, read.pos, read.pos + read.rlen, read.seq] )
+ # take care of reads whose mates are out of range
+ for qname, read in paired_pending.iteritems():
+ if read['mate_start'] < read['start']:
+ start = read['mate_start']
+ end = read['end']
+ r1 = [read['mate_start'], read['mate_start'] + read['rlen']]
+ r2 = [read['start'], read['end'], read['seq']]
+ else:
+ start = read['start']
+ end = read['mate_start'] + read['rlen']
+ r1 = [read['start'], read['end'], read['seq']]
+ r2 = [read['mate_start'], read['mate_start'] + read['rlen']]
+
+ results.append( [ qname, start, end, read['seq'], r1, r2 ] )
+
bamfile.close()
- return results
-
\ No newline at end of file
+ return results
\ No newline at end of file
diff -r a5ccb2ba4c74 -r 436c9d1c5e64 lib/galaxy/visualization/tracks/data/summary_tree.py
--- a/lib/galaxy/visualization/tracks/data/summary_tree.py Wed Apr 28 16:06:58 2010 -0400
+++ b/lib/galaxy/visualization/tracks/data/summary_tree.py Wed Apr 28 17:35:02 2010 -0400
@@ -38,6 +38,6 @@
if results == "detail":
return None
elif results == "draw":
- return "no_detail", None, None
+ return "no_detail"
else:
- return results, stats["max"], stats["avg"]
+ return results, stats[level]["max"], stats[level]["avg"], stats[level]["delta"]
diff -r a5ccb2ba4c74 -r 436c9d1c5e64 lib/galaxy/visualization/tracks/summary.py
--- a/lib/galaxy/visualization/tracks/summary.py Wed Apr 28 16:06:58 2010 -0400
+++ b/lib/galaxy/visualization/tracks/summary.py Wed Apr 28 17:35:02 2010 -0400
@@ -54,8 +54,10 @@
self.chrom_stats[chrom]["detail_level"] = level
break
else:
- self.chrom_stats[chrom]["max"] = max_val
- self.chrom_stats[chrom]["avg"] = float(max_val) / len(blocks[level])
+ self.chrom_stats[chrom][level] = {}
+ self.chrom_stats[chrom][level]["delta"] = self.block_size ** level
+ self.chrom_stats[chrom][level]["max"] = max_val
+ self.chrom_stats[chrom][level]["avg"] = float(max_val) / len(blocks[level])
cur_best = level
self.chrom_blocks[chrom] = dict([ (key, value) for key, value in blocks.iteritems() if key >= cur_best ])
diff -r a5ccb2ba4c74 -r 436c9d1c5e64 lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py Wed Apr 28 16:06:58 2010 -0400
+++ b/lib/galaxy/web/controllers/tracks.py Wed Apr 28 17:35:02 2010 -0400
@@ -236,12 +236,12 @@
indexer = dataset_type_to_data_provider[data_sources['index']]( dataset.get_converted_dataset(trans, data_sources['index']), dataset )
summary = indexer.get_summary( chrom, low, high, **kwargs )
if summary is not None:
- frequencies, max_v, avg_v = summary
- if frequencies != "no_detail":
- return { "dataset_type": data_sources['index'], "data": frequencies, "max": max_v, "avg": avg_v }
- else:
+ if summary == "no_detail":
kwargs["no_detail"] = True # meh
extra_info = "no_detail"
+ else:
+ frequencies, max_v, avg_v, delta = summary
+ return { "dataset_type": data_sources['index'], "data": frequencies, "max": max_v, "avg": avg_v, "delta": delta }
dataset_type = data_sources['data']
data_provider = dataset_type_to_data_provider[ dataset_type ]( dataset.get_converted_dataset(trans, dataset_type), dataset )
diff -r a5ccb2ba4c74 -r 436c9d1c5e64 static/scripts/packed/trackster.js
--- a/static/scripts/packed/trackster.js Wed Apr 28 16:06:58 2010 -0400
+++ b/static/scripts/packed/trackster.js Wed Apr 28 17:35:02 2010 -0400
@@ -1,1 +1,1 @@
-var DEBUG=false;var DENSITY=1000,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset.",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src="../images/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src="../images/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="../images/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="../images/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}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 Drawer=function(){};$.extend(Drawer.prototype,{intensity:function(b,a,c){},});drawer=new Drawer();var View=function(b,d,c,a){this.vis_id=c;this.dbkey=a;this.title=d;this.chrom=b;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_h!
igh=0;this.center=(this.max_high-this.max_low)/2;this.zoom_factor=3;th
is.zoom_level=0;this.track_id_counter=0};$.extend(View.prototype,{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},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[a]},update_options:function(){var b=$("ul#sortable-ul").sortable("toArray");var d=[];var c=$("#viewport > div").sort(function(g,f){return b.indexOf($(g).attr("id"))>b.indexOf($(f).attr("id"))});$("#viewport > div").remove();$("#viewport").html(c);for(var e in view.tracks){var a=view.tracks[e];if(a.update_options){a.update_options(e)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.center=this.center=(this.max_high-this.max_low)/2;this.zoom_level=0;$(".yaxislabel").remove()},redraw:function(f){this.span=this.max_high-this.max_low;var d=this.spa!
n/Math.pow(this.zoom_factor,this.zoom_level),b=this.center-(d/2),e=b+d;if(b<0){b=0;e=b+d}else{if(e>this.max_high){e=this.max_high;b=e-d}}this.low=Math.floor(b);this.high=Math.ceil(e);this.center=Math.round(this.low+(this.high-this.low)/2);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))));$("#overview-box").css({left:(this.low/this.span)*$("#overview-viewport").width(),width:Math.max(12,((this.high-this.low)/this.span)*$("#overview-viewport").width())}).show();$("#low").val(commatize(this.low));$("#high").val(commatize(this.high));if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(a,b){if(this.max_high===0||this.high-this.low<30){return}if(a){this.center=a/b.width()*(this.h!
igh-this.low)+this.low}this.zoom_level+=1;this.redraw()},zoom_out:func
tion(){if(this.max_high===0){return}if(this.zoom_level<=0){this.zoom_level=0;return}this.zoom_level-=1;this.redraw()}});var Track=function(a,b){this.name=a;this.parent_element=b;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div></div>").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.content_div.css("height","30px");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"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR)}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_N!
OCONVERTER)}else{if(d.data&&d.data.length===0||d.data===null){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(){};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var i=this.view.low,e=this.view.high,f=e-i,d=this.view.resolution;if(DEBUG){$("#debug").text(d+" "+this.view.zoom_res)}var k=$("<div style='position: relative;'></div>");this.content_div.children(":first").remove();this.content_div.append(k);var l=this.content_div.width()/f;var h;var a=Math.floor(i/d/DENSITY);while((a*DENSITY*d)<e){var j=this.content_div.width()+"_"+this.view.zoom_level+"_"+a;var c=this.tile_cache.get(j);if(c){var g=a*DENSITY*d;var b=(g-!
i)*l;if(this.left_offset){b-=this.left_offset}c.css({left:b});k.append
(c);this.max_height=Math.max(this.max_height,c.height())}else{this.delayed_draw(this,j,i,e,a,d,k,l)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)}});var LabelTrack=function(a){Track.call(this,null,a);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute",left:f-1}));a+=g}this.content_div.children(":first").remove!
();this.content_div.append(b)}});var LineTrack=function(c,a,b){this.track_type="LineTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.height_px=100;this.container_div.addClass("line-track");this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(b.min_value!==undefined){this.prefs.min_value=b.min_value}if(b.max_value!==undefined){this.prefs.max_value=b.max_value}if(b.mode!==undefined){this.prefs.mode=b.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){data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_!
maxval").val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.p
refs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div></div>").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(a.prefs.min_value);var d=$("<div></div>").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(a.prefs.max_value);d.css({position:"relative",top:"25px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+55+"px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(o,q,c,e){if(this.vertical_range===undefined){return}var r=q*DENSITY*o,a=DENSITY*o,!
b=$("<canvas class='tile'></canvas>"),u=o+"_"+q;if(this.data_cache.get(u)===undefined){this.get_data(o,q);return}var t=this.data_cache.get(u);if(t===null){return}b.css({position:"absolute",top:0,left:(r-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"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,m=this.vertical_range,s=this.total_frequency,d=this.height_px;n.beginPath();if(t.length>1){var f=Math.ceil((t[1][0]-t[0][0])*e)}else{var f=10}for(var p=0;p<t.length;p++){var j=t[p][0]-r;var h=t[p][1];if(this.prefs.mode=="Intensity"){if(h===null){continue}j=j*e;if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/m*255);n.fillStyle="rgb("+h+","+h+","+h+")";n.fillRect(j,0,f,this.height_px)}else{if(h===null){k=false;continue}else{j=j*e;if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/m*d);if(k){n.lineTo(j,h)}else{n.moveTo(j,h);k=true}}}}n.stroke();c.append(b);return b},gen_options:function(n){var a=$("<div></!
div>").addClass("form-row");var h="track_"+n+"_minval",k="track_"+n+"_
maxval",e="track_"+n+"_mode",l=$("<label></label>").attr("for",h).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),m=$("<input></input>").attr("id",h).val(b),g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(j),d=$("<label></label>").attr("for",e).text("Display mode:"),i=(this.prefs.mode===undefined?"Line":this.prefs.mode),c=$('<select id="'+e+'"><option value="Line" id="mode_Line">Line</option><option value="Intensity" id="mode_Intensity">Intensity</option></select>');c.children("#mode_"+i).attr("selected","selected");return a.append(l).append(m).append(g).append(f).append(d).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_mode option:selected").val();if(a!==this.prefs.min_value||c!==this.prefs.max_value||b!=this.prefs.mode){this.prefs.min_value=parseFloat(a);th!
is.prefs.max_value=parseFloat(c);this.prefs.mode=b;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(c,a,b){this.track_type="FeatureTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.height_px=100;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.default_font="9px Monaco, Lucida Console, monospace";this.left_offset=200;this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.prefs={block_color:"black",label_color:"black",show_counts:false};if(b.block_color!==undefined){this.prefs.block_color=b.block_color}if(b.label_color!==undefined){this.prefs.!
label_color=b.label_color}if(b.show_counts!==undefined){this.prefs.sho
w_counts=b.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.max_low+"_"+a.view.max_high;this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.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},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,g,c){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.s_e_by_tile[a]={}}var m=this.inc_slots[a].w_scale,v=[],h=0,b=$("<canvas></canvas>").get(0).getContext("2d"),n=this.view.max_low;var d,f,x=[];for(var s=0,t=g.length;s<t;s++){var e=g[s],l=e[0];if(this.inc_slots[a][l]!==undefined){h=Math.max(h,this.inc_slots[a][l]);x.push(this.inc_slots[a][l]!
)}else{v.push(s)}}for(var s=0,t=v.length;s<t;s++){var e=g[v[s]];l=e[0],feature_start=e[1],feature_end=e[2],feature_name=e[3];d=Math.floor((feature_start-n)*m);f=Math.ceil((feature_end-n)*m);if(!c){var p=b.measureText(feature_name).width;if(d-p<0){f+=p}else{d-=p}}var r=0;while(true){var o=true;if(this.s_e_by_tile[a][r]!==undefined){for(var q=0,w=this.s_e_by_tile[a][r].length;q<w;q++){var u=this.s_e_by_tile[a][r][q];if(f>u[0]&&d<u[1]){o=false;break}}}if(o){if(this.s_e_by_tile[a][r]===undefined){this.s_e_by_tile[a][r]=[]}this.s_e_by_tile[a][r].push([d,f]);this.inc_slots[a][l]=r;h=Math.max(h,r);break}r++}}return h},draw_tile:function(R,h,m,ae){var z=h*DENSITY*R,X=(h+1)*DENSITY*R,w=DENSITY*R;var ac,ad,p;var Y=z+"_"+X;var ac=this.data_cache.get(Y);if(ac===undefined){this.data_queue[[z,X]]=true;this.get_data(z,X);return}if(ac.dataset_type=="array_tree"){p=30}else{var P=(ac.extra_info==="no_detail");var af=(P?this.vertical_nodetail_px:this.vertical_detail_px);p=this.incremental_slo!
ts(this.view.zoom_res,ac.data,P)*af+15;m.parent().css("height",Math.ma
x(this.height_px,p)+"px");ad=this.inc_slots[this.view.zoom_res]}var a=Math.ceil(w*ae),F=$("<canvas class='tile'></canvas>"),T=this.prefs.label_color,f=this.prefs.block_color,J=this.left_offset;F.css({position:"absolute",top:0,left:(z-this.view.low)*ae-J});F.get(0).width=a+J;F.get(0).height=p;var t=F.get(0).getContext("2d");t.fillStyle=this.prefs.block_color;t.font=this.default_font;t.textAlign="right";var C=55,W=255-C,g=W*2/3;if(ac.dataset_type=="summary_tree"){var L=ac.data;var v=ac.max;var l=ac.avg;if(ac.data.length>2){var b=Math.ceil((L[1][0]-L[0][0])*ae)}else{var b=50}for(var aa=0,s=L.length;aa<s;aa++){var N=Math.ceil((L[aa][0]-z)*ae);var M=L[aa][1];if(!M){continue}var E=Math.floor(W-(M/v)*W);t.fillStyle="rgb("+E+","+E+","+E+")";t.fillRect(N+J,0,b,20);if(this.prefs.show_counts){if(E>g){t.fillStyle="black"}else{t.fillStyle="#ddd"}t.textAlign="center";t.fillText(L[aa][1],N+J+(b/2),12)}}m.append(F);return F}var ac=ac.data;var Z=0;for(var aa=0,s=ac.length;aa<s;aa++){var G=ac!
[aa],D=G[0],ab=G[1],O=G[2],A=G[3];if(ab<=X&&O>=z){var Q=Math.floor(Math.max(0,(ab-z)*ae)),u=Math.ceil(Math.min(a,(O-z)*ae)),K=ad[D]*af;if(P){t.fillRect(Q+J,K+5,u-Q,1)}else{var r=G[4],I=G[5],S=G[6],e=G[7];var q,U,B=null,ag=null;if(I&&S){B=Math.floor(Math.max(0,(I-z)*ae));ag=Math.ceil(Math.min(a,(S-z)*ae))}if(A!==undefined&&ab>z){t.fillStyle=T;if(h===0&&Q-t.measureText(A).width<0){t.textAlign="left";t.fillText(A,u+2+J,K+8)}else{t.textAlign="right";t.fillText(A,Q-2+J,K+8)}t.fillStyle=f}if(e){if(r){if(r=="+"){t.fillStyle=RIGHT_STRAND}else{if(r=="-"){t.fillStyle=LEFT_STRAND}}t.fillRect(Q+J,K,u-Q,10);t.fillStyle=f}for(var Y=0,d=e.length;Y<d;Y++){var n=e[Y],c=Math.floor(Math.max(0,(n[0]-z)*ae)),H=Math.ceil(Math.min(a,(n[1]-z)*ae));if(c>H){continue}q=5;U=3;t.fillRect(c+J,K+U,H-c,q);if(B!==undefined&&!(c>ag||H<B)){q=9;U=1;var V=Math.max(c,B),o=Math.min(H,ag);t.fillRect(V+J,K+U,o-V,q)}}}else{q=9;U=1;t.fillRect(Q+J,K+U,u-Q,q);if(G.strand){if(G.strand=="+"){t.fillStyle=RIGHT_STRAND_INV!
}else{if(G.strand=="-"){t.fillStyle=LEFT_STRAND_INV}}t.fillRect(Q+J,K,
u-Q,10);t.fillStyle=prefs.block_color}}}Z++}}m.append(F);return F},gen_options:function(i){var a=$("<div></div>").addClass("form-row");var e="track_"+i+"_block_color",k=$("<label></label>").attr("for",e).text("Block color:"),l=$("<input></input>").attr("id",e).attr("name",e).val(this.prefs.block_color),j="track_"+i+"_label_color",g=$("<label></label>").attr("for",j).text("Text color:"),h=$("<input></input>").attr("id",j).attr("name",j).val(this.prefs.label_color),f="track_"+i+"_show_count",c=$("<label></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></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.labe!
l_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(c,a,b){FeatureTrack.call(this,c,a,b);this.track_type="ReadTrack"};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
\ No newline at end of file
+var DEBUG=false;var DENSITY=200,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset.",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=5,CONTEXT=$("<canvas></canvas>").get(0).getContext("2d"),RIGHT_STRAND,LEFT_STRAND;var right_img=new Image();right_img.src="../images/visualization/strand_right.png";right_img.onload=function(){RIGHT_STRAND=CONTEXT.createPattern(right_img,"repeat")};var left_img=new Image();left_img.src="../images/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="../images/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="../images/visualization/strand_left_inv.png";left_img_inv.onload=function(){LEFT_STRAND_INV=CONTEXT.createPattern(left_img_inv,"repeat")};function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}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 Drawer=function(){};$.extend(Drawer.prototype,{intensity:function(b,a,c){},});drawer=new Drawer();var View=function(b,d,c,a){this.vis_id=c;this.dbkey=a;this.title=d;this.chrom=b;this.tracks=[];this.label_tracks=[];this.max_low=0;this.max_hi!
gh=0;this.center=(this.max_high-this.max_low)/2;this.zoom_factor=3;thi
s.zoom_level=0;this.track_id_counter=0};$.extend(View.prototype,{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},add_label_track:function(a){a.view=this;this.label_tracks.push(a)},remove_track:function(a){a.container_div.fadeOut("slow",function(){$(this).remove()});delete this.tracks[a]},update_options:function(){var b=$("ul#sortable-ul").sortable("toArray");var d=[];var c=$("#viewport > div").sort(function(g,f){return b.indexOf($(g).attr("id"))>b.indexOf($(f).attr("id"))});$("#viewport > div").remove();$("#viewport").html(c);for(var e in view.tracks){var a=view.tracks[e];if(a.update_options){a.update_options(e)}}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.center=this.center=(this.max_high-this.max_low)/2;this.zoom_level=0;$(".yaxislabel").remove()},redraw:function(f){this.span=this.max_high-this.max_low;var d=this.span!
/Math.pow(this.zoom_factor,this.zoom_level),b=this.center-(d/2),e=b+d;if(b<0){b=0;e=b+d}else{if(e>this.max_high){e=this.max_high;b=e-d}}this.low=Math.floor(b);this.high=Math.ceil(e);this.center=Math.round(this.low+(this.high-this.low)/2);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))));$("#overview-box").css({left:(this.low/this.span)*$("#overview-viewport").width(),width:Math.max(12,((this.high-this.low)/this.span)*$("#overview-viewport").width())}).show();$("#low").val(commatize(this.low));$("#high").val(commatize(this.high));if(!f){for(var c=0,a=this.tracks.length;c<a;c++){if(this.tracks[c].enabled){this.tracks[c].draw()}}for(var c=0,a=this.label_tracks.length;c<a;c++){this.label_tracks[c].draw()}}},zoom_in:function(a,b){if(this.max_high===0||this.high-this.low<30){return}if(a){this.center=a/b.width()*(this.hi!
gh-this.low)+this.low}this.zoom_level+=1;this.redraw()},zoom_out:funct
ion(){if(this.max_high===0){return}if(this.zoom_level<=0){this.zoom_level=0;return}this.zoom_level-=1;this.redraw()}});var Track=function(a,b){this.name=a;this.parent_element=b;this.init_global()};$.extend(Track.prototype,{init_global:function(){this.header_div=$("<div class='track-header'>").text(this.name);this.content_div=$("<div class='track-content'>");this.container_div=$("<div></div>").addClass("track").append(this.header_div).append(this.content_div);this.parent_element.append(this.container_div)},init_each:function(c,b){var a=this;a.enabled=false;a.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.content_div.css("height","30px");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"){a.container_div.addClass("error");a.content_div.text(DATA_ERROR)}else{if(d==="no converter"){a.container_div.addClass("error");a.content_div.text(DATA_NO!
CONVERTER)}else{if(d.data&&d.data.length===0||d.data===null){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(){};$.extend(TiledTrack.prototype,Track.prototype,{draw:function(){var i=this.view.low,e=this.view.high,f=e-i,d=this.view.resolution;if(DEBUG){$("#debug").text(d+" "+this.view.zoom_res)}var k=$("<div style='position: relative;'></div>"),l=this.content_div.width()/f,h;this.content_div.children(":first").remove();this.content_div.append(k),this.max_height=0;var a=Math.floor(i/d/DENSITY);while((a*DENSITY*d)<e){var j=this.content_div.width()+"_"+this.view.zoom_level+"_"+a;var c=this.tile_cache.get(j);if(c){var g=a*DENSITY*d;!
var b=(g-i)*l;if(this.left_offset){b-=this.left_offset}c.css({left:b})
;k.append(c);this.max_height=Math.max(this.max_height,c.height());this.content_div.css("height",this.max_height+"px")}else{this.delayed_draw(this,j,i,e,a,d,k,l)}a+=1}},delayed_draw:function(c,e,a,f,b,d,g,h){setTimeout(function(){if(!(a>c.view.high||f<c.view.low)){tile_element=c.draw_tile(d,b,g,h);if(tile_element){c.tile_cache.set(e,tile_element);c.max_height=Math.max(c.max_height,tile_element.height());c.content_div.css("height",c.max_height+"px")}}},50)}});var LabelTrack=function(a){Track.call(this,null,a);this.track_type="LabelTrack";this.hidden=true;this.container_div.addClass("label-track")};$.extend(LabelTrack.prototype,Track.prototype,{draw:function(){var c=this.view,d=c.high-c.low,g=Math.floor(Math.pow(10,Math.floor(Math.log(d)/Math.log(10)))),a=Math.floor(c.low/g)*g,e=this.content_div.width(),b=$("<div style='position: relative; height: 1.3em;'></div>");while(a<c.high){var f=(a-c.low)/d*e;b.append($("<div class='label'>"+commatize(a)+"</div>").css({position:"absolute!
",left:f-1}));a+=g}this.content_div.children(":first").remove();this.content_div.append(b)}});var LineTrack=function(c,a,b){this.track_type="LineTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.height_px=100;this.container_div.addClass("line-track");this.dataset_id=a;this.data_cache=new Cache(CACHED_DATA);this.tile_cache=new Cache(CACHED_TILES_LINE);this.prefs={min_value:undefined,max_value:undefined,mode:"Line"};if(b.min_value!==undefined){this.prefs.min_value=b.min_value}if(b.max_value!==undefined){this.prefs.max_value=b.max_value}if(b.mode!==undefined){this.prefs.mode=b.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){data=c.data;if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=data.min;a.prefs.max_value=data.max;$("!
#track_"+b+"_minval").val(a.prefs.min_value);$("#track_"+b+"_maxval").
val(a.prefs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.total_frequency=data.total_frequency;$("#linetrack_"+b+"_minval").remove();$("#linetrack_"+b+"_maxval").remove();var e=$("<div></div>").addClass("yaxislabel").attr("id","linetrack_"+b+"_minval").text(a.prefs.min_value);var d=$("<div></div>").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(a.prefs.max_value);d.css({position:"relative",top:"25px"});d.prependTo(a.container_div);e.css({position:"relative",top:a.height_px+55+"px"});e.prependTo(a.container_div)})},get_data:function(d,b){var c=this,a=b*DENSITY*d,f=(b+1)*DENSITY*d,e=d+"_"+b;if(!c.data_queue[e]){c.data_queue[e]=true;$.ajax({url:data_url,dataType:"json",data:{chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution},success:function(g){data=g.data;c.data_cache.set(e,data);delete c.data_queue[e];c.draw()},error:function(h,g,i){console.log(h,g,i)}})}},draw_tile:function(o,q,c,e){if(this.vert!
ical_range===undefined){return}var r=q*DENSITY*o,a=DENSITY*o,b=$("<canvas class='tile'></canvas>"),u=o+"_"+q;if(this.data_cache.get(u)===undefined){this.get_data(o,q);return}var t=this.data_cache.get(u);if(t===null){return}b.css({position:"absolute",top:0,left:(r-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"),k=false,l=this.prefs.min_value,g=this.prefs.max_value,m=this.vertical_range,s=this.total_frequency,d=this.height_px;n.beginPath();if(t.length>1){var f=Math.ceil((t[1][0]-t[0][0])*e)}else{var f=10}for(var p=0;p<t.length;p++){var j=t[p][0]-r;var h=t[p][1];if(this.prefs.mode=="Intensity"){if(h===null){continue}j=j*e;if(h<=l){h=l}else{if(h>=g){h=g}}h=255-Math.floor((h-l)/m*255);n.fillStyle="rgb("+h+","+h+","+h+")";n.fillRect(j,0,f,this.height_px)}else{if(h===null){k=false;continue}else{j=j*e;if(h<=l){h=l}else{if(h>=g){h=g}}h=Math.round(d-(h-l)/m*d);if(k){n.lineTo(j,h)}else{n.moveTo(j,h);k=true}}}}n.stroke();c!
.append(b);return b},gen_options:function(n){var a=$("<div></div>").ad
dClass("form-row");var h="track_"+n+"_minval",k="track_"+n+"_maxval",e="track_"+n+"_mode",l=$("<label></label>").attr("for",h).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),m=$("<input></input>").attr("id",h).val(b),g=$("<label></label>").attr("for",k).text("Max value:"),j=(this.prefs.max_value===undefined?"":this.prefs.max_value),f=$("<input></input>").attr("id",k).val(j),d=$("<label></label>").attr("for",e).text("Display mode:"),i=(this.prefs.mode===undefined?"Line":this.prefs.mode),c=$('<select id="'+e+'"><option value="Line" id="mode_Line">Line</option><option value="Intensity" id="mode_Intensity">Intensity</option></select>');c.children("#mode_"+i).attr("selected","selected");return a.append(l).append(m).append(g).append(f).append(d).append(c)},update_options:function(d){var a=$("#track_"+d+"_minval").val(),c=$("#track_"+d+"_maxval").val(),b=$("#track_"+d+"_mode option:selected").val();if(a!==this.prefs.min_value||c!==this.prefs.max_val!
ue||b!=this.prefs.mode){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(c);this.prefs.mode=b;this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+d+"_minval").text(this.prefs.min_value);$("#linetrack_"+d+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(c,a,b){this.track_type="FeatureTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.height_px=100;this.container_div.addClass("feature-track");this.dataset_id=a;this.zo_slots={};this.show_labels_scale=0.001;this.showing_details=false;this.vertical_detail_px=10;this.vertical_nodetail_px=3;this.default_font="9px Monaco, Lucida Console, monospace";this.left_offset=200;this.inc_slots={};this.data_queue={};this.s_e_by_tile={};this.tile_cache=new Cache(CACHED_TILES_FEATURE);this.data_cache=new Cache(20);this.prefs={block_color:"black",label_color:"black",show_counts:false};if(b.block_color!==undefined){this.prefs.block_!
color=b.block_color}if(b.label_color!==undefined){this.prefs.label_col
or=b.label_color}if(b.show_counts!==undefined){this.prefs.show_counts=b.show_counts}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this,b=a.view.max_low+"_"+a.view.max_high;this.init_each({low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom,resolution:this.view.resolution},function(c){a.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},function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},incremental_slots:function(a,g,c){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.s_e_by_tile[a]={}}var m=this.inc_slots[a].w_scale,v=[],h=0,b=$("<canvas></canvas>").get(0).getContext("2d"),n=this.view.max_low;var d,f,x=[];for(var s=0,t=g.length;s<t;s++){var e=g[s],l=e[0];if(this.inc_slots[a][l]!==undefined){h!
=Math.max(h,this.inc_slots[a][l]);x.push(this.inc_slots[a][l])}else{v.push(s)}}for(var s=0,t=v.length;s<t;s++){var e=g[v[s]];l=e[0],feature_start=e[1],feature_end=e[2],feature_name=e[3];d=Math.floor((feature_start-n)*m);f=Math.ceil((feature_end-n)*m);if(!c){var p=b.measureText(feature_name).width;if(d-p<0){f+=p}else{d-=p}}var r=0;while(true){var o=true;if(this.s_e_by_tile[a][r]!==undefined){for(var q=0,w=this.s_e_by_tile[a][r].length;q<w;q++){var u=this.s_e_by_tile[a][r][q];if(f>u[0]&&d<u[1]){o=false;break}}}if(o){if(this.s_e_by_tile[a][r]===undefined){this.s_e_by_tile[a][r]=[]}this.s_e_by_tile[a][r].push([d,f]);this.inc_slots[a][l]=r;h=Math.max(h,r);break}r++}}return h},rect_or_text:function(n,o,g,f,m,b,d,k,e,i){n.textAlign="center";var j=Math.round(o/2);if(d!==undefined&&o>g){n.fillStyle="#555";n.fillRect(k,i+1,e,9);n.fillStyle="#eee";for(var h=0,l=d.length;h<l;h++){if(b+h>=f&&b+h<=m){var a=Math.floor(Math.max(0,(b+h-f)*o));n.fillText(d[h],a+this.left_offset+j,i+9)}}}else!
{n.fillStyle="#555";n.fillRect(k,i+4,e,3)}},draw_tile:function(W,h,m,a
k){var D=h*DENSITY*W,ac=(h+1)*DENSITY*W,C=DENSITY*W;var aj,r;var ad=D+"_"+ac;var w=this.data_cache.get(ad);if(w===undefined){this.data_queue[[D,ac]]=true;this.get_data(D,ac);return}if(w.dataset_type==="summary_tree"){r=30}else{var U=(w.extra_info==="no_detail");var al=(U?this.vertical_nodetail_px:this.vertical_detail_px);r=this.incremental_slots(this.view.zoom_res,w.data,U)*al+15;m.parent().css("height",Math.max(this.height_px,r)+"px");aj=this.inc_slots[this.view.zoom_res]}var a=Math.ceil(C*ak),K=$("<canvas class='tile'></canvas>"),Y=this.prefs.label_color,f=this.prefs.block_color,O=this.left_offset;K.css({position:"absolute",top:0,left:(D-this.view.low)*ak-O});K.get(0).width=a+O;K.get(0).height=r;var z=K.get(0).getContext("2d"),ah=z.measureText("A").width;z.fillStyle=this.prefs.block_color;z.font=this.default_font;z.textAlign="right";if(w.dataset_type=="summary_tree"){var J,G=55,ab=255-G,g=ab*2/3,Q=w.data,B=w.max,l=w.avg;if(Q.length>2){var b=Math.ceil((Q[1][0]-Q[0][0])*ak)}!
else{var b=50}for(var af=0,v=Q.length;af<v;af++){var S=Math.ceil((Q[af][0]-D)*ak);var R=Q[af][1];if(!R){continue}J=Math.floor(ab-(R/B)*ab);z.fillStyle="rgb("+J+","+J+","+J+")";z.fillRect(S+O,0,b,20);if(this.prefs.show_counts){if(J>g){z.fillStyle="black"}else{z.fillStyle="#ddd"}z.textAlign="center";z.fillText(Q[af][1],S+O+(b/2),12)}}m.append(K);return K}var ai=w.data;var ae=0;for(var af=0,v=ai.length;af<v;af++){var L=ai[af],I=L[0],ag=L[1],T=L[2],E=L[3];if(ag<=ac&&T>=D){var V=Math.floor(Math.max(0,(ag-D)*ak)),A=Math.ceil(Math.min(a,Math.max(0,(T-D)*ak))),P=aj[I]*al;if(w.dataset_type==="bai"){z.fillStyle="#555";if(L[4] instanceof Array){var s=Math.floor(Math.max(0,(L[4][0]-D)*ak)),H=Math.ceil(Math.min(a,Math.max(0,(L[4][1]-D)*ak))),q=Math.floor(Math.max(0,(L[5][0]-D)*ak)),o=Math.ceil(Math.min(a,Math.max(0,(L[5][1]-D)*ak)));if(L[4][1]>=D&&L[4][0]<=ac){this.rect_or_text(z,ak,ah,D,ac,L[4][0],L[4][2],s+O,H-s,P)}if(L[5][1]>=D&&L[5][0]<=ac){this.rect_or_text(z,ak,ah,D,ac,L[5][0],L[5!
][2],q+O,o-q,P)}if(q>H){z.fillStyle="#999";z.fillRect(H+O,P+5,q-H,1)}}
else{z.fillStyle="#555";this.rect_or_text(z,ak,ah,D,ac,ag,E,V+O,A-V,P)}if(!U&&ag>D){z.fillStyle=this.prefs.label_color;if(h===0&&V-z.measureText(E).width<0){z.textAlign="left";z.fillText(I,A+2+O,P+8)}else{z.textAlign="right";z.fillText(I,V-2+O,P+8)}z.fillStyle="#555"}}else{if(w.dataset_type==="interval_index"){if(U){z.fillRect(V+O,P+5,A-V,1)}else{var u=L[4],N=L[5],X=L[6],e=L[7];var t,Z,F=null,am=null;if(N&&X){F=Math.floor(Math.max(0,(N-D)*ak));am=Math.ceil(Math.min(a,Math.max(0,(X-D)*ak)))}if(E!==undefined&&ag>D){z.fillStyle=Y;if(h===0&&V-z.measureText(E).width<0){z.textAlign="left";z.fillText(E,A+2+O,P+8)}else{z.textAlign="right";z.fillText(E,V-2+O,P+8)}z.fillStyle=f}if(e){if(u){if(u=="+"){z.fillStyle=RIGHT_STRAND}else{if(u=="-"){z.fillStyle=LEFT_STRAND}}z.fillRect(V+O,P,A-V,10);z.fillStyle=f}for(var ad=0,d=e.length;ad<d;ad++){var n=e[ad],c=Math.floor(Math.max(0,(n[0]-D)*ak)),M=Math.ceil(Math.min(a,Math.max((n[1]-D)*ak)));if(c>M){continue}t=5;Z=3;z.fillRect(c+O,P+Z,M-c,t);i!
f(F!==undefined&&!(c>am||M<F)){t=9;Z=1;var aa=Math.max(c,F),p=Math.min(M,am);z.fillRect(aa+O,P+Z,p-aa,t)}}}else{t=9;Z=1;z.fillRect(V+O,P+Z,A-V,t);if(L.strand){if(L.strand=="+"){z.fillStyle=RIGHT_STRAND_INV}else{if(L.strand=="-"){z.fillStyle=LEFT_STRAND_INV}}z.fillRect(V+O,P,A-V,10);z.fillStyle=prefs.block_color}}}}}ae++}}m.append(K);return K},gen_options:function(i){var a=$("<div></div>").addClass("form-row");var e="track_"+i+"_block_color",k=$("<label></label>").attr("for",e).text("Block color:"),l=$("<input></input>").attr("id",e).attr("name",e).val(this.prefs.block_color),j="track_"+i+"_label_color",g=$("<label></label>").attr("for",j).text("Text color:"),h=$("<input></input>").attr("id",j).attr("name",j).val(this.prefs.label_color),f="track_"+i+"_show_count",c=$("<label></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></div>").appen!
d(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(c,a,b){FeatureTrack.call(this,c,a,b);this.track_type="ReadTrack";this.vertical_detail_px=10;this.vertical_nodetail_px=5};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
\ No newline at end of file
diff -r a5ccb2ba4c74 -r 436c9d1c5e64 static/scripts/trackster.js
--- a/static/scripts/trackster.js Wed Apr 28 16:06:58 2010 -0400
+++ b/static/scripts/trackster.js Wed Apr 28 17:35:02 2010 -0400
@@ -3,7 +3,7 @@
*/
var DEBUG = false;
-var DENSITY = 1000,
+var DENSITY = 200,
FEATURE_LEVELS = 10,
DATA_ERROR = "There was an error in indexing this dataset.",
DATA_NOCONVERTER = "A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",
@@ -271,16 +271,15 @@
range = high - low,
resolution = this.view.resolution;
-
if (DEBUG) { $("#debug").text(resolution + " " + this.view.zoom_res); }
- var parent_element = $("<div style='position: relative;'></div>");
- this.content_div.children( ":first" ).remove();
- this.content_div.append( parent_element );
+ var parent_element = $("<div style='position: relative;'></div>"),
+ w_scale = this.content_div.width() / range,
+ tile_element;
- var w_scale = this.content_div.width() / range;
-
- var tile_element;
+ this.content_div.children( ":first" ).remove();
+ this.content_div.append( parent_element ),
+ this.max_height = 0;
// Index of first tile that overlaps visible region
var tile_index = Math.floor( low / resolution / DENSITY );
while ( ( tile_index * DENSITY * resolution ) < high ) {
@@ -298,6 +297,7 @@
// Our responsibility to move the element to the new parent
parent_element.append( cached );
this.max_height = Math.max( this.max_height, cached.height() );
+ this.content_div.css("height", this.max_height + "px");
} else {
this.delayed_draw(this, key, low, high, tile_index, resolution, parent_element, w_scale);
}
@@ -311,7 +311,7 @@
if ( tile_element ) {
track.tile_cache.set(key, tile_element);
track.max_height = Math.max( track.max_height, tile_element.height() );
- track.content_div.css( "height", track.max_height + "px");
+ track.content_div.css("height", track.max_height + "px");
}
}
}, 50);
@@ -679,12 +679,30 @@
return highest_slot;
},
+ rect_or_text: function( ctx, w_scale, px_per_char, tile_low, tile_high, feature_start, name, x, x_len, y_center ) {
+ ctx.textAlign = "center";
+ var gap = Math.round(w_scale / 2);
+ if (name !== undefined && w_scale > px_per_char) {
+ ctx.fillStyle = "#555";
+ ctx.fillRect(x, y_center + 1, x_len, 9);
+ ctx.fillStyle = "#eee";
+ for (var c = 0, str_len = name.length; c < str_len; c++) {
+ if (feature_start + c >= tile_low && feature_start + c <= tile_high) {
+ var c_start = Math.floor( Math.max(0, (feature_start + c - tile_low) * w_scale) );
+ ctx.fillText(name[c], c_start + this.left_offset + gap, y_center + 9);
+ }
+ }
+ } else {
+ ctx.fillStyle = "#555";
+ ctx.fillRect(x, y_center + 4, x_len, 3);
+ }
+ },
draw_tile: function( resolution, tile_index, parent_element, w_scale ) {
var tile_low = tile_index * DENSITY * resolution,
tile_high = ( tile_index + 1 ) * DENSITY * resolution,
tile_span = DENSITY * resolution;
// console.log("drawing " + tile_index);
- var data, slots, required_height;
+ var slots, required_height;
/*for (var k in this.data_cache.obj_cache) {
var k_split = k.split("_"), k_low = k_split[0], k_high = k_split[1];
@@ -696,23 +714,22 @@
// var k = this.view.low + '_' + this.view.high;
var k = tile_low + '_' + tile_high;
- var data = this.data_cache.get(k);
+ var result = this.data_cache.get(k);
- if (data === undefined) {
+ if (result === undefined) {
this.data_queue[ [tile_low, tile_high] ] = true;
this.get_data(tile_low, tile_high);
return;
}
- if (data.dataset_type == "array_tree") {
+ if (result.dataset_type === "summary_tree") {
required_height = 30;
- // Blah
} else {
// Calculate new slots incrementally for this new chunk of data and update height if necessary
- var no_detail = (data.extra_info === "no_detail");
+ var no_detail = (result.extra_info === "no_detail");
var y_scale = ( no_detail ? this.vertical_nodetail_px : this.vertical_detail_px );
- required_height = this.incremental_slots( this.view.zoom_res, data.data, no_detail ) * y_scale + 15;
+ required_height = this.incremental_slots( this.view.zoom_res, result.data, no_detail ) * y_scale + 15;
parent_element.parent().css("height", Math.max(this.height_px, required_height) + "px");
slots = this.inc_slots[this.view.zoom_res];
}
@@ -732,20 +749,21 @@
new_canvas.get(0).width = width + left_offset;
new_canvas.get(0).height = required_height;
// console.log(( tile_low - this.view.low ) * w_scale, tile_index, w_scale);
- var ctx = new_canvas.get(0).getContext("2d");
+ var ctx = new_canvas.get(0).getContext("2d"),
+ px_per_char = ctx.measureText("A").width;
ctx.fillStyle = this.prefs.block_color;
ctx.font = this.default_font;
ctx.textAlign = "right";
- var min_color = 55,
- color_span = 255 - min_color,
- color_cutoff = color_span*2/3; // Where text switches from black to white
-
- if (data.dataset_type == "summary_tree") {
- var points = data.data;
- var max = data.max;
- var avg = data.avg;
- if (data.data.length > 2) {
+ if (result.dataset_type == "summary_tree") {
+ var color,
+ min_color = 55,
+ color_span = 255 - min_color,
+ color_cutoff = color_span*2/3, // Where text switches from black to white
+ points = result.data,
+ max = result.max,
+ avg = result.avg;
+ if (points.length > 2) {
var delta_x_px = Math.ceil((points[1][0] - points[0][0]) * w_scale);
} else {
var delta_x_px = 50; // Arbitrary, fix
@@ -756,7 +774,7 @@
var y = points[i][1];
if (!y) { continue; }
- var color = Math.floor( color_span - (y / max) * color_span );
+ color = Math.floor( color_span - (y / max) * color_span );
ctx.fillStyle = "rgb(" +color+ "," +color+ "," +color+ ")";
ctx.fillRect(x + left_offset, 0, delta_x_px, 20);
@@ -770,11 +788,12 @@
ctx.fillText(points[i][1], x + left_offset + (delta_x_px/2), 12);
}
}
+
parent_element.append( new_canvas );
return new_canvas;
}
- var data = data.data;
+ var data = result.data;
var j = 0;
for (var i = 0, len = data.length; i < len; i++) {
var feature = data[i],
@@ -785,80 +804,118 @@
if (feature_start <= tile_high && feature_end >= tile_low) {
var f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ),
- f_end = Math.ceil( Math.min(width, (feature_end - tile_low) * w_scale) ),
+ f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ),
y_center = slots[feature_uid] * y_scale;
-
- // console.log(feature_uid, feature_start, feature_end, f_start, f_end, y_center);
- if (no_detail) {
- ctx.fillRect(f_start + left_offset, y_center + 5, f_end - f_start, 1);
- } else {
- // Showing labels, blocks, details
- var feature_strand = feature[4],
- feature_ts = feature[5],
- feature_te = feature[6],
- feature_blocks = feature[7];
- var thickness, y_start, thick_start = null, thick_end = null;
- if (feature_ts && feature_te) {
- thick_start = Math.floor( Math.max(0, (feature_ts - tile_low) * w_scale) );
- thick_end = Math.ceil( Math.min(width, (feature_te - tile_low) * w_scale) );
+ if (result.dataset_type === "bai") {
+ ctx.fillStyle = "#555";
+ if (feature[4] instanceof Array) {
+ var b1_start = Math.floor( Math.max(0, (feature[4][0] - tile_low) * w_scale) ),
+ b1_end = Math.ceil( Math.min(width, Math.max(0, (feature[4][1] - tile_low) * w_scale)) ),
+ b2_start = Math.floor( Math.max(0, (feature[5][0] - tile_low) * w_scale) ),
+ b2_end = Math.ceil( Math.min(width, Math.max(0, (feature[5][1] - tile_low) * w_scale)) );
+
+ if (feature[4][1] >= tile_low && feature[4][0] <= tile_high) {
+ this.rect_or_text(ctx, w_scale, px_per_char, tile_low, tile_high, feature[4][0], feature[4][2], b1_start + left_offset, b1_end - b1_start, y_center);
+ }
+ if (feature[5][1] >= tile_low && feature[5][0] <= tile_high) {
+ this.rect_or_text(ctx, w_scale, px_per_char, tile_low, tile_high, feature[5][0], feature[5][2], b2_start + left_offset, b2_end - b2_start, y_center);
+ }
+ if (b2_start > b1_end) {
+ ctx.fillStyle = "#999";
+ ctx.fillRect(b1_end + left_offset, y_center + 5, b2_start - b1_end, 1);
+ }
+ } else {
+ ctx.fillStyle = "#555";
+ this.rect_or_text(ctx, w_scale, px_per_char, tile_low, tile_high, feature_start, feature_name, f_start + left_offset, f_end - f_start, y_center);
}
- if (feature_name !== undefined && feature_start > tile_low) {
- ctx.fillStyle = label_color;
+ if (!no_detail && feature_start > tile_low) {
+ // Draw label
+ ctx.fillStyle = this.prefs.label_color;
if (tile_index === 0 && f_start - ctx.measureText(feature_name).width < 0) {
ctx.textAlign = "left";
- ctx.fillText(feature_name, f_end + 2 + left_offset, y_center + 8);
+ ctx.fillText(feature_uid, f_end + 2 + left_offset, y_center + 8);
} else {
ctx.textAlign = "right";
- ctx.fillText(feature_name, f_start - 2 + left_offset, y_center + 8);
+ ctx.fillText(feature_uid, f_start - 2 + left_offset, y_center + 8);
}
- ctx.fillStyle = block_color;
+ ctx.fillStyle = "#555";
}
- if (feature_blocks) {
- // Draw introns
- if (feature_strand) {
- if (feature_strand == "+") {
- ctx.fillStyle = RIGHT_STRAND;
- } else if (feature_strand == "-") {
- ctx.fillStyle = LEFT_STRAND;
+
+ } else if (result.dataset_type === "interval_index") {
+
+ // console.log(feature_uid, feature_start, feature_end, f_start, f_end, y_center);
+ if (no_detail) {
+ ctx.fillRect(f_start + left_offset, y_center + 5, f_end - f_start, 1);
+ } else {
+ // Showing labels, blocks, details
+ var feature_strand = feature[4],
+ feature_ts = feature[5],
+ feature_te = feature[6],
+ feature_blocks = feature[7];
+
+ var thickness, y_start, thick_start = null, thick_end = null;
+ if (feature_ts && feature_te) {
+ thick_start = Math.floor( Math.max(0, (feature_ts - tile_low) * w_scale) );
+ thick_end = Math.ceil( Math.min(width, Math.max(0, (feature_te - tile_low) * w_scale)) );
+ }
+ if (feature_name !== undefined && feature_start > tile_low) {
+ ctx.fillStyle = label_color;
+ if (tile_index === 0 && f_start - ctx.measureText(feature_name).width < 0) {
+ ctx.textAlign = "left";
+ ctx.fillText(feature_name, f_end + 2 + left_offset, y_center + 8);
+ } else {
+ ctx.textAlign = "right";
+ ctx.fillText(feature_name, f_start - 2 + left_offset, y_center + 8);
}
- ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, 10);
ctx.fillStyle = block_color;
}
+ if (feature_blocks) {
+ // Draw introns
+ if (feature_strand) {
+ if (feature_strand == "+") {
+ ctx.fillStyle = RIGHT_STRAND;
+ } else if (feature_strand == "-") {
+ ctx.fillStyle = LEFT_STRAND;
+ }
+ ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, 10);
+ ctx.fillStyle = block_color;
+ }
- for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) {
- var block = feature_blocks[k],
- block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ),
- block_end = Math.ceil( Math.min(width, (block[1] - tile_low) * w_scale) );
- if (block_start > block_end) { continue; }
- // Draw the block
- thickness = 5;
- y_start = 3;
- ctx.fillRect(block_start + left_offset, y_center + y_start, block_end - block_start, thickness);
+ for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) {
+ var block = feature_blocks[k],
+ block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ),
+ block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) );
+ if (block_start > block_end) { continue; }
+ // Draw the block
+ thickness = 5;
+ y_start = 3;
+ ctx.fillRect(block_start + left_offset, y_center + y_start, block_end - block_start, thickness);
- // Draw thick regions: check if block intersects with thick region
- if (thick_start !== undefined && !(block_start > thick_end || block_end < thick_start) ) {
- thickness = 9;
- y_start = 1;
- var block_thick_start = Math.max(block_start, thick_start),
- block_thick_end = Math.min(block_end, thick_end);
- ctx.fillRect(block_thick_start + left_offset, y_center + y_start, block_thick_end - block_thick_start, thickness);
+ // Draw thick regions: check if block intersects with thick region
+ if (thick_start !== undefined && !(block_start > thick_end || block_end < thick_start) ) {
+ thickness = 9;
+ y_start = 1;
+ var block_thick_start = Math.max(block_start, thick_start),
+ block_thick_end = Math.min(block_end, thick_end);
+ ctx.fillRect(block_thick_start + left_offset, y_center + y_start, block_thick_end - block_thick_start, thickness);
+ }
}
- }
- } else {
- // If there are no blocks, we treat the feature as one big exon
- thickness = 9;
- y_start = 1;
- ctx.fillRect(f_start + left_offset, y_center + y_start, f_end - f_start, thickness);
- if ( feature.strand ) {
- if (feature.strand == "+") {
- ctx.fillStyle = RIGHT_STRAND_INV;
- } else if (feature.strand == "-") {
- ctx.fillStyle = LEFT_STRAND_INV;
+ } else {
+ // If there are no blocks, we treat the feature as one big exon
+ thickness = 9;
+ y_start = 1;
+ ctx.fillRect(f_start + left_offset, y_center + y_start, f_end - f_start, thickness);
+ if ( feature.strand ) {
+ if (feature.strand == "+") {
+ ctx.fillStyle = RIGHT_STRAND_INV;
+ } else if (feature.strand == "-") {
+ ctx.fillStyle = LEFT_STRAND_INV;
+ }
+ ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, 10);
+ ctx.fillStyle = prefs.block_color;
}
- ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, 10);
- ctx.fillStyle = prefs.block_color;
}
}
}
@@ -899,62 +956,9 @@
var ReadTrack = function ( name, dataset_id, prefs ) {
FeatureTrack.call( this, name, dataset_id, prefs );
this.track_type = "ReadTrack";
+ this.vertical_detail_px = 10;
+ this.vertical_nodetail_px = 5;
};
$.extend( ReadTrack.prototype, TiledTrack.prototype, FeatureTrack.prototype, {
- /*draw_tile: function( resolution, tile_index, parent_element, w_scale ) {
- if (!this.values) {
- return;
- }
- var tile_low = tile_index * DENSITY * resolution,
- tile_high = ( tile_index + 1 ) * DENSITY * resolution,
- tile_span = DENSITY * resolution;
- // console.log("drawing " + tile_index);
- // Once we zoom in enough, show name labels
- var data, slots, required_height;
- required_height = this.height_px;
- slots = this.zo_slots;
- data = this.values;
-
- // console.log(tile_low, tile_high, tile_length, w_scale);
- var width = Math.ceil( tile_span * w_scale ),
- new_canvas = $("<canvas class='tile'></canvas>");
-
- new_canvas.css({
- position: "absolute",
- top: 0,
- left: ( tile_low - this.view.low ) * w_scale - this.left_offset
- });
- new_canvas.get(0).width = width + this.left_offset;
- new_canvas.get(0).height = required_height;
- // console.log(( tile_low - this.view.low ) * w_scale, tile_index, w_scale);
- var ctx = new_canvas.get(0).getContext("2d");
- ctx.fillStyle = this.prefs.block_color;
- ctx.font = this.default_font;
- ctx.textAlign = "right";
- var px_per_char = ctx.measureText("A").width;
-
- var j = 0;
- for (var i = 0, len = data.length; i < len; i++) {
- var feature = data[i];
- if (feature.start <= tile_high && feature.end >= tile_low) {
- var f_start = Math.floor( Math.max(0, (feature.start - tile_low) * w_scale) ),
- f_end = Math.ceil( Math.min(width, (feature.end - tile_low) * w_scale) ),
- y_center = slots[feature.uid] * this.vertical_detail_px;
-
- var thickness, y_start, thick_start = null, thick_end = null;
- if (w_scale > px_per_char) {
- for (var c = 0, str_len = feature.name.length; c < str_len; c++) {
- var c_start = Math.floor( Math.max(0, (feature.start + c - tile_low) * w_scale) );
- ctx.fillText(feature.name[c], c_start + this.left_offset, y_center + 8);
- }
- } else {
- ctx.fillRect(f_start + this.left_offset, y_center + 4, f_end - f_start, 3);
- }
- }
- }
-
- parent_element.append( new_canvas );
- return new_canvas;
- }*/
});
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/a5ccb2ba4c74
changeset: 3715:a5ccb2ba4c74
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Wed Apr 28 16:06:58 2010 -0400
description:
Another rev on cuffcompare wrapper.
diffstat:
tools/ngs_rna/cuffcompare_wrapper.py | 16 +++++++++++-----
tools/ngs_rna/cuffcompare_wrapper.xml | 24 +++++++++++++++++++-----
2 files changed, 30 insertions(+), 10 deletions(-)
diffs (83 lines):
diff -r b70d9444f29f -r a5ccb2ba4c74 tools/ngs_rna/cuffcompare_wrapper.py
--- a/tools/ngs_rna/cuffcompare_wrapper.py Wed Apr 28 14:54:55 2010 -0400
+++ b/tools/ngs_rna/cuffcompare_wrapper.py Wed Apr 28 16:06:58 2010 -0400
@@ -13,6 +13,8 @@
parser.add_option( '-R', action="store_true", dest='ignore_nonoverlap', help='If -r was specified, this option causes cuffcompare to ignore reference transcripts that are not overlapped by any transcript in one of cuff1.gtf,...,cuffN.gtf. Useful for ignoring annotated transcripts that are not present in your RNA-Seq samples and thus adjusting the "sensitivity" calculation in the accuracy report written in the transcripts accuracy file' )
# Wrapper / Galaxy options.
+ parser.add_option( '-1', dest='input1')
+ parser.add_option( '-2', dest='input2')
parser.add_option( '-A', '--transcripts-accuracy-output', dest='transcripts_accuracy_output_file', help='' )
parser.add_option( '-B', '--transcripts-combined-output', dest='transcripts_combined_output_file', help='' )
parser.add_option( '-C', '--transcripts-tracking-output', dest='transcripts_tracking_output_file', help='' )
@@ -37,9 +39,10 @@
print cmd
# Add input files.
- if type(args) is list:
- args = " ".join(args)
- cmd += " " + args
+ cmd += " %s" % options.input1
+ two_inputs = ( options.input2 != None)
+ if two_inputs:
+ cmd += " %s" % options.input2
# Run command.
try:
@@ -76,8 +79,11 @@
try:
try:
shutil.copyfile( tmp_output_dir + "/cc_output", options.transcripts_accuracy_output_file )
- shutil.copyfile( tmp_output_dir + "/cc_output.combined.gtf", options.transcripts_combined_output_file )
- shutil.copyfile( tmp_output_dir + "/cc_output.tracking", options.transcripts_tracking_output_file )
+ if two_inputs:
+ shutil.copyfile( tmp_output_dir + "/cc_output.combined.gtf", options.transcripts_combined_output_file )
+ shutil.copyfile( tmp_output_dir + "/cc_output.tracking", options.transcripts_tracking_output_file )
+
+ # TODO: also copy *.tmap, *.refmap to outputs?
except Exception, e:
stop_err( 'Error in cuffcompare:\n' + str( e ) )
finally:
diff -r b70d9444f29f -r a5ccb2ba4c74 tools/ngs_rna/cuffcompare_wrapper.xml
--- a/tools/ngs_rna/cuffcompare_wrapper.xml Wed Apr 28 14:54:55 2010 -0400
+++ b/tools/ngs_rna/cuffcompare_wrapper.xml Wed Apr 28 16:06:58 2010 -0400
@@ -3,20 +3,34 @@
<command interpreter="python">
cuffcompare_wrapper.py
--transcripts-accuracy-output=$transcripts_accuracy
- --transcripts-combined-output=$transcripts_combined
- --transcripts-tracking-output=$transcripts_tracking
+ #if $second_gtf.use_second_gtf == "Yes":
+ --transcripts-combined-output=$transcripts_combined
+ --transcripts-tracking-output=$transcripts_tracking
+ #end if
#if $annotation.use_ref_annotation == "Yes":
-r $annotation.reference_annotation
#if $annotation.ignore_nonoverlapping_reference:
-R
#end if
#end if
- $input1
- $input2
+ -1 $input1
+ #if $second_gtf.use_second_gtf == "Yes":
+ -2 $second_gtf.input2
+ #end if
</command>
<inputs>
<param format="gtf" name="input1" type="data" label="GTF file produced by Cufflinks" help=""/>
- <param format="gtf" name="input2" type="data" label="GTF file produced by Cufflinks" help=""/>
+ <conditional name="second_gtf">
+ <param name="use_second_gtf" type="select" label="Use Another GTF file producted by Cufflinks?">
+ <option value="No">No</option>
+ <option value="Yes">Yes</option>
+ </param>
+ <when value="Yes">
+ <param format="gtf" name="input2" type="data" label="GTF file produced by Cufflinks" help=""/>
+ </when>
+ <when value="No">
+ </when>
+ </conditional>
<conditional name="annotation">
<param name="use_ref_annotation" type="select" label="Use Reference Annotation">
<option value="No">No</option>
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/b70d9444f29f
changeset: 3714:b70d9444f29f
user: rc
date: Wed Apr 28 14:54:55 2010 -0400
description:
lims:
fixed role selection bug in request_type permissions
diffstat:
templates/admin/requests/request_type_permissions.mako | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diffs (12 lines):
diff -r c63fad1c7d3c -r b70d9444f29f templates/admin/requests/request_type_permissions.mako
--- a/templates/admin/requests/request_type_permissions.mako Wed Apr 28 14:20:24 2010 -0400
+++ b/templates/admin/requests/request_type_permissions.mako Wed Apr 28 14:54:55 2010 -0400
@@ -20,7 +20,7 @@
var out_select = '#' + action + '_out_select';
return !$( in_select + ' option:selected' ).remove().appendTo( out_select );
});
- $( 'form#edit_role_associations' ).submit( function() {
+ $( 'form#request_type_permissions' ).submit( function() {
$( '.in_select option' ).each(function( i ) {
$( this ).attr( "selected", "selected" );
});
1
0

10 May '10
details: http://www.bx.psu.edu/hg/galaxy/rev/c63fad1c7d3c
changeset: 3713:c63fad1c7d3c
user: Nate Coraor <nate(a)bx.psu.edu>
date: Wed Apr 28 14:20:24 2010 -0400
description:
Community: Display tool tarball contents on the view page and allow streaming contents directly from the tarball
diffstat:
lib/galaxy/web/framework/base.py | 7 +++
lib/galaxy/webapps/community/controllers/common.py | 3 +
lib/galaxy/webapps/community/controllers/tool.py | 16 ++++++-
static/images/silk/page_white.png | 0
templates/webapps/community/tool/edit_tool.mako | 42 ++++++++++-------
templates/webapps/community/tool/view_tool.mako | 49 ++++++++++++++++++++-
6 files changed, 98 insertions(+), 19 deletions(-)
diffs (224 lines):
diff -r 811b4794da70 -r c63fad1c7d3c lib/galaxy/web/framework/base.py
--- a/lib/galaxy/web/framework/base.py Wed Apr 28 12:47:44 2010 -0400
+++ b/lib/galaxy/web/framework/base.py Wed Apr 28 14:20:24 2010 -0400
@@ -7,6 +7,7 @@
import logging
import os.path
import sys
+import tarfile
from Cookie import SimpleCookie
@@ -135,6 +136,12 @@
elif isinstance( body, types.FileType ):
# Stream the file back to the browser
return send_file( start_response, trans, body )
+ elif isinstance( body, tarfile.ExFileObject ):
+ # Stream the tarfile member back to the browser
+ body = iterate_file( body )
+ start_response( trans.response.wsgi_status(),
+ trans.response.wsgi_headeritems() )
+ return body
else:
start_response( trans.response.wsgi_status(),
trans.response.wsgi_headeritems() )
diff -r 811b4794da70 -r c63fad1c7d3c lib/galaxy/webapps/community/controllers/common.py
--- a/lib/galaxy/webapps/community/controllers/common.py Wed Apr 28 12:47:44 2010 -0400
+++ b/lib/galaxy/webapps/community/controllers/common.py Wed Apr 28 14:20:24 2010 -0400
@@ -1,3 +1,4 @@
+import tarfile
from galaxy.web.base.controller import *
#from galaxy.web.controllers.admin import get_user, get_group, get_role
from galaxy.webapps.community import model
@@ -79,8 +80,10 @@
status='error' ) )
tool = get_tool( trans, id )
categories = [ tca.category for tca in tool.categories ]
+ tool_file_contents = tarfile.open( tool.file_name, 'r' ).getnames()
return trans.fill_template( '/webapps/community/tool/view_tool.mako',
tool=tool,
+ tool_file_contents=tool_file_contents,
categories=categories,
cntrller=cntrller,
message=message,
diff -r 811b4794da70 -r c63fad1c7d3c lib/galaxy/webapps/community/controllers/tool.py
--- a/lib/galaxy/webapps/community/controllers/tool.py Wed Apr 28 12:47:44 2010 -0400
+++ b/lib/galaxy/webapps/community/controllers/tool.py Wed Apr 28 14:20:24 2010 -0400
@@ -1,4 +1,4 @@
-import sys, os, operator, string, shutil, re, socket, urllib, time, logging, mimetypes
+import os, logging, urllib, tarfile
from galaxy.web.base.controller import *
from galaxy.webapps.community import model
@@ -249,3 +249,17 @@
trans.response.headers['Content-Length'] = int( os.stat( tool.file_name ).st_size )
trans.response.headers['Content-Disposition'] = 'attachment; filename=%s' % tool.download_file_name
return open( tool.file_name )
+ @web.expose
+ def view_tool_file( self, trans, **kwd ):
+ params = util.Params( kwd )
+ id = params.get( 'id', None )
+ if not id:
+ return trans.response.send_redirect( web.url_for( controller='tool',
+ action='browse_tools',
+ message='Select a tool to download',
+ status='error' ) )
+ tool = get_tool( trans, id )
+ tool_file_name = urllib.unquote_plus( kwd['file_name'] )
+ tool_file = tarfile.open( tool.file_name ).extractfile( tool_file_name )
+ trans.response.set_content_type( 'text/plain' )
+ return tool_file
diff -r 811b4794da70 -r c63fad1c7d3c static/images/silk/page_white.png
Binary file static/images/silk/page_white.png has changed
diff -r 811b4794da70 -r c63fad1c7d3c templates/webapps/community/tool/edit_tool.mako
--- a/templates/webapps/community/tool/edit_tool.mako Wed Apr 28 12:47:44 2010 -0400
+++ b/templates/webapps/community/tool/edit_tool.mako Wed Apr 28 14:20:24 2010 -0400
@@ -45,24 +45,24 @@
<%def name="title()">Edit Tool</%def>
-<h2>Edit ${tool.name} <em>${tool.description}</em></h2>
+<h2>Edit Tool: ${tool.name} <em>${tool.description}</em></h2>
%if message:
${render_msg( message, status )}
%endif
%if cntrller == 'admin' or ( tool.is_new() and trans.user == tool.user ):
- <div class="toolForm">
- <div class="toolFormTitle">${tool.name}
- <a id="tool-${tool.id}-popup" class="popup-arrow" style="display: none;">▼</a>
- <div popupmenu="tool-${tool.id}-popup">
- <a class="action-button" href="${h.url_for( controller='common', action='view_tool', id=trans.app.security.encode_id( tool.id ), cntrller=cntrller )}">View information</a>
- <a class="action-button" href="${h.url_for( controller='common', action='manage_categories', id=trans.app.security.encode_id( tool.id ), cntrller=cntrller )}">Manage categories</a>
- <a class="action-button" href="${h.url_for( controller='common', action='upload_new_tool_version', id=trans.app.security.encode_id( tool.id ), cntrller=cntrller )}">Upload a new version</a>
- <a class="action-button" href="${h.url_for( controller='tool', action='download_tool', id=trans.app.security.encode_id( tool.id ) )}">Download tool</a>
+ <form id="edit_tool" name="edit_tool" action="${h.url_for( controller='common', action='edit_tool' )}" method="post">
+ <div class="toolForm">
+ <div class="toolFormTitle">${tool.name}
+ <a id="tool-${tool.id}-popup" class="popup-arrow" style="display: none;">▼</a>
+ <div popupmenu="tool-${tool.id}-popup">
+ <a class="action-button" href="${h.url_for( controller='common', action='view_tool', id=trans.app.security.encode_id( tool.id ), cntrller=cntrller )}">View information</a>
+ <a class="action-button" href="${h.url_for( controller='common', action='manage_categories', id=trans.app.security.encode_id( tool.id ), cntrller=cntrller )}">Manage categories</a>
+ <a class="action-button" href="${h.url_for( controller='common', action='upload_new_tool_version', id=trans.app.security.encode_id( tool.id ), cntrller=cntrller )}">Upload a new version</a>
+ <a class="action-button" href="${h.url_for( controller='tool', action='download_tool', id=trans.app.security.encode_id( tool.id ) )}">Download tool</a>
+ </div>
</div>
- </div>
- <form id="edit_tool" name="edit_tool" action="${h.url_for( controller='common', action='edit_tool' )}" method="post">
<div class="toolFormBody">
<input type="hidden" name="id" value="${trans.app.security.encode_id( tool.id )}"/>
<input type="hidden" name="cntrller" value="${cntrller}"/>
@@ -85,6 +85,9 @@
<input type="submit" id="edit_tool_button" name="edit_tool_button" value="Save">
</div>
</div>
+ </div>
+ <p/>
+ <div class="toolForm">
<div class="toolFormTitle">Manage categories</div>
<div class="toolFormBody">
<div class="form-row">
@@ -103,7 +106,10 @@
<input type="submit" id="edit_tool_button" name="edit_tool_button" value="Save"/>
</div>
</div>
- </form>
+ </div>
+ </form>
+ <p/>
+ <div class="toolForm">
%if tool.is_new():
<div class="toolFormTitle">Get approval for publishing</div>
<div class="toolFormBody">
@@ -113,11 +119,13 @@
<div class="form-row">
<input type="submit" name="approval_button" value="Submit for approval"/>
</div>
- <div class="toolParamHelp" style="clear: both;">
- Tools must be approved before they are made available to others in the community. After you have submitted
- your tool to be published, you will no longer be able to modify it, so make sure to save the information in
- each of the forms above before submitting for approval.
- </div>
+ <div class="form-row">
+ <div class="toolParamHelp" style="clear: both;">
+ Tools must be approved before they are made available to others in the community. After you have submitted
+ your tool to be published, you will no longer be able to modify it, so make sure the information above is
+ correct and has been saved before submitting for approval.
+ </div>
+ </div>
</form>
</div>
%endif
diff -r 811b4794da70 -r c63fad1c7d3c templates/webapps/community/tool/view_tool.mako
--- a/templates/webapps/community/tool/view_tool.mako Wed Apr 28 12:47:44 2010 -0400
+++ b/templates/webapps/community/tool/view_tool.mako Wed Apr 28 14:20:24 2010 -0400
@@ -2,6 +2,7 @@
<%
from galaxy.web.framework.helpers import time_ago
+ from urllib import quote_plus
if cntrller in [ 'tool' ]:
can_edit = trans.app.security_agent.can_edit_item( trans.user, tool )
@@ -16,9 +17,37 @@
%>
<%inherit file="${inherit(context)}"/>
+<%def name="stylesheets()">
+ ${parent.stylesheets()}
+ <style type="text/css">
+ ul.fileBrowser,
+ ul.toolFile {
+ margin-left: 0;
+ padding-left: 0;
+ list-style: none;
+ }
+ ul.fileBrowser {
+ margin-left: 20px;
+ }
+ .fileBrowser li,
+ .toolFile li {
+ padding-left: 20px;
+ background-repeat: no-repeat;
+ background-position: 0;
+ min-height: 20px;
+ }
+ .toolFile li {
+ background-image: url( ${h.url_for( '/static/images/silk/page_white_compressed.png' )} );
+ }
+ .fileBrowser li {
+ background-image: url( ${h.url_for( '/static/images/silk/page_white.png' )} );
+ }
+ </style>
+</%def>
+
<%def name="title()">View Tool</%def>
-<h2>View ${tool.name} <em>${tool.description}</em></h2>
+<h2>View Tool: ${tool.name} <em>${tool.description}</em></h2>
%if message:
${render_msg( message, status )}
@@ -71,3 +100,21 @@
</div>
</div>
</div>
+
+<p/>
+
+<div class="toolForm">
+ <div class="toolFormTitle">Tool Contents</div>
+ <div class="toolFormBody">
+ <div class="form-row">
+ <ul class="toolFile">
+ <li><a href="${h.url_for( controller='tool', action='download_tool', id=trans.app.security.encode_id( tool.id ) )}">${tool.download_file_name}</a></li>
+ <ul class="fileBrowser">
+ %for name in tool_file_contents:
+ <li><a href="${h.url_for( controller='tool', action='view_tool_file', id=trans.app.security.encode_id( tool.id ), file_name=quote_plus( name ) )}">${name}</a></li>
+ %endfor
+ </ul>
+ </ul>
+ </div>
+ </div>
+</div>
1
0

10 May '10
details: http://www.bx.psu.edu/hg/galaxy/rev/811b4794da70
changeset: 3712:811b4794da70
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Wed Apr 28 12:47:44 2010 -0400
description:
Allow automatic creation of GALAXY_URL for 'data_source' tools; add 'data_source_async' tool type which inherits from 'data_source' type, but generates a different GALAXY_URL. Backwards compatibility fix for datasource tools that have default tool_id configured, but which are now only using GALAXY_URL in the tool configuration.
diffstat:
lib/galaxy/tools/__init__.py | 17 ++++++++++++++++-
lib/galaxy/web/controllers/tool_runner.py | 11 ++++++++++-
2 files changed, 26 insertions(+), 2 deletions(-)
diffs (64 lines):
diff -r cdbffdf2dbf7 -r 811b4794da70 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py Wed Apr 28 12:30:32 2010 -0400
+++ b/lib/galaxy/tools/__init__.py Wed Apr 28 12:47:44 2010 -0400
@@ -1583,6 +1583,15 @@
class DataSourceTool( Tool ):
tool_type = 'data_source'
+
+ def _build_GALAXY_URL_parameter( self ):
+ return ToolParameter.build( self, ElementTree.XML( '<param name="GALAXY_URL" type="baseurl" value="/tool_runner?tool_id=%s" />' % self.id ) )
+
+ def parse_inputs( self, root ):
+ Tool.parse_inputs( self, root )
+ if 'GALAXY_URL' not in self.inputs:
+ self.inputs[ 'GALAXY_URL' ] = self._build_GALAXY_URL_parameter()
+
def exec_before_job( self, app, inp_data, out_data, param_dict={} ):
#TODO: Allow for a generic way for all Tools to have output dataset properties be set to input parameter values
#as defined in a tool XML
@@ -1646,6 +1655,12 @@
self.sa_session.add( data )
self.sa_session.flush()
+class AsyncDataSourceTool( DataSourceTool ):
+ tool_type = 'data_source_async'
+
+ def _build_GALAXY_URL_parameter( self ):
+ return ToolParameter.build( self, ElementTree.XML( '<param name="GALAXY_URL" type="baseurl" value="/async/%s" />' % self.id ) )
+
class DataDestinationTool( Tool ):
tool_type = 'data_destination'
@@ -1665,7 +1680,7 @@
#load tool_type to ToolClass mappings
tool_types = {}
-for tool_class in [ Tool, DataDestinationTool, SetMetadataTool, DataSourceTool ]:
+for tool_class in [ Tool, DataDestinationTool, SetMetadataTool, DataSourceTool, AsyncDataSourceTool ]:
tool_types[ tool_class.tool_type ] = tool_class
# ---- Utility classes to be factored out -----------------------------------
diff -r cdbffdf2dbf7 -r 811b4794da70 lib/galaxy/web/controllers/tool_runner.py
--- a/lib/galaxy/web/controllers/tool_runner.py Wed Apr 28 12:30:32 2010 -0400
+++ b/lib/galaxy/web/controllers/tool_runner.py Wed Apr 28 12:47:44 2010 -0400
@@ -43,9 +43,18 @@
return trans.response.send_redirect( url_for( "/static/welcome.html" ) )
# Load the tool
toolbox = self.get_toolbox()
- tool = toolbox.tools_by_id.get( tool_id, None )
+ #Backwards compatibility for datasource tools that have default tool_id configured, but which are now using only GALAXY_URL
+ if isinstance( tool_id, list ):
+ tool_ids = tool_id
+ else:
+ tool_ids = [ tool_id ]
+ for tool_id in tool_ids:
+ tool = toolbox.tools_by_id.get( tool_id, None )
+ if tool:
+ break
# No tool matching the tool id, display an error (shouldn't happen)
if not tool:
+ tool_id = ','.join( tool_ids )
log.error( "index called with tool id '%s' but no such tool exists", tool_id )
trans.log_event( "Tool id '%s' does not exist" % tool_id )
return "Tool '%s' does not exist, kwd=%s " % (tool_id, kwd)
1
0

10 May '10
details: http://www.bx.psu.edu/hg/galaxy/rev/cdbffdf2dbf7
changeset: 3711:cdbffdf2dbf7
user: Nate Coraor <nate(a)bx.psu.edu>
date: Wed Apr 28 12:30:32 2010 -0400
description:
A few grid hacks and community tool browser enhancements
diffstat:
lib/galaxy/web/framework/helpers/grids.py | 8 +-
lib/galaxy/webapps/community/controllers/tool.py | 100 +++++++++++++-
templates/grid_base.mako | 9 +-
templates/webapps/community/category/create_category.mako | 2 +-
templates/webapps/community/index.mako | 5 +-
5 files changed, 110 insertions(+), 14 deletions(-)
diffs (242 lines):
diff -r a5e19a623de5 -r cdbffdf2dbf7 lib/galaxy/web/framework/helpers/grids.py
--- a/lib/galaxy/web/framework/helpers/grids.py Wed Apr 28 11:50:17 2010 -0400
+++ b/lib/galaxy/web/framework/helpers/grids.py Wed Apr 28 12:30:32 2010 -0400
@@ -290,7 +290,9 @@
if self.format:
value = self.format( value )
return value
- def get_link( self, trans, grid, item ):
+ def get_link( self, trans, grid, item, filter_params ):
+ # FIXME: filter_params is only here so we can do grid filtering from
+ # column links. remove once a better way is created.
if self.link and self.link( item ):
return self.link( item )
return None
@@ -447,7 +449,7 @@
class PublicURLColumn( TextColumn ):
""" Column displays item's public URL based on username and slug. """
- def get_link( self, trans, grid, item ):
+ def get_link( self, trans, grid, item, filter_params ):
if item.user.username and item.slug:
return dict( action='display_by_username_and_slug', username=item.user.username, slug=item.slug )
elif not item.user.username:
@@ -483,7 +485,7 @@
if item.published:
sharing_statuses.append( "Published" )
return ", ".join( sharing_statuses )
- def get_link( self, trans, grid, item ):
+ def get_link( self, trans, grid, item, filter_params ):
if not item.deleted and ( item.users_shared_with or item.importable or item.published ):
return dict( operation="share or publish", id=item.id )
return None
diff -r a5e19a623de5 -r cdbffdf2dbf7 lib/galaxy/webapps/community/controllers/tool.py
--- a/lib/galaxy/webapps/community/controllers/tool.py Wed Apr 28 11:50:17 2010 -0400
+++ b/lib/galaxy/webapps/community/controllers/tool.py Wed Apr 28 12:30:32 2010 -0400
@@ -20,9 +20,33 @@
if tool.categories:
rval = ''
for tca in tool.categories:
- rval = '%s%s<br/>' % ( rval, tca.category.name )
+ rval += '%s<br/>\n' % tca.category.name
return rval
return 'not set'
+ def filter( self, trans, user, query, column_filter ):
+ # Category.name conflicts with Tool.name, so we have to make our own filter
+ def get_single_filter( filter ):
+ return func.lower( model.Category.name ).like( "%" + filter.lower() + "%" )
+ if column_filter == 'All':
+ pass
+ elif isinstance( column_filter, list ):
+ clause_list = []
+ for filter in column_filter:
+ clause_list.append( get_single_filter( filter ) )
+ query = query.filter( or_( *clause_list ) )
+ else:
+ query = query.filter( get_single_filter( column_filter ) )
+ return query
+ def get_link( self, trans, grid, tool, filter_params ):
+ if tool.categories:
+ filter_params['f-category'] = []
+ for tca in tool.categories:
+ filter_params['f-category'].append( tca.category.name )
+ if len( filter_params['f-category'] ) == 1:
+ filter_params['f-category'] = filter_params['f-category'][0]
+ filter_params['advanced-search'] = 'True'
+ return filter_params
+ return None
class StateColumn( grids.GridColumn ):
def get_value( self, trans, grid, tool ):
state = tool.state()
@@ -51,7 +75,11 @@
return accepted_filters
class UserColumn( grids.TextColumn ):
def get_value( self, trans, grid, tool ):
- return tool.user.email
+ return tool.user.username
+ def get_link( self, trans, grid, tool, filter_params ):
+ filter_params['f-username'] = tool.user.username
+ filter_params['advanced-search'] = 'True'
+ return filter_params
# Grid definition
title = "Tools"
model_class = model.Tool
@@ -64,9 +92,14 @@
link=( lambda item: dict( operation="View Tool", id=item.id, cntrller='tool', webapp="community" ) ),
attach_popup=True,
filterable="advanced" ),
- CategoryColumn( "Category",
- key="category",
- model_class=model.Category,
+ CategoryColumn( "Categories",
+ key="category",
+ model_class=model.Tool,
+ attach_popup=False,
+ filterable="advanced" ),
+ UserColumn( "Uploaded By",
+ key="username",
+ model_class=model.User,
attach_popup=False,
filterable="advanced" ),
StateColumn( "State",
@@ -92,6 +125,48 @@
grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
]
+ default_filter = dict( name="All", deleted="False", username="All" )
+ num_rows_per_page = 50
+ preserve_state = False
+ use_paging = True
+ def build_initial_query( self, session ):
+ return session.query( self.model_class ).outerjoin( model.ToolCategoryAssociation ).outerjoin( model.Category )
+ def apply_default_filter( self, trans, query, **kwargs ):
+ return query.filter( self.model_class.deleted==False )
+
+class ToolCategoryListGrid( grids.Grid ):
+ class NameColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, category ):
+ return category.name
+ class DescriptionColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, category ):
+ return category.description
+ # Grid definition
+ title = "Tool Categories"
+ model_class = model.Category
+ template='/webapps/community/category/grid.mako'
+ default_sort_key = "name"
+ columns = [
+ NameColumn( "Name",
+ key="name",
+ model_class=model.Category,
+ link=( lambda item: dict( operation="Browse Category", id=item.id, webapp="community" ) ),
+ attach_popup=False,
+ filterable="advanced" ),
+ DescriptionColumn( "Description",
+ key="description",
+ model_class=model.Category,
+ attach_popup=False,
+ filterable="advanced" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search",
+ cols_to_filter=[ columns[0], columns[1] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ standard_filters = [
+ grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
+ ]
default_filter = dict( name="All", deleted="False" )
num_rows_per_page = 50
preserve_state = False
@@ -103,6 +178,7 @@
class ToolBrowserController( BaseController ):
+ tool_category_list_grid = ToolCategoryListGrid()
tool_list_grid = ToolListGrid()
@web.expose
@@ -112,6 +188,20 @@
status = params.get( 'status', 'done' )
return trans.fill_template( '/webapps/community/index.mako', message=message, status=status )
@web.expose
+ def browse_tool_categories( self, trans, **kwargs ):
+ if 'operation' in kwargs:
+ operation = kwargs['operation'].lower()
+ if operation == "browse category":
+ category_id = int( trans.app.security.decode_id( kwargs['id'] ) )
+ category = trans.sa_session.query( model.Category ).get( category_id )
+ del kwargs['id']
+ del kwargs['operation']
+ kwargs['f-category'] = category.name
+ return trans.response.send_redirect( web.url_for( controller='tool',
+ action='browse_tools',
+ **kwargs ) )
+ return self.tool_category_list_grid( trans, **kwargs )
+ @web.expose
def browse_tools( self, trans, **kwargs ):
if 'operation' in kwargs:
operation = kwargs['operation'].lower()
diff -r a5e19a623de5 -r cdbffdf2dbf7 templates/grid_base.mako
--- a/templates/grid_base.mako Wed Apr 28 11:50:17 2010 -0400
+++ b/templates/grid_base.mako Wed Apr 28 12:30:32 2010 -0400
@@ -801,8 +801,12 @@
%for column in grid.columns:
%if column.visible:
<%
+ # Get filter params for generating filter links
+ filter_params = {}
+ for k, v in cur_filter_dict.items():
+ filter_params['f-' + k] = v
# Link
- link = column.get_link( trans, grid, item )
+ link = column.get_link( trans, grid, item, filter_params )
if link:
href = url( **link )
else:
@@ -827,10 +831,9 @@
cls = "menubutton"
if column.attach_popup and href:
cls = "menubutton split"
-
%>
%if href:
- <td><div id="${id}" class="${cls}" style="float: left;"><a class="label" href="${href}">${v}</a></td>
+ <td><div id="${id}" class="${cls}" style="float: left;"><a class="label" href="${href}">${v}</a></div></td>
%else:
<td><div id="${id}" class="${cls}"><label for="${encoded_id}">${v}</label></div></td>
%endif
diff -r a5e19a623de5 -r cdbffdf2dbf7 templates/webapps/community/category/create_category.mako
--- a/templates/webapps/community/category/create_category.mako Wed Apr 28 11:50:17 2010 -0400
+++ b/templates/webapps/community/category/create_category.mako Wed Apr 28 12:30:32 2010 -0400
@@ -15,7 +15,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Create Role</div>
+ <div class="toolFormTitle">Create Category</div>
<div class="toolFormBody">
<form name="create_category_form" id="create_category_form" action="${h.url_for( action='create_category' )}" method="post" >
<div class="form-row">
diff -r a5e19a623de5 -r cdbffdf2dbf7 templates/webapps/community/index.mako
--- a/templates/webapps/community/index.mako Wed Apr 28 11:50:17 2010 -0400
+++ b/templates/webapps/community/index.mako Wed Apr 28 12:30:32 2010 -0400
@@ -29,7 +29,8 @@
</div>
<div class="toolSectionBody">
<div class="toolSectionBg">
- <div class="toolTitle"><a href="${h.url_for( controller='tool', action='browse_tools' )}" target="galaxy_main">Browse tools</a></div>
+ <div class="toolTitle"><a href="${h.url_for( controller='tool', action='browse_tool_categories' )}" target="galaxy_main">Browse tools by category</a></div>
+ <div class="toolTitle"><a href="${h.url_for( controller='tool', action='browse_tools' )}" target="galaxy_main">Browse all tools</a></div>
</div>
</div>
<div class="toolSectionBody">
@@ -53,7 +54,7 @@
if trans.app.config.require_login and not trans.user:
center_url = h.url_for( controller='user', action='login', message=message, status=status )
else:
- center_url = h.url_for( controller='tool', action='browse_tools', message=message, status=status )
+ center_url = h.url_for( controller='tool', action='browse_tool_categories', message=message, status=status )
%>
<iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${center_url}"> </iframe>
</%def>
1
0