galaxy-dev
Threads by month
- ----- 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
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
April 2010
- 37 participants
- 148 discussions
details: http://www.bx.psu.edu/hg/galaxy/rev/0890f7bf9d49
changeset: 3562:0890f7bf9d49
user: Kanwei Li <kanwei(a)gmail.com>
date: Thu Mar 25 15:21:57 2010 -0400
description:
trackster:
- New summary tree data structure that specializes in aggregation at defined levels
- BED converter for summary_tree
- Feature tracks now have a summary display when there are a lot of things to be rendered on screen, but will display simple lines and full detailed view as you zoom in and can fit more on screen
- Added option to display number of features in a region of summary view
- Line tracks can now be displayed as intensity
- Pack scripts
diffstat:
datatypes_conf.xml.sample | 5 +-
lib/galaxy/datatypes/binary.py | 2 +-
lib/galaxy/datatypes/converters/bam_to_array_tree_converter.py | 45 --
lib/galaxy/datatypes/converters/bam_to_array_tree_converter.xml | 15 -
lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py | 45 ++
lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.xml | 15 +
lib/galaxy/datatypes/converters/bed_to_array_tree_converter.py | 29 -
lib/galaxy/datatypes/converters/bed_to_array_tree_converter.xml | 14 -
lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.py | 25 +
lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.xml | 14 +
lib/galaxy/datatypes/interval.py | 2 +-
lib/galaxy/visualization/tracks/data/array_tree.py | 74 +--
lib/galaxy/visualization/tracks/data/interval_index.py | 32 +-
lib/galaxy/visualization/tracks/data/summary_tree.py | 37 +
lib/galaxy/visualization/tracks/summary.py | 88 ++++
lib/galaxy/web/controllers/tracks.py | 19 +-
lib/galaxy/web/controllers/visualization.py | 4 +-
static/scripts/packed/galaxy.workflow_editor.canvas.js | 2 +-
static/scripts/packed/trackster.js | 2 +-
static/scripts/trackster.js | 210 +++++----
templates/tracks/browser.mako | 2 +-
21 files changed, 397 insertions(+), 284 deletions(-)
diffs (1067 lines):
diff -r 44f2713a7279 -r 0890f7bf9d49 datatypes_conf.xml.sample
--- a/datatypes_conf.xml.sample Wed Mar 24 15:13:57 2010 -0400
+++ b/datatypes_conf.xml.sample Thu Mar 25 15:21:57 2010 -0400
@@ -5,14 +5,14 @@
<datatype extension="axt" type="galaxy.datatypes.sequence:Axt" display_in_upload="true"/>
<datatype extension="bam" type="galaxy.datatypes.binary:Bam" mimetype="application/octet-stream" display_in_upload="true">
<converter file="bam_to_bai.xml" target_datatype="bai"/>
- <converter file="bam_to_array_tree_converter.xml" target_datatype="array_tree"/>
+ <converter file="bam_to_summary_tree_converter.xml" target_datatype="summary_tree"/>
<display file="ucsc/bam.xml" />
</datatype>
<datatype extension="bed" type="galaxy.datatypes.interval:Bed" display_in_upload="true">
<converter file="bed_to_gff_converter.xml" target_datatype="gff"/>
<converter file="interval_to_coverage.xml" target_datatype="coverage"/>
<converter file="bed_to_interval_index_converter.xml" target_datatype="interval_index"/>
- <converter file="bed_to_array_tree_converter.xml" target_datatype="array_tree"/>
+ <converter file="bed_to_summary_tree_converter.xml" target_datatype="summary_tree"/>
<converter file="bed_to_genetrack_converter.xml" target_datatype="genetrack"/>
<!-- <display file="ucsc/interval_as_bed.xml" /> -->
<display file="genetrack.xml" />
@@ -80,6 +80,7 @@
<converter file="wiggle_to_simple_converter.xml" target_datatype="interval"/>
</datatype>
<datatype extension="array_tree" type="galaxy.datatypes.data:Data" />
+ <datatype extension="summary_tree" type="galaxy.datatypes.data:Data" />
<datatype extension="interval_index" type="galaxy.datatypes.data:Data" />
<!-- Start EMBOSS tools -->
<datatype extension="acedb" type="galaxy.datatypes.data:Text"/>
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/binary.py
--- a/lib/galaxy/datatypes/binary.py Wed Mar 24 15:13:57 2010 -0400
+++ b/lib/galaxy/datatypes/binary.py Thu Mar 25 15:21:57 2010 -0400
@@ -139,7 +139,7 @@
except:
return "Binary bam alignments file (%s)" % ( data.nice_size( dataset.get_size() ) )
def get_track_type( self ):
- return "ReadTrack", ["bai", "array_tree"]
+ return "ReadTrack", ["bai", "summary_tree"]
class Binseq( Binary ):
"""Class describing a zip archive of binary sequence files"""
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/converters/bam_to_array_tree_converter.py
--- a/lib/galaxy/datatypes/converters/bam_to_array_tree_converter.py Wed Mar 24 15:13:57 2010 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import division
-
-import sys
-from galaxy import eggs
-import pkg_resources; pkg_resources.require( "bx-python" ); pkg_resources.require( "pysam" )
-
-from pysam import csamtools
-from bx.arrays.array_tree import *
-
-BLOCK_SIZE = 1000
-
-class BamReader:
- def __init__( self, input_fname, index_fname ):
- self.bamfile = csamtools.Samfile( filename=input_fname, mode='rb', index_filename=index_fname )
- self.iterator = self.bamfile.fetch()
-
- def __iter__( self ):
- return self
-
- def __next__( self ):
- while True:
- read = self.iterator.next()
- return read.rname, read.mpos, read.pos + read.rlen, None, mapq
-
-
-def main():
-
- input_fname = sys.argv[1]
- index_fname = sys.argv[2]
- out_fname = sys.argv[3]
-
- reader = BamReader( input_fname, index_fname )
-
- # Fill array from reader
- d = array_tree_dict_from_reader( reader, {}, block_size = BLOCK_SIZE )
-
- for array_tree in d.itervalues():
- array_tree.root.build_summary()
-
- FileArrayTreeDict.dict_to_file( d, open( out_fname, "w" ), no_leaves=True )
-
-if __name__ == "__main__":
- main()
\ No newline at end of file
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/converters/bam_to_array_tree_converter.xml
--- a/lib/galaxy/datatypes/converters/bam_to_array_tree_converter.xml Wed Mar 24 15:13:57 2010 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<tool id="CONVERTER_bam_to_array_tree_0" name="Convert BAM to Array Tree" version="1.0.0">
-<!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
- <command interpreter="python">bam_to_array_tree_converter.py $input1 $output1</command>
- <inputs>
- <page>
- <param format="bam" name="input1" type="data" label="Choose BAM file"/>
- <param format="bai" name="index" type="data" label="BAM index file"/>
- </page>
- </inputs>
- <outputs>
- <data format="array_tree" name="output1"/>
- </outputs>
- <help>
- </help>
-</tool>
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py Thu Mar 25 15:21:57 2010 -0400
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+from __future__ import division
+
+import sys
+from galaxy import eggs
+import pkg_resources; pkg_resources.require( "bx-python" ); pkg_resources.require( "pysam" )
+
+from pysam import csamtools
+from bx.arrays.array_tree import *
+
+BLOCK_SIZE = 1000
+
+class BamReader:
+ def __init__( self, input_fname, index_fname ):
+ self.bamfile = csamtools.Samfile( filename=input_fname, mode='rb', index_filename=index_fname )
+ self.iterator = self.bamfile.fetch()
+
+ def __iter__( self ):
+ return self
+
+ def __next__( self ):
+ while True:
+ read = self.iterator.next()
+ return read.rname, read.mpos, read.pos + read.rlen, None, mapq
+
+
+def main():
+
+ input_fname = sys.argv[1]
+ index_fname = sys.argv[2]
+ out_fname = sys.argv[3]
+
+ reader = BamReader( input_fname, index_fname )
+
+ # Fill array from reader
+ d = array_tree_dict_from_reader( reader, {}, block_size = BLOCK_SIZE )
+
+ for array_tree in d.itervalues():
+ array_tree.root.build_summary()
+
+ FileArrayTreeDict.dict_to_file( d, open( out_fname, "w" ), no_leaves=True )
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.xml Thu Mar 25 15:21:57 2010 -0400
@@ -0,0 +1,15 @@
+<tool id="CONVERTER_bam_to_summary_tree_0" name="Convert BAM to Summary Tree" version="1.0.0">
+<!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
+ <command interpreter="python">bam_to_summary_tree_converter.py $input1 $output1</command>
+ <inputs>
+ <page>
+ <param format="bam" name="input1" type="data" label="Choose BAM file"/>
+ <param format="bai" name="index" type="data" label="BAM index file"/>
+ </page>
+ </inputs>
+ <outputs>
+ <data format="summary_tree" name="output1"/>
+ </outputs>
+ <help>
+ </help>
+</tool>
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/converters/bed_to_array_tree_converter.py
--- a/lib/galaxy/datatypes/converters/bed_to_array_tree_converter.py Wed Mar 24 15:13:57 2010 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import division
-
-import sys
-from galaxy import eggs
-import pkg_resources; pkg_resources.require( "bx-python" )
-from bx.arrays.array_tree import *
-from bx.arrays.bed import BedReader
-
-BLOCK_SIZE = 1000
-
-def main():
-
- input_fname = sys.argv[1]
- out_fname = sys.argv[2]
-
- reader = BedReader( open( input_fname ) )
-
- # Fill array from reader
- d = array_tree_dict_from_reader( reader, {}, block_size = BLOCK_SIZE )
-
- for array_tree in d.itervalues():
- array_tree.root.build_summary()
-
- FileArrayTreeDict.dict_to_file( d, open( out_fname, "w" ), no_leaves=True )
-
-if __name__ == "__main__":
- main()
\ No newline at end of file
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/converters/bed_to_array_tree_converter.xml
--- a/lib/galaxy/datatypes/converters/bed_to_array_tree_converter.xml Wed Mar 24 15:13:57 2010 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<tool id="CONVERTER_bed_to_array_tree_0" name="Convert BED to Array Tree" version="1.0.0">
-<!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
- <command interpreter="python">bed_to_array_tree_converter.py $input1 $output1</command>
- <inputs>
- <page>
- <param format="bed" name="input1" type="data" label="Choose BED file"/>
- </page>
- </inputs>
- <outputs>
- <data format="array_tree" name="output1"/>
- </outputs>
- <help>
- </help>
-</tool>
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.py Thu Mar 25 15:21:57 2010 -0400
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+
+from __future__ import division
+
+import sys
+from galaxy import eggs
+import pkg_resources; pkg_resources.require( "bx-python" )
+from galaxy.visualization.tracks.summary import *
+from bx.arrays.bed import BedReader
+
+def main():
+
+ input_fname = sys.argv[1]
+ out_fname = sys.argv[2]
+
+ reader = BedReader( open( input_fname ) )
+
+ st = SummaryTree(block_size=100, levels=4, draw_cutoff=100, detail_cutoff=20)
+ for chrom, chrom_start, chrom_end, name, score in reader:
+ st.insert_range(chrom, chrom_start, chrom_end)
+
+ st.write(out_fname)
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.xml Thu Mar 25 15:21:57 2010 -0400
@@ -0,0 +1,14 @@
+<tool id="CONVERTER_bed_to_summary_tree_0" name="Convert BED to Summary Tree" version="1.0.0">
+<!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
+ <command interpreter="python">bed_to_summary_tree_converter.py $input1 $output1</command>
+ <inputs>
+ <page>
+ <param format="bed" name="input1" type="data" label="Choose BED file"/>
+ </page>
+ </inputs>
+ <outputs>
+ <data format="summary_tree" name="output1"/>
+ </outputs>
+ <help>
+ </help>
+</tool>
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/datatypes/interval.py
--- a/lib/galaxy/datatypes/interval.py Wed Mar 24 15:13:57 2010 -0400
+++ b/lib/galaxy/datatypes/interval.py Thu Mar 25 15:21:57 2010 -0400
@@ -508,7 +508,7 @@
except: return False
def get_track_type( self ):
- return "FeatureTrack", ["interval_index", "array_tree"]
+ return "FeatureTrack", ["interval_index", "summary_tree"]
class BedStrict( Bed ):
"""Tab delimited data in strict BED format - no non-standard columns allowed"""
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/visualization/tracks/data/array_tree.py
--- a/lib/galaxy/visualization/tracks/data/array_tree.py Wed Mar 24 15:13:57 2010 -0400
+++ b/lib/galaxy/visualization/tracks/data/array_tree.py Thu Mar 25 15:21:57 2010 -0400
@@ -3,26 +3,13 @@
"""
import pkg_resources; pkg_resources.require( "bx-python" )
-try:
- from bx.arrays.array_tree import FileArrayTreeDict
-except:
- pass
+from bx.arrays.array_tree import FileArrayTreeDict
from math import floor, ceil, log, pow
-import logging
-logger = logging.getLogger(__name__)
-
-# Maybe this should be included in the datatype itself, so users can add their
-# own types to the browser as long as they return the right format of data?
-
-SUMMARIZE_N = 200
class ArrayTreeDataProvider( object ):
def __init__( self, dataset, original_dataset ):
self.dataset = dataset
- # def calc_resolution(self, start, end, density):
- # return pow( 10, ceil( log( (end - start) / density , 10 ) ) )
-
def get_stats( self, chrom ):
f = open( self.dataset.file_name )
d = FileArrayTreeDict( f )
@@ -52,8 +39,8 @@
if n != n: # NaN != NaN
return None
else:
- return float(n)
-
+ return float(n)
+
def get_data( self, chrom, start, end, **kwargs ):
f = open( self.dataset.file_name )
d = FileArrayTreeDict( f )
@@ -61,7 +48,7 @@
# Get the right chromosome
try:
chrom_array_tree = d[chrom]
- except KeyError:
+ except:
f.close()
return None
@@ -70,53 +57,26 @@
end = int( end )
resolution = max(1, ceil(float(kwargs['resolution'])))
- level = int( ceil( log( resolution, block_size ) ) )
+ level = int( floor( log( resolution, block_size ) ) )
level = max( level, 0 )
stepsize = block_size ** level
# Is the requested level valid?
assert 0 <= level <= chrom_array_tree.levels
- if "frequencies" in kwargs:
- if level <= 0:
- # Low level enough to always display features
- f.close()
- return None
+ results = []
+ for block_start in range( start, end, stepsize * block_size ):
+ # print block_start
+ # Return either data point or a summary depending on the level
+ indexes = range( block_start, block_start + stepsize * block_size, stepsize )
+ if level > 0:
+ s = chrom_array_tree.get_summary( block_start, level )
+ if s is not None:
+ results.extend( zip( indexes, map( self.float_nan, s.sums / s.counts ) ) )
else:
- # Round to nearest bin
- bin_start = start // (stepsize * block_size) * (stepsize * block_size)
-
- indexes = range( bin_start, (bin_start + stepsize * block_size), stepsize )
- summary = chrom_array_tree.get_summary( bin_start, level )
- if summary:
- results = zip( indexes, map( int, summary.frequencies ) )
- filtered = filter(lambda tup: tup[0] >= start and tup[0] <= end, results)
- sums = 0
- max_f = 0
- for tup in filtered:
- sums += tup[1]
- max_f = max(max_f, tup[1])
-
- if max_f > 10000:
- f.close()
- return filtered, int(sums), float(sums)/len(filtered)
- f.close()
- return None
-
- else:
- results = []
- for block_start in range( start, end, stepsize * block_size ):
- # print block_start
- # Return either data point or a summary depending on the level
- indexes = range( block_start, block_start + stepsize * block_size, stepsize )
- if level > 0:
- s = chrom_array_tree.get_summary( block_start, level )
- if s:
- results.extend( zip( indexes, map( self.float_nan, s.sums / s.counts ) ) )
- else:
- l = chrom_array_tree.get_leaf( block_start )
- if l:
- results.extend( zip( indexes, map( self.float_nan, l ) ) )
+ l = chrom_array_tree.get_leaf( block_start )
+ if l is not None:
+ results.extend( zip( indexes, map( self.float_nan, l ) ) )
f.close()
return results
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/visualization/tracks/data/interval_index.py
--- a/lib/galaxy/visualization/tracks/data/interval_index.py Wed Mar 24 15:13:57 2010 -0400
+++ b/lib/galaxy/visualization/tracks/data/interval_index.py Thu Mar 25 15:21:57 2010 -0400
@@ -1,6 +1,8 @@
"""
Interval index data provider for the Galaxy track browser.
Kanwei Li, 2009
+
+Payload format: [ uid (offset), start, end, name, strand, thick_start, thick_end, blocks ]
"""
import pkg_resources; pkg_resources.require( "bx-python" )
@@ -21,26 +23,22 @@
for start, end, offset in index.find(chrom, start, end):
source.seek(offset)
feature = source.readline().split()
- payload = { 'uid': offset, 'start': start, 'end': end, 'name': feature[3] }
- try:
- payload['strand'] = feature[5]
- except IndexError:
- pass
-
- if 'include_blocks' in kwargs:
- try:
+ payload = [ offset, start, end ]
+ if "no_detail" not in kwargs:
+ length = len(feature)
+ payload.append(feature[3]) # name
+ if length >= 6: # strand
+ payload.append(feature[5])
+
+ if length >= 8:
+ payload.append(int(feature[6]))
+ payload.append(int(feature[7]))
+
+ if length >= 12:
block_sizes = [ int(n) for n in feature[10].split(',') if n != '']
block_starts = [ int(n) for n in feature[11].split(',') if n != '' ]
blocks = zip(block_sizes, block_starts)
- payload['blocks'] = [ (start + block[1], start + block[1] + block[0]) for block in blocks]
- except IndexError:
- pass
-
- try:
- payload['thick_start'] = int(feature[6])
- payload['thick_end'] = int(feature[7])
- except IndexError:
- pass
+ payload.append( [ (start + block[1], start + block[1] + block[0]) for block in blocks] )
results.append(payload)
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/visualization/tracks/data/summary_tree.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/visualization/tracks/data/summary_tree.py Thu Mar 25 15:21:57 2010 -0400
@@ -0,0 +1,37 @@
+"""
+Summary tree data provider for the Galaxy track browser.
+"""
+
+import pkg_resources; pkg_resources.require( "bx-python" )
+from galaxy.visualization.tracks.summary import *
+from math import ceil, log
+from galaxy.util.lrucache import LRUCache
+
+CACHE = LRUCache(20) # Store 20 recently accessed indices for performance
+
+class SummaryTreeDataProvider( object ):
+ def __init__( self, dataset, original_dataset ):
+ self.dataset = dataset
+
+ def get_summary( self, chrom, start, end, **kwargs):
+ filename = self.dataset.file_name
+ st = CACHE[filename]
+ if st is None:
+ st = summary_tree_from_file( self.dataset.file_name )
+ CACHE[filename] = st
+ if chrom not in st.chrom_blocks:
+ return None
+
+ resolution = max(1, ceil(float(kwargs['resolution'])))
+
+ level = ceil( log( resolution, st.block_size ) )
+ level = int(max( level, 0 ))
+
+ stats = st.chrom_stats[chrom]
+ results = st.query(chrom, int(start), int(end), level)
+ if results == "detail" or level <= 0:
+ return None
+ elif results == "draw":
+ return "no_detail", None, None
+ else:
+ return results, stats["max"], stats["avg"]
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/visualization/tracks/summary.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/visualization/tracks/summary.py Thu Mar 25 15:21:57 2010 -0400
@@ -0,0 +1,88 @@
+'''
+2010, Kanwei Li
+Summary tree data structure for aggregation
+'''
+
+import sys, os
+import cPickle
+
+VERSION = 1
+
+class SummaryTree:
+ def __init__(self, block_size, levels, draw_cutoff, detail_cutoff):
+ self.version = VERSION
+ self.chrom_blocks = {}
+ self.levels = levels
+ self.draw_cutoff = draw_cutoff
+ self.detail_cutoff = detail_cutoff
+ self.block_size = block_size
+ self.chrom_stats = {}
+
+ def find_block(self, num, level):
+ return (num / self.block_size ** level)
+
+ def insert_range(self, chrom, start, end):
+ if chrom in self.chrom_blocks:
+ blocks = self.chrom_blocks[chrom]
+ else:
+ blocks = self.chrom_blocks[chrom] = {}
+ self.chrom_stats[chrom] = {}
+ for level in range(1, self.levels+1):
+ blocks[level] = {}
+
+
+ for level in range(1, self.levels+1):
+ block_level = blocks[level]
+ starting_block = self.find_block(start, level)
+ ending_block = self.find_block(end, level)
+ for block in range(starting_block, ending_block+1):
+ if block in block_level:
+ block_level[block] += 1
+ else:
+ block_level[block] = 1
+
+ def finish(self):
+ ''' Checks for cutoff and only stores levels above it '''
+ for chrom, blocks in self.chrom_blocks.iteritems():
+ cur_best = 999
+ for level in range(self.levels, 0, -1):
+ max_val = max(blocks[level].values())
+ if max_val < self.draw_cutoff:
+ if "draw_level" not in self.chrom_stats[chrom]:
+ self.chrom_stats[chrom]["draw_level"] = level
+ elif max_val < self.detail_cutoff:
+ 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])
+ cur_best = level
+
+ self.chrom_blocks[chrom] = dict([ (key, value) for key, value in blocks.iteritems() if key >= cur_best ])
+
+ def query(self, chrom, start, end, level):
+ if chrom in self.chrom_blocks:
+ stats = self.chrom_stats[chrom]
+ if "detail_level" in stats and level <= stats["detail_level"]:
+ return "detail"
+ elif "draw_level" in stats and level <= stats["draw_level"]:
+ return "draw"
+ blocks = self.chrom_blocks[chrom]
+ results = []
+ multiplier = self.block_size ** level
+ starting_block = self.find_block(start, level)
+ ending_block = self.find_block(end, level)
+ for block in range(starting_block, ending_block+1):
+ if block in blocks[level]:
+ results.append( (block * multiplier, blocks[level][block]) )
+ return results
+
+ return None
+
+ def write(self, filename):
+ self.finish()
+ cPickle.dump(self, open(filename, 'wb'), 2)
+
+def summary_tree_from_file(filename):
+ return cPickle.load(open(filename, "r"))
+
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py Wed Mar 24 15:13:57 2010 -0400
+++ b/lib/galaxy/web/controllers/tracks.py Thu Mar 25 15:21:57 2010 -0400
@@ -25,6 +25,7 @@
from galaxy.visualization.tracks.data.array_tree import ArrayTreeDataProvider
from galaxy.visualization.tracks.data.interval_index import IntervalIndexDataProvider
from galaxy.visualization.tracks.data.bam import BamDataProvider
+from galaxy.visualization.tracks.data.summary_tree import SummaryTreeDataProvider
# Message strings returned to browser
messages = Bunch(
@@ -41,7 +42,8 @@
dataset_type_to_data_provider = {
"array_tree": ArrayTreeDataProvider,
"interval_index": IntervalIndexDataProvider,
- "bai": BamDataProvider
+ "bai": BamDataProvider,
+ "summary_tree": SummaryTreeDataProvider
}
class DatasetSelectionGrid( grids.Grid ):
@@ -199,6 +201,7 @@
track_type, indexes = dataset.datatype.get_track_type()
converted = dict([ (index, self.__dataset_as_type( trans, dataset, index )) for index in indexes ])
+ extra_info = None
for index, converted_dataset in converted.iteritems():
if not converted_dataset:
@@ -212,11 +215,15 @@
if len(converted) > 1:
# Have to choose between array_tree and other provider
- array_tree = ArrayTreeDataProvider( converted['array_tree'], dataset )
- freqs = array_tree.get_data( chrom, low, high, frequencies=True, **kwargs )
+ summary_tree = SummaryTreeDataProvider( converted['summary_tree'], dataset )
+ freqs = summary_tree.get_summary( chrom, low, high, **kwargs )
if freqs is not None:
- frequencies, sums, avg_f = freqs
- return { "dataset_type": "array_tree", "data": frequencies, "sums": sums, "avg_f": avg_f }
+ frequencies, max_v, avg_v = freqs
+ if frequencies != "no_detail":
+ return { "dataset_type": "summary_tree", "data": frequencies, "max": max_v, "avg": avg_v }
+ else:
+ kwargs["no_detail"] = True # meh
+ extra_info = "no_detail"
dataset_type = "interval_index"
else:
dataset_type = converted.keys()[0]
@@ -228,7 +235,7 @@
else:
data = data_provider.get_data( chrom, low, high, **kwargs )
- return { "dataset_type": dataset_type, "data": data }
+ return { "dataset_type": dataset_type, "extra_info": extra_info, "data": data }
def __dataset_as_type( self, trans, dataset, type ):
"""
diff -r 44f2713a7279 -r 0890f7bf9d49 lib/galaxy/web/controllers/visualization.py
--- a/lib/galaxy/web/controllers/visualization.py Wed Mar 24 15:13:57 2010 -0400
+++ b/lib/galaxy/web/controllers/visualization.py Thu Mar 25 15:21:57 2010 -0400
@@ -25,8 +25,8 @@
key="free-text-search", visible=False, filterable="standard" )
)
operations = [
- grids.GridOperation( "Edit content", allow_multiple=False, url_args=dict( controller='tracks', action='browser' ) ),
- grids.GridOperation( "Edit attributes", allow_multiple=False, url_args=dict( action='edit') ),
+ grids.GridOperation( "View", allow_multiple=False, url_args=dict( controller='tracks', action='browser' ) ),
+ grids.GridOperation( "Edit Attributes", allow_multiple=False, url_args=dict( action='edit') ),
grids.GridOperation( "Share or Publish", allow_multiple=False, condition=( lambda item: not item.deleted ), async_compatible=False ),
grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), async_compatible=True, confirm="Are you sure you want to delete this visualization?" ),
]
diff -r 44f2713a7279 -r 0890f7bf9d49 static/scripts/packed/galaxy.workflow_editor.canvas.js
--- a/static/scripts/packed/galaxy.workflow_editor.canvas.js Wed Mar 24 15:13:57 2010 -0400
+++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js Thu Mar 25 15:21:57 2010 -0400
@@ -1,1 +1,1 @@
-function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatype=b}OutputTerminal.prototype=new Terminal();function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(var b in this.datatypes){if(a.datatype=="input"){return true}if(issubtype(a.datatype,this.datatypes[b])){return true}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a!
){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*!
f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canv
as.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){(new Connector(g.dragTarget.terminal,g.dropTarget.terminal)).redraw()}).bind("hover",function(){if(f.connectors.length>0){var g=$("<div class='callou!
t'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img src='../images/delete_icon.png' />").click(function(){$.each(f.connectors,function(i,h){h.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(h){return this.terminal.can_accept(f)}}).addClass("input-terminal-active");return i}).bind("drag",function(i){var h=function(){var k=$(i.dragProx!
y).offsetParent().offset(),j=i.offsetX-k.left,l=i.offsetY-k.top;$(i.dr
agProxy).css({left:j,top:l});i.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h){h.dragProxy.terminal.connectors[0].destroy();$(h.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=!
g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;this.tooltip=g.tooltip?g.tooltip:"";this.annotation=g.annotation;if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var h=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);h.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.extension);var f=b.name;if(b.extension!="input"){f=f+" ("+b.extension+")"}a.append($("<div class='form-row dataRow'>"+f+"</div>").append(j)!
)});workflow.node_changed(this)},update_field_data:function(f){var c=$
(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(k,h){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,h.name,h.extensions);g.find("div[name="+h.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j[0].terminal.connectors[0]=i;i.handle2=j[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))});g.replaceWith(b);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='!
color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes,function(b,d){var f={};$.each(d.input_terminals,function(g,h){f[h.name]=null;$.each(h.connectors,function(j,k){f[h.name]={id:k.handle1.node.id,output_name:k.handle1.name}})});var c={id:d.id,type:d.type,tool_id:d.tool_id,tool_state:d.t!
ool_state,tool_errors:d.tool_errors,input_connections:f,position:$(d.e
lement).position(),annotation:d.annotation};a[d.id]=c});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a.steps,function(f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(h,g){if(g){var i=wf.nodes[g.id];var j=new Connector();j.connect(i.output_terminals[g.output_name],c.input_terminals[h]);j.redraw()}})})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_cha!
nges_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(f!
unction(p,o){return $(d[p].element).position().top-$(d[o].element).pos
ition().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(functio!
n(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='../images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<img src='../images/delete_icon.png' />").click(function(b){g.destroy()}).hover(function(){$(this).attr("src","../images/delete_icon_dark.png")},function(){$(this).attr("src","../ima!
ges/delete_icon.png")}));i.appendTo("#canvas-container");var d=$("#can
vas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(this).css({left:b,top:p});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{te!
st:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=fu!
nction(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.
cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var h=$(this).offset();var f=b.cc.position();c=f.top-h.top;d=f.left-h.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k){var j=b.cc.width(),g=b.cc.height(),f=b.oc.width(),h=b.oc.height(),i=$(this).offsetParent().offset(),m=k.offsetX-i.left,l=k.offsetY-i.top;a(-(m/f*j),-(l/h*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var i=$(this).offsetParent();var h=i.offset();var f=Math.max(i.width()-(g.offsetX-h.left),i.height()-(g.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",fun!
ction(f){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;$.each(workflow.nodes,function(t,q){var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}});
\ No newline at end of file
+function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatype=b}OutputTerminal.prototype=new Terminal();function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(var b in this.datatypes){if(a.datatype=="input"){return true}if(issubtype(a.datatype,this.datatypes[b])){return true}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a!
){this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*!
f;this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canv
as.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){(new Connector(g.dragTarget.terminal,g.dropTarget.terminal)).redraw()}).bind("hover",function(){if(f.connectors.length>0){var g=$("<div class='callou!
t'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img src='../images/delete_icon.png' />").click(function(){$.each(f.connectors,function(i,h){h.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(h){return this.terminal.can_accept(f)}}).addClass("input-terminal-active");return i}).bind("drag",function(i){var h=function(){var k=$(i.dragProx!
y).offsetParent().offset(),j=i.offsetX-k.left,l=i.offsetY-k.top;$(i.dr
agProxy).css({left:j,top:l});i.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h){h.dragProxy.terminal.connectors[0].destroy();$(h.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b.appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=!
g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;this.tooltip=g.tooltip?g.tooltip:"";this.annotation=g.annotation;if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var h=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);h.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.extension);var f=b.name;if(b.extension!="input"){f=f+" ("+b.extension+")"}a.append($("<div class='form-row dataRow'>"+f+"</div>").append(j)!
)});workflow.node_changed(this)},update_field_data:function(f){var c=$
(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;this.annotation=f.annotation;if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(k,h){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,h.name,h.extensions);g.find("div[name="+h.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j[0].terminal.connectors[0]=i;i.handle2=j[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))});g.replaceWith(b);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div")!
.remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes,function(b,d){var f={};$.each(d.input_terminals,function(g,h){f[h.name]=null;$.each(h.connectors,function(j,k){f[h.name]={id:k.handle1.node.id,output_name:k.handle1.name}})});var c={id:d.id,type:d.type,too!
l_id:d.tool_id,tool_state:d.tool_state,tool_errors:d.tool_errors,input
_connections:f,position:$(d.element).position(),annotation:d.annotation};a[d.id]=c});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a.steps,function(f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(h,g){if(g){var i=wf.nodes[g.id];var j=new Connector();j.connect(i.output_terminals[g.output_name],c.input_terminals[h]);j.redraw()}})})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form").submit();this.active_form_has_changes=false}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.a!
ctive_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();this.has_changes=true;var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by!
_level,function(k,l){l.sort(function(p,o){return $(d[p].element).posit
ion().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_cont!
ainer.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='../images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<img src='../images/delete_icon.png' />").click(function(b){g.destroy()}).hover(function(){$(this).attr("src","../images/delete_icon_dark.png")},function!
(){$(this).attr("src","../images/delete_icon.png")}));i.appendTo("#can
vas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(this).css({left:b,top:p});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.ext!
end(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:f!
unction(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);
f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var h=$(this).offset();var f=b.cc.position();c=f.top-h.top;d=f.left-h.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k){var j=b.cc.width(),g=b.cc.height(),f=b.oc.width(),h=b.oc.height(),i=$(this).offsetParent().offset(),m=k.offsetX-i.left,l=k.offsetY-i.top;a(-(m/f*j),-(l/h*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var i=$(this).offsetParent();var h=i.offset();var f=Math.max(i.width()-(g.offsetX-h.left),i.height()-(g.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview!
-border div").bind("drag",function(f){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;$.each(workflow.nodes,function(t,q){var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_!
viewport_overlay()}});
\ No newline at end of file
diff -r 44f2713a7279 -r 0890f7bf9d49 static/scripts/packed/trackster.js
--- a/static/scripts/packed/trackster.js Wed Mar 24 15:13:57 2010 -0400
+++ b/static/scripts/packed/trackster.js Thu Mar 25 15:21:57 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_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=20,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 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_high=0;this.center=(this.max_high-this.max_low)/2;this.zoom_factor=3;this.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.tr!
acks.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)}}},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)/DENSITY)/Math.LN10));this.zoom_res=Math.pow(FEATURE_LEVELS,Math.ma!
x(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++){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){if(this.max_high===0||this.high-this.low<30){return}if(a){this.center=a/$(document).width()*(this.high-this.low)+this.low}this.zoom_level+=1;this.redraw()},zoom_out:function(){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.con!
tent_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.data_queue={};a.tile_cache.clear();a.data_cache.clear();a.content_div.css("height","30px");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.length===0||d=="no data"){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");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,d,b){this.track_type="LineTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.indexer=d;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};if(b.min_value!==undefined){this.prefs.min_value=b.min_value}if(b.max_value!==undefined){this.prefs.max_value=b.max_value}};$.extend(LineTrack.prototype,TiledTrack.prototype,{init:fu!
nction(){var a=this,b=a.view.tracks.indexOf(a);a.vertical_range=undefined;this.init_each({stats:true,indexer:a.indexer,chrom:a.view.chrom,low:null,high:null,dataset_id:a.dataset_id},function(d){if(isNaN(parseFloat(a.prefs.min_value))||isNaN(parseFloat(a.prefs.max_value))){a.prefs.min_value=d.min;a.prefs.max_value=d.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;$("#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 c=$("<div></div>").addClass("yaxislabel").attr("id","linetrack_"+b+"_maxval").text(a.prefs.max_value);c.css({position:"relative",top:"25px"});c.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;$.getJSON(data_url,{indexer:
this.indexer,chrom:this.view.chrom,low:a,high:f,dataset_id:this.dataset_id,resolution:this.view.resolution,},function(g){c.data_cache.set(e,g);delete c.data_queue[e];c.draw()})}},draw_tile:function(n,p,c,e){if(this.vertical_range===undefined){return}var q=p*DENSITY*n,a=DENSITY*n,b=$("<canvas class='tile'></canvas>"),s=n+"_"+p;if(!this.data_cache.get(s)){this.get_data(n,p);return}var r=this.data_cache.get(s);b.css({position:"absolute",top:0,left:(q-this.view.low)*e});b.get(0).width=Math.ceil(a*e);b.get(0).height=this.height_px;var m=b.get(0).getContext("2d"),j=false,k=this.prefs.min_value,f=this.prefs.max_value,l=this.vertical_range,d=this.height_px;m.beginPath();for(var o=0;o<r.length-1;o++){var h=r[o][0]-q;var g=r[o][1];if(isNaN(g)){j=false}else{h=h*e;if(g<=k){g=k}else{if(g>=f){g=f}}g=Math.round(d-(g-k)/l*d);if(j){m.lineTo(h,g)}else{m.moveTo(h,g);j=true}}}m.stroke();c.append(b);return b},gen_options:function(j){var a=$("<div></div>").addClass("form-row");var e="track_"+j+"_!
minval",g="track_"+j+"_maxval",h=$("<label></label>").attr("for",e).text("Min value:"),b=(this.prefs.min_value===undefined?"":this.prefs.min_value),i=$("<input></input>").attr("id",e).val(b),d=$("<label></label>").attr("for",g).text("Max value:"),f=(this.prefs.max_value===undefined?"":this.prefs.max_value),c=$("<input></input>").attr("id",g).val(f);return a.append(h).append(i).append(d).append(c)},update_options:function(c){var a=$("#track_"+c+"_minval").val(),b=$("#track_"+c+"_maxval").val();if(a!==this.prefs.min_value||b!==this.prefs.max_value){this.prefs.min_value=parseFloat(a);this.prefs.max_value=parseFloat(b);this.vertical_range=this.prefs.max_value-this.prefs.min_value;$("#linetrack_"+c+"_minval").text(this.prefs.min_value);$("#linetrack_"+c+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.draw()}}});var FeatureTrack=function(c,a,d,b){this.track_type="FeatureTrack";Track.call(this,c,$("#viewport"));TiledTrack.call(this);this.indexer=d;this.height_px!
=100;this.container_div.addClass("feature-track");this.dataset_id=a;th
is.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"};if(b.block_color!==undefined){this.prefs.block_color=b.block_color}if(b.label_color!==undefined){this.prefs.label_color=b.label_color}};$.extend(FeatureTrack.prototype,TiledTrack.prototype,{init:function(){var a=this;this.init_each({indexer:a.indexer,low:a.view.max_low,high:a.view.max_high,dataset_id:a.dataset_id,chrom:a.view.chrom},function(b){a.values=b;a.calc_slots();a.slots=a.zo_slots})},get_data:function(a,d){var b=this,c=a+"_"+d;if(!b.data_queue[c]){b.data_queue[c]=true;$.getJSON(data_url,{indexer:b.indexer,chrom:b.view.chrom,low:a,high:d,dataset_id:b.dataset_id,include_blocks:true},!
function(e){b.data_cache.set(c,e);delete b.data_queue[c];b.draw()})}},calc_slots:function(){var b=[],a=this.content_div.width()/(this.view.high-this.view.low),d=this.view.max_low;for(var e=0,f=this.values.length;e<f;e++){var g,h,k=this.values[e];g=Math.floor((k.start-d)*a);h=Math.ceil((k.end-d)*a);var c=0;while(true){if(b[c]===undefined||b[c]<g){b[c]=h;this.zo_slots[k.uid]=c;break}c++}}this.height_px=b.length*this.vertical_nodetail_px+15;this.content_div.css("height",this.height_px+"px")},incremental_slots:function(a,f){if(!this.inc_slots[a]){this.inc_slots[a]={};this.inc_slots[a].w_scale=1/a;this.s_e_by_tile[a]={}}var h=this.inc_slots[a].w_scale,s=[],g=0,b=$("<canvas></canvas>").get(0).getContext("2d"),l=this.view.max_low;var c,e,u=[];for(var p=0,q=f.length;p<q;p++){var d=f[p];if(this.inc_slots[a][d.uid]!==undefined){g=Math.max(g,this.inc_slots[a][d.uid]);u.push(this.inc_slots[a][d.uid])}else{s.push(p)}}for(var p=0,q=s.length;p<q;p++){var d=f[s[p]];c=Math.floor((d.start-l)!
*h);c-=b.measureText(d.name).width;e=Math.ceil((d.end-l)*h);var o=0;wh
ile(true){var m=true;if(this.s_e_by_tile[a][o]!==undefined){for(var n=0,t=this.s_e_by_tile[a][o].length;n<t;n++){var r=this.s_e_by_tile[a][o][n];if(e>r[0]&&c<r[1]){m=false;break}}}if(m){if(this.s_e_by_tile[a][o]===undefined){this.s_e_by_tile[a][o]=[]}this.s_e_by_tile[a][o].push([c,e]);this.inc_slots[a][d.uid]=o;g=Math.max(g,o);break}o++}}return g},draw_tile:function(B,f,g,M){if(!this.values){return}var s=f*DENSITY*B,G=(f+1)*DENSITY*B,r=DENSITY*B;var K,L,m;if(M>this.show_labels_scale){if(!this.showing_details){this.showing_details=true}for(var H in this.data_cache.obj_cache){var C=H.split("_"),z=C[0],c=C[1];if(z<=s&&c>=G){K=this.data_cache.get(H);break}}if(!K){this.data_queue[[s,G]]=true;this.get_data(s,G);return}m=this.incremental_slots(this.view.zoom_res,K)*this.vertical_detail_px+15;L=this.inc_slots[this.view.zoom_res]}else{if(this.showing_details){this.showing_details=false}m=this.height_px;L=this.zo_slots;K=this.values}var a=Math.ceil(r*M),u=$("<canvas class='tile'></can!
vas>"),D=this.prefs.label_color,e=this.prefs.block_color,x=this.left_offset,N=this.showing_details,O=(this.showing_details?this.vertical_detail_px:this.vertical_nodetail_px);u.css({position:"absolute",top:0,left:(s-this.view.low)*M-x});u.get(0).width=a+x;u.get(0).height=m;var p=u.get(0).getContext("2d");p.fillStyle=this.prefs.block_color;p.font=this.default_font;p.textAlign="right";var I=0;for(var J=0,o=K.length;J<o;J++){var v=K[J];if(v.start<=G&&v.end>=s){var A=Math.floor(Math.max(0,(v.start-s)*M)),q=Math.ceil(Math.min(a,(v.end-s)*M)),y=L[v.uid]*O;var n,E,t=null,P=null;if(v.thick_start&&v.thick_end){t=Math.floor(Math.max(0,(v.thick_start-s)*M));P=Math.ceil(Math.min(a,(v.thick_end-s)*M))}if(!N){p.fillRect(A+x,y+5,q-A,1)}else{if(v.start>s){p.fillStyle=D;p.fillText(v.name,A-1+x,y+8);p.fillStyle=e}var Q=v.blocks;if(Q){if(v.strand){if(v.strand=="+"){p.fillStyle=RIGHT_STRAND}else{if(v.strand=="-"){p.fillStyle=LEFT_STRAND}}p.fillRect(A+x,y,q-A,10);p.fillStyle=e}for(var H=0,d=Q.le!
ngth;H<d;H++){var h=Q[H],b=Math.floor(Math.max(0,(h[0]-s)*M)),w=Math.c
eil(Math.min(a,(h[1]-s)*M));if(b>w){continue}n=5;E=3;p.fillRect(b+x,y+E,w-b,n);if(t!==undefined&&!(b>P||w<t)){n=9;E=1;var F=Math.max(b,t),l=Math.min(w,P);p.fillRect(F+x,y+E,l-F,n)}}}else{n=9;E=1;p.fillRect(A+x,y+E,q-A,n);if(v.strand){if(v.strand=="+"){p.fillStyle=RIGHT_STRAND_INV}else{if(v.strand=="-"){p.fillStyle=LEFT_STRAND_INV}}p.fillRect(A+x,y,q-A,10);p.fillStyle=prefs.block_color}}}I++}}g.append(u);return u},gen_options:function(g){var a=$("<div></div>").addClass("form-row");var d="track_"+g+"_block_color",c=$("<label></label>").attr("for",d).text("Block color:"),b=$("<input></input>").attr("id",d).attr("name",d).val(this.prefs.block_color),f="track_"+g+"_label_color",h=$("<label></label>").attr("for",f).text("Label color:"),e=$("<input></input>").attr("id",f).attr("name",f).val(this.prefs.label_color);return a.append(c).append(b).append(h).append(e)},update_options:function(c){var a=$("#track_"+c+"_block_color").val(),b=$("#track_"+c+"_label_color").val();if(a!==this.p!
refs.block_color||b!==this.prefs.label_color){this.prefs.block_color=a;this.prefs.label_color=b;this.tile_cache.clear();this.draw()}}});var ReadTrack=function(c,a,d,b){this.track_type="ReadTrack";this.tile_cache=new Cache(CACHED_TILES_FEATURE);Track.call(this,c,$("#viewport"));TiledTrack.call(this);FeatureTrack.call(this,c,a,d,b)};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{draw_tile:function(v,z,m,n){if(!this.values){return}var A=z*DENSITY*v,e=(z+1)*DENSITY*v,q=DENSITY*v;var D,p,h;h=this.height_px;p=this.zo_slots;D=this.values;var t=Math.ceil(q*n),r=$("<canvas class='tile'></canvas>");r.css({position:"absolute",top:0,left:(A-this.view.low)*n-this.left_offset});r.get(0).width=t+this.left_offset;r.get(0).height=h;var u=r.get(0).getContext("2d");u.fillStyle=this.prefs.block_color;u.font=this.default_font;u.textAlign="right";var s=u.measureText("A").width;var w=0;for(var x=0,y=D.length;x<y;x++){var l=D[x];if(l.start<=e&&l.end>=A){var g=Math.floor(!
Math.max(0,(l.start-A)*n)),k=Math.ceil(Math.min(t,(l.end-A)*n)),f=p[l.
uid]*this.vertical_detail_px;var a,E,d=null,o=null;if(n>s){for(var B=0,b=l.name.length;B<b;B++){var C=Math.floor(Math.max(0,(l.start+B-A)*n));u.fillText(l.name[B],C+this.left_offset,f+8)}}else{u.fillRect(g+this.left_offset,f+4,k-g,3)}}}m.append(r);return r}});
\ No newline at end of file
+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=20,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_!
high=0;this.center=(this.max_high-this.max_low)/2;this.zoom_factor=3;t
his.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.sp!
an/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.!
high-this.low)+this.low}this.zoom_level+=1;this.redraw()},zoom_out:fun
ction(){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");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_NOCONVERTER)}else{if((d.da!
ta&&d.data.length===0)||d==="no data"){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_offse!
t){b-=this.left_offset}c.css({left:b});k.append(c);this.max_height=Mat
h.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.app!
end(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.max_value!==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.pre!
fs.max_value)}a.vertical_range=a.prefs.max_value-a.prefs.min_value;a.t
otal_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)){this.get_data(o,q);return}var t=this.data_cache.get(u);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,30)}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="tra!
ck_"+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>');$("#"+e+" #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);this.prefs.max_value=parseFloat(c);this.prefs.mode=b;this.vertica!
l_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:true};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.pre!
fs.show_counts=b.show_counts}};$.extend(FeatureTrack.prototype,TiledTr
ack.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,u=[],h=0,b=$("<canvas></canvas>").get(0).getContext("2d"),n=this.view.max_low;var d,f,w=[];for(var r=0,s=g.length;r<s;r++){var e=g[r],l=e[0];if(this.inc_slots[a][l]!==undefined){h=Math.max(h,this.inc_slots[a][l]);w.push(this.inc_slots[a][l])}else{u.push(r)}}for(var r=0,s=u.length;r<s;r++){var e=g[u[r]];!
l=e[0],feature_start=e[1],feature_end=e[2],feature_name=e[3];d=Math.floor((feature_start-n)*m);if(!c){d-=b.measureText(feature_name).width}f=Math.ceil((feature_end-n)*m);var q=0;while(true){var o=true;if(this.s_e_by_tile[a][q]!==undefined){for(var p=0,v=this.s_e_by_tile[a][q].length;p<v;p++){var t=this.s_e_by_tile[a][q][p];if(f>t[0]&&d<t[1]){o=false;break}}}if(o){if(this.s_e_by_tile[a][q]===undefined){this.s_e_by_tile[a][q]=[]}this.s_e_by_tile[a][q].push([d,f]);this.inc_slots[a][l]=q;h=Math.max(h,q);break}q++}}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){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_slots(this.view.zoom_res,ac.data,P)*af+15;m.parent().css("height",Math.max(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(Ma!
th.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(ab>z){t.fillStyle=T;t.fillText(A,Q-1+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(h){var a=$("<div></div>").addClass("form-row");var d="track_"+h+"_b!
lock_color",j=$("<label></label>").attr("for",d).text("Block color:"),
k=$("<input></input>").attr("id",d).attr("name",d).val(this.prefs.block_color),i="track_"+h+"_label_color",f=$("<label></label>").attr("for",i).text("Text color:"),g=$("<input></input>").attr("id",i).attr("name",i).val(this.prefs.label_color),e="track_"+h+"_show_count",c=$("<label></label>").attr("for",e).text("Show summary counts"),b=$('<input type="checkbox" style="float:left;"></input>').attr("id",e).attr("name",e).attr("checked",this.prefs.show_counts);return a.append(j).append(k).append(f).append(g).append(b).append(c)},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){this.track_type="ReadTrack";this.tile_cache=new Cache(CACHED_TILES_FEATUR!
E);Track.call(this,c,$("#viewport"));TiledTrack.call(this);FeatureTrack.call(this,c,a,b)};$.extend(ReadTrack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{draw_tile:function(v,z,m,n){if(!this.values){return}var A=z*DENSITY*v,e=(z+1)*DENSITY*v,q=DENSITY*v;var D,p,h;h=this.height_px;p=this.zo_slots;D=this.values;var t=Math.ceil(q*n),r=$("<canvas class='tile'></canvas>");r.css({position:"absolute",top:0,left:(A-this.view.low)*n-this.left_offset});r.get(0).width=t+this.left_offset;r.get(0).height=h;var u=r.get(0).getContext("2d");u.fillStyle=this.prefs.block_color;u.font=this.default_font;u.textAlign="right";var s=u.measureText("A").width;var w=0;for(var x=0,y=D.length;x<y;x++){var l=D[x];if(l.start<=e&&l.end>=A){var g=Math.floor(Math.max(0,(l.start-A)*n)),k=Math.ceil(Math.min(t,(l.end-A)*n)),f=p[l.uid]*this.vertical_detail_px;var a,E,d=null,o=null;if(n>s){for(var B=0,b=l.name.length;B<b;B++){var C=Math.floor(Math.max(0,(l.start+B-A)*n));u.fillText(l.name[B],C+this.lef!
t_offset,f+8)}}else{u.fillRect(g+this.left_offset,f+4,k-g,3)}}}m.appen
d(r);return r}});
\ No newline at end of file
diff -r 44f2713a7279 -r 0890f7bf9d49 static/scripts/trackster.js
--- a/static/scripts/trackster.js Wed Mar 24 15:13:57 2010 -0400
+++ b/static/scripts/trackster.js Thu Mar 25 15:21:57 2010 -0400
@@ -163,7 +163,7 @@
this.center = Math.round( this.low + (this.high - this.low) / 2 );
// 10^log10(range / DENSITY) Close approximation for browser window, assuming DENSITY = window width
- this.resolution = Math.pow( 10, Math.ceil( Math.log( (this.high - this.low) / DENSITY ) / Math.LN10 ) );
+ 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
@@ -355,9 +355,10 @@
this.dataset_id = dataset_id;
this.data_cache = new Cache(CACHED_DATA);
this.tile_cache = new Cache(CACHED_TILES_LINE);
- this.prefs = { 'min_value': undefined, 'max_value': undefined };
+ this.prefs = { 'min_value': undefined, 'max_value': undefined, 'mode': 'line' };
if (prefs.min_value !== undefined) { this.prefs.min_value = prefs.min_value; }
if (prefs.max_value !== undefined) { this.prefs.max_value = prefs.max_value; }
+ if (prefs.max_value !== undefined) { this.prefs.mode = prefs.mode; }
};
$.extend( LineTrack.prototype, TiledTrack.prototype, {
init: function() {
@@ -457,14 +458,17 @@
ctx.beginPath();
// for intensity, calculate delta x in pixels to for width of box
- var delta_x_px = Math.ceil((data[1][0] - data[0][0]) * w_scale);
- var mode = "line";
+ if (data.length > 1) {
+ var delta_x_px = Math.ceil((data[1][0] - data[0][0]) * w_scale);
+ } else {
+ var delta_x_px = 10;
+ }
for ( var i = 0; i < data.length; i++ ) {
var x = data[i][0] - tile_low;
var y = data[i][1];
- if ( mode == "intensity" ) {
+ if ( this.prefs.mode == "intensity" ) {
// DRAW INTENSITY
if (y === null) {
continue;
@@ -475,7 +479,7 @@
} else if (y >= max_value) {
y = max_value;
}
- y = Math.floor( (y - min_value) / vertical_range * 255 );
+ y = 255 - Math.floor( (y - min_value) / vertical_range * 255 );
ctx.fillStyle = "rgb(" +y+ "," +y+ "," +y+ ")";
ctx.fillRect(x, 0, delta_x_px, 30);
}
@@ -512,20 +516,27 @@
var minval = 'track_' + track_id + '_minval',
maxval = 'track_' + track_id + '_maxval',
+ mode = 'track_' + track_id + '_mode',
min_label = $('<label></label>').attr("for", minval).text("Min value:"),
min_val = (this.prefs.min_value === undefined ? "" : this.prefs.min_value),
min_input = $('<input></input>').attr("id", minval).val(min_val),
max_label = $('<label></label>').attr("for", maxval).text("Max value:"),
max_val = (this.prefs.max_value === undefined ? "" : this.prefs.max_value),
- max_input = $('<input></input>').attr("id", maxval).val(max_val);
+ max_input = $('<input></input>').attr("id", maxval).val(max_val),
+ mode_label = $('<label></label>').attr("for", mode).text("Display mode:"),
+ mode_val = (this.prefs.mode === undefined ? "line" : this.prefs.mode),
+ mode_input = $('<select id="' +mode+ '"><option value="line" id="mode_line">Line</option><option value="intensity" id="mode_intensity">Intensity</option></select>');
+ $("#" + mode + " #mode_"+mode_val).attr('selected', 'selected');
- return container.append(min_label).append(min_input).append(max_label).append(max_input);
+ return container.append(min_label).append(min_input).append(max_label).append(max_input).append(mode_label).append(mode_input);
}, update_options: function(track_id) {
var min_value = $('#track_' + track_id + '_minval').val(),
- max_value = $('#track_' + track_id + '_maxval').val();
- if ( min_value !== this.prefs.min_value || max_value !== this.prefs.max_value) {
+ max_value = $('#track_' + track_id + '_maxval').val(),
+ mode = $('#track_' + track_id + '_mode option:selected').val();
+ if ( min_value !== this.prefs.min_value || max_value !== this.prefs.max_value || mode != this.prefs.mode ) {
this.prefs.min_value = parseFloat(min_value);
this.prefs.max_value = parseFloat(max_value);
+ this.prefs.mode = mode;
this.vertical_range = this.prefs.max_value - this.prefs.min_value;
// Update the y-axis
$('#linetrack_' + track_id + '_minval').text(this.prefs.min_value);
@@ -557,9 +568,10 @@
this.tile_cache = new Cache(CACHED_TILES_FEATURE);
this.data_cache = new Cache(20);
- this.prefs = { 'block_color': 'black', 'label_color': 'black' };
+ this.prefs = { 'block_color': 'black', 'label_color': 'black', 'show_counts': true };
if (prefs.block_color !== undefined) { this.prefs.block_color = prefs.block_color; }
if (prefs.label_color !== undefined) { this.prefs.label_color = prefs.label_color; }
+ if (prefs.show_counts !== undefined) { this.prefs.show_counts = prefs.show_counts; }
};
$.extend( FeatureTrack.prototype, TiledTrack.prototype, {
@@ -584,7 +596,7 @@
track.data_queue[key] = true;
$.getJSON( data_url, { chrom: track.view.chrom,
low: low, high: high, dataset_id: track.dataset_id,
- include_blocks: true, resolution: this.view.resolution }, function (result) {
+ resolution: this.view.resolution }, function (result) {
track.data_cache.set(key, result);
// console.log("datacache", track.data_cache.get(key));
delete track.data_queue[key];
@@ -592,31 +604,7 @@
});
}
},
- calc_slots: function() {
- var end_ary = [],
- scale = this.content_div.width() / (this.view.high - this.view.low),
- max_low = this.view.max_low;
- // console.log(scale, this.view.high, this.view.low);
- for (var i = 0, len = this.values.length; i < len; i++) {
- var f_start, f_end, feature = this.values[i];
- f_start = Math.floor( (feature.start - max_low) * scale );
- f_end = Math.ceil( (feature.end - max_low) * scale );
-
- // if (include_labels) { console.log(f_start, f_end); }
- var j = 0;
- while (true) {
- if (end_ary[j] === undefined || end_ary[j] < f_start) {
- end_ary[j] = f_end;
- this.zo_slots[feature.uid] = j;
- break;
- }
- j++;
- }
- }
- this.height_px = end_ary.length * this.vertical_nodetail_px + 15;
- this.content_div.css( "height", this.height_px + "px" );
- },
- incremental_slots: function( level, features ) {
+ incremental_slots: function( level, features, no_detail ) {
if (!this.inc_slots[level]) {
this.inc_slots[level] = {};
this.inc_slots[level].w_scale = 1 / level;
@@ -636,10 +624,11 @@
// If feature already exists in slots (from previously seen tiles), use the same slot,
// otherwise if not seen, add to "undone" list for slot calculation
for (var i = 0, len = features.length; i < len; i++) {
- var feature = features[i];
- if (this.inc_slots[level][feature.uid] !== undefined) {
- highest_slot = Math.max(highest_slot, this.inc_slots[level][feature.uid]);
- slotted.push(this.inc_slots[level][feature.uid]);
+ var feature = features[i],
+ feature_uid = feature[0];
+ if (this.inc_slots[level][feature_uid] !== undefined) {
+ highest_slot = Math.max(highest_slot, this.inc_slots[level][feature_uid]);
+ slotted.push(this.inc_slots[level][feature_uid]);
} else {
undone.push(i);
}
@@ -648,9 +637,15 @@
// console.log("Slotted: ", features.length - undone.length, "/", features.length, slotted);
for (var i = 0, len = undone.length; i < len; i++) {
var feature = features[undone[i]];
- f_start = Math.floor( (feature.start - max_low) * w_scale );
- f_start -= dummy_canvas.measureText(feature.name).width;
- f_end = Math.ceil( (feature.end - max_low) * w_scale );
+ feature_uid = feature[0],
+ feature_start = feature[1],
+ feature_end = feature[2],
+ feature_name = feature[3];
+ f_start = Math.floor( (feature_start - max_low) * w_scale );
+ if (!no_detail) {
+ f_start -= dummy_canvas.measureText(feature_name).width;
+ }
+ f_end = Math.ceil( (feature_end - max_low) * w_scale );
var j = 0;
// Try to fit the feature to the first slot that doesn't overlap any other features in that slot
@@ -668,7 +663,7 @@
if (found) {
if (this.s_e_by_tile[level][j] === undefined) { this.s_e_by_tile[level][j] = []; }
this.s_e_by_tile[level][j].push([f_start, f_end]);
- this.inc_slots[level][feature.uid] = j;
+ this.inc_slots[level][feature_uid] = j;
highest_slot = Math.max(highest_slot, j);
break;
}
@@ -707,9 +702,12 @@
required_height = 30;
// Blah
} else {
- // Calculate new slots incrementally for this new chunk of data and update height if necessary
- required_height = this.incremental_slots( this.view.zoom_res, data.data ) * this.vertical_detail_px + 15;
- // console.log(required_height);
+ // Calculate new slots incrementally for this new chunk of data and update height if necessary
+ var no_detail = (data.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;
+ parent_element.parent().css("height", Math.max(this.height_px, required_height) + "px");
slots = this.inc_slots[this.view.zoom_res];
}
@@ -718,9 +716,7 @@
new_canvas = $("<canvas class='tile'></canvas>"),
label_color = this.prefs.label_color,
block_color = this.prefs.block_color,
- left_offset = this.left_offset,
- // showing_details = this.showing_details,
- y_scale = this.vertical_detail_px;
+ left_offset = this.left_offset;
new_canvas.css({
position: "absolute",
@@ -734,24 +730,39 @@
ctx.fillStyle = this.prefs.block_color;
ctx.font = this.default_font;
ctx.textAlign = "right";
- var min_color = 150;
+ 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 == "array_tree") {
+ if (data.dataset_type == "summary_tree") {
var points = data.data;
- var sums = data.sums;
- var avg_f = data.avg_f;
- var delta_x_px = Math.ceil((points[1][0] - points[0][0]) * w_scale);
-
+ var max = data.max;
+ var avg = data.avg;
+ if (data.data.length > 2) {
+ var delta_x_px = Math.ceil((points[1][0] - points[0][0]) * w_scale);
+ } else {
+ var delta_x_px = 50; // Arbitrary, fix
+ }
+
for ( var i = 0, len = points.length; i < len; i++ ) {
var x = Math.ceil( (points[i][0] - tile_low) * w_scale );
var y = points[i][1];
-
- if (!y) {
- continue;
+
+ if (!y) { continue; }
+ var 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);
+
+ if (this.prefs.show_counts) {
+ if (color > color_cutoff) {
+ ctx.fillStyle = "black";
+ } else {
+ ctx.fillStyle = "#ddd";
+ }
+ ctx.textAlign = "center";
+ ctx.fillText(points[i][1], x + left_offset + (delta_x_px/2), 12);
}
- y = Math.floor( min_color + (y - avg_f)/sums * min_color );
- ctx.fillStyle = "rgb(" +y+ "," +y+ "," +y+ ")";
- ctx.fillRect(x + left_offset, 0, delta_x_px, 20);
}
parent_element.append( new_canvas );
return new_canvas;
@@ -760,42 +771,51 @@
var data = data.data;
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] * y_scale;
+ var feature = data[i],
+ feature_uid = feature[0],
+ feature_start = feature[1],
+ feature_end = feature[2],
+ feature_name = feature[3];
- var thickness, y_start, thick_start = null, thick_end = null;
- if (feature.thick_start && feature.thick_end) {
- thick_start = Math.floor( Math.max(0, (feature.thick_start - tile_low) * w_scale) );
- thick_end = Math.ceil( Math.min(width, (feature.thick_end - tile_low) * w_scale) );
- }
- // if (!showing_details) {
- // Non-detail levels
- // ctx.fillRect(f_start + left_offset, y_center + 5, f_end - f_start, 1);
- // } else {
+ 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] * 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
- if (feature.start > tile_low) {
+ 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 (feature_start > tile_low) {
ctx.fillStyle = label_color;
- ctx.fillText(feature.name, f_start - 1 + left_offset, y_center + 8);
+ ctx.fillText(feature_name, f_start - 1 + left_offset, y_center + 8);
ctx.fillStyle = block_color;
}
- var blocks = feature.blocks;
- if (blocks) {
+ if (feature_blocks) {
// Draw introns
- if (feature.strand) {
- if (feature.strand == "+") {
+ if (feature_strand) {
+ if (feature_strand == "+") {
ctx.fillStyle = RIGHT_STRAND;
- } else if (feature.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 = blocks.length; k < k_len; k++) {
- var block = blocks[k],
+ 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; }
@@ -829,7 +849,7 @@
ctx.fillStyle = prefs.block_color;
}
}
- // }
+ }
j++;
}
}
@@ -843,15 +863,21 @@
block_color_label = $('<label></label>').attr("for", block_color).text("Block color:"),
block_color_input = $('<input></input>').attr("id", block_color).attr("name", block_color).val(this.prefs.block_color),
label_color = 'track_' + track_id + '_label_color',
- label_color_label = $('<label></label>').attr("for", label_color).text("Label color:"),
- label_color_input = $('<input></input>').attr("id", label_color).attr("name", label_color).val(this.prefs.label_color);
- return container.append(block_color_label).append(block_color_input).append(label_color_label).append(label_color_input);
+ label_color_label = $('<label></label>').attr("for", label_color).text("Text color:"),
+ label_color_input = $('<input></input>').attr("id", label_color).attr("name", label_color).val(this.prefs.label_color),
+ show_count = 'track_' + track_id + '_show_count',
+ show_count_label = $('<label></label>').attr("for", show_count).text("Show summary counts"),
+ show_count_input = $('<input type="checkbox" style="float:left;"></input>').attr("id", show_count).attr("name", show_count).attr("checked", this.prefs.show_counts);
+
+ return container.append(block_color_label).append(block_color_input).append(label_color_label).append(label_color_input).append(show_count_input).append(show_count_label);
}, update_options: function(track_id) {
var block_color = $('#track_' + track_id + '_block_color').val(),
- label_color = $('#track_' + track_id + '_label_color').val();
- if (block_color !== this.prefs.block_color || label_color !== this.prefs.label_color) {
+ label_color = $('#track_' + track_id + '_label_color').val(),
+ show_counts = $('#track_' + track_id + '_show_count').attr("checked");
+ if (block_color !== this.prefs.block_color || label_color !== this.prefs.label_color || show_counts != this.prefs.show_counts) {
this.prefs.block_color = block_color;
this.prefs.label_color = label_color;
+ this.prefs.show_counts = show_counts;
this.tile_cache.clear();
this.draw();
}
diff -r 44f2713a7279 -r 0890f7bf9d49 templates/tracks/browser.mako
--- a/templates/tracks/browser.mako Wed Mar 24 15:13:57 2010 -0400
+++ b/templates/tracks/browser.mako Thu Mar 25 15:21:57 2010 -0400
@@ -170,7 +170,7 @@
$("#right-border").bind( "dragend", function(e) { refresh(e); } );
$(window).trigger( "resize" );
- $("#viewport").bind( "dragstart", function( e ) {
+ $("#viewport-container").bind( "dragstart", function( e ) {
this.original_low = view.low;
this.current_height = e.clientY;
this.current_x = e.offsetX;
1
0
details: http://www.bx.psu.edu/hg/galaxy/rev/44f2713a7279
changeset: 3561:44f2713a7279
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Wed Mar 24 15:13:57 2010 -0400
description:
Add FASTQ <--> Tabular converter tools.
diffstat:
test-data/fastq_to_tabular_out_1.tabular | 2 +
test-data/fastq_to_tabular_out_2.tabular | 2 +
tool_conf.xml.main | 2 +
tool_conf.xml.sample | 2 +
tools/fastq/fastq_to_tabular.py | 21 ++++++++++++++++++
tools/fastq/fastq_to_tabular.xml | 30 +++++++++++++++++++++++++
tools/fastq/tabular_to_fastq.py | 29 +++++++++++++++++++++++++
tools/fastq/tabular_to_fastq.xml | 37 ++++++++++++++++++++++++++++++++
8 files changed, 125 insertions(+), 0 deletions(-)
diffs (169 lines):
diff -r 4c95f1a101f1 -r 44f2713a7279 test-data/fastq_to_tabular_out_1.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/fastq_to_tabular_out_1.tabular Wed Mar 24 15:13:57 2010 -0400
@@ -0,0 +1,2 @@
+FAKE0001 Original version has PHRED scores from 0 to 93 inclusive (in that order) ACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTACGTAC !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+FAKE0002 Original version has PHRED scores from 93 to 0 inclusive (in that order) CATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCA ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!
diff -r 4c95f1a101f1 -r 44f2713a7279 test-data/fastq_to_tabular_out_2.tabular
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/fastq_to_tabular_out_2.tabular Wed Mar 24 15:13:57 2010 -0400
@@ -0,0 +1,2 @@
+FAKE0001 Original version has PHRED scores from 0 to 93 inclusive (in that order) G2131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+FAKE0002 Original version has PHRED scores from 93 to 0 inclusive (in that order) G3131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131 ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!
diff -r 4c95f1a101f1 -r 44f2713a7279 tool_conf.xml.main
--- a/tool_conf.xml.main Wed Mar 24 14:14:58 2010 -0400
+++ b/tool_conf.xml.main Wed Mar 24 15:13:57 2010 -0400
@@ -297,6 +297,8 @@
<tool file="fastq/fastq_trimmer.xml" />
<tool file="fastq/fastq_manipulation.xml" />
<tool file="fastq/fastq_to_fasta.xml" />
+ <tool file="fastq/fastq_to_tabular.xml" />
+ <tool file="fastq/tabular_to_fastq.xml" />
</section>
<section name="NGS: Mapping" id="ngs_mapping">
<label text="Illumina" id="illumina"/>
diff -r 4c95f1a101f1 -r 44f2713a7279 tool_conf.xml.sample
--- a/tool_conf.xml.sample Wed Mar 24 14:14:58 2010 -0400
+++ b/tool_conf.xml.sample Wed Mar 24 15:13:57 2010 -0400
@@ -208,6 +208,8 @@
<tool file="fastq/fastq_trimmer.xml" />
<tool file="fastq/fastq_manipulation.xml" />
<tool file="fastq/fastq_to_fasta.xml" />
+ <tool file="fastq/fastq_to_tabular.xml" />
+ <tool file="fastq/tabular_to_fastq.xml" />
</section>
<section name="NGS: Mapping" id="solexa_tools">
<tool file="sr_mapping/lastz_wrapper.xml" />
diff -r 4c95f1a101f1 -r 44f2713a7279 tools/fastq/fastq_to_tabular.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/fastq/fastq_to_tabular.py Wed Mar 24 15:13:57 2010 -0400
@@ -0,0 +1,21 @@
+#Dan Blankenberg
+import sys
+from galaxy_utils.sequence.fastq import fastqReader
+
+def main():
+ input_filename = sys.argv[1]
+ output_filename = sys.argv[2]
+ input_type = sys.argv[3] or 'sanger' #input type should ordinarily be unnecessary
+
+ num_reads = None
+ fastq_read = None
+ out = open( output_filename, 'wb' )
+ for num_reads, fastq_read in enumerate( fastqReader( open( input_filename ), format = input_type ) ):
+ out.write( "%s\t%s\t%s\n" % ( fastq_read.identifier[1:].replace( '\t', ' ' ), fastq_read.sequence.replace( '\t', ' ' ), fastq_read.quality.replace( '\t', ' ' ) ) )
+ out.close()
+ if num_reads is None:
+ print "No valid FASTQ reads could be processed."
+ else:
+ print "%i FASTQ reads were converted to Tabular." % ( num_reads + 1 )
+
+if __name__ == "__main__": main()
diff -r 4c95f1a101f1 -r 44f2713a7279 tools/fastq/fastq_to_tabular.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/fastq/fastq_to_tabular.xml Wed Mar 24 15:13:57 2010 -0400
@@ -0,0 +1,30 @@
+<tool id="fastq_to_tabular" name="FASTQ to Tabular" version="1.0.0">
+ <description>converter</description>
+ <command interpreter="python">fastq_to_tabular.py '$input_file' '$output_file' '${input_file.extension[len( 'fastq' ):]}'</command>
+ <inputs>
+ <param name="input_file" type="data" format="fastqsanger,fastqcssanger,fastqillumina,fastqsolexa" label="FASTQ file to convert" />
+ </inputs>
+ <outputs>
+ <data name="output_file" format="tabular" />
+ </outputs>
+ <tests>
+ <!-- basic test -->
+ <test>
+ <param name="input_file" value="sanger_full_range_original_sanger.fastqsanger" ftype="fastqsanger" />
+ <output name="output_file" file="fastq_to_tabular_out_1.tabular" />
+ </test>
+ <!-- color space test -->
+ <test>
+ <param name="input_file" value="sanger_full_range_as_cssanger.fastqcssanger" ftype="fastqcssanger" />
+ <output name="output_file" file="fastq_to_tabular_out_2.tabular" />
+ </test>
+ </tests>
+ <help>
+**What it does**
+
+This tool converts FASTQ sequencing reads to a Tabular file.
+
+Tab characters, if present in the source FASTQ file, will be converted to spaces.
+
+ </help>
+</tool>
diff -r 4c95f1a101f1 -r 44f2713a7279 tools/fastq/tabular_to_fastq.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/fastq/tabular_to_fastq.py Wed Mar 24 15:13:57 2010 -0400
@@ -0,0 +1,29 @@
+#Dan Blankenberg
+import sys
+
+def main():
+ input_filename = sys.argv[1]
+ output_filename = sys.argv[2]
+ identifier_col = int( sys.argv[3] ) - 1
+ sequence_col = int( sys.argv[4] ) - 1
+ quality_col = int( sys.argv[5] ) - 1
+
+ max_col = max( identifier_col, sequence_col, quality_col )
+ num_reads = None
+ fastq_read = None
+ skipped_lines = 0
+ out = open( output_filename, 'wb' )
+ for num_reads, line in enumerate( open( input_filename ) ):
+ fields = line.rstrip( '\n\r' ).split( '\t' )
+ if len( fields ) > max_col:
+ out.write( "@%s\n%s\n+\n%s\n" % ( fields[identifier_col], fields[sequence_col], fields[quality_col] ) )
+ else:
+ skipped_lines += 1
+
+ out.close()
+ if num_reads is None:
+ print "Input was empty."
+ else:
+ print "%i tabular lines were written as FASTQ reads. Be sure to use the FASTQ Groomer tool on this output before further analysis." % ( num_reads + 1 - skipped_lines )
+
+if __name__ == "__main__": main()
diff -r 4c95f1a101f1 -r 44f2713a7279 tools/fastq/tabular_to_fastq.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/fastq/tabular_to_fastq.xml Wed Mar 24 15:13:57 2010 -0400
@@ -0,0 +1,37 @@
+<tool id="tabular_to_fastq" name="Tabular to FASTQ" version="1.0.0">
+ <description>converter</description>
+ <command interpreter="python">tabular_to_fastq.py '$input_file' '$output_file' '$identifier' '$sequence' '$quality'</command>
+ <inputs>
+ <param name="input_file" type="data" format="tabular" label="Tabular file to convert" />
+ <param name="identifier" label="Identifier column" type="data_column" data_ref="input_file" />
+ <param name="sequence" label="Sequence column" type="data_column" data_ref="input_file" />
+ <param name="quality" label="Quality column" type="data_column" data_ref="input_file" />
+ </inputs>
+ <outputs>
+ <data name="output_file" format="fastq" />
+ </outputs>
+ <tests>
+ <!-- basic test -->
+ <test>
+ <param name="input_file" value="fastq_to_tabular_out_1.tabular" ftype="tabular" />
+ <param name="identifier" value="1" />
+ <param name="sequence" value="2" />
+ <param name="quality" value="3" />
+ <output name="output_file" file="sanger_full_range_original_sanger.fastqsanger" />
+ </test>
+ <!-- color space test -->
+ <test>
+ <param name="input_file" value="fastq_to_tabular_out_2.tabular" ftype="tabular" />
+ <param name="identifier" value="1" />
+ <param name="sequence" value="2" />
+ <param name="quality" value="3" />
+ <output name="output_file" file="sanger_full_range_as_cssanger.fastqcssanger" />
+ </test>
+ </tests>
+ <help>
+**What it does**
+
+This tool attempts to convert a tabular file containing sequencing read data to a FASTQ formatted file. The FASTQ Groomer tool should always be used on the output of this tool.
+
+ </help>
+</tool>
1
0
Hello
I have installed Galaxy in a production environment and a UCSC local mirror.
When I click on "display at UCSC main", I have an error on UCSC :
"redirected to non-http(s): /galaxy/root"
Have you an idea to resolve this problem ?
Thanks
Emeric
--
Ce message a été vérifié par MailScanner
pour des virus ou des polluriels et rien de
suspect n'a été trouvé.
3
5
Hi,
I recently discovered an issue that prevents me from easily deleting
multiple histories at once.
This is the method I use:
Click ³Options² on the right side menu -> Go to ³Saved Histories² -> Click
on the check box of the history to be deleted -> Click ³Delete² button at
the bottom (next to ³For selected histories:²).
When I do this, nothing happens, and the history remains.
However, if I click on the the downward triangle and click on ³Delete² from
the pull down menu, the history is correctly deleted.
Deleting using the check-boxes and the Delete button works in changeset
3446:143c920af25c
But fails in changeset 3447:f5d383525d68.
Please let me know if you cannot reproduce the problem.
Cheers,
Oliver
2
1
Hi
I have a problem that I've not been able to track down. I've tried
searching the mailing list archive and googling.
When I enable paste in universe_wsgi.ini and then run run.sh I get this
error. The same occurs for both the stable and development branches.
Traceback (most recent call last):
File "./scripts/paster.py", line 34, in <module>
command.run()
File
"/home/nat/work/software/galaxy-central/eggs/PasteScript-1.7.3-py2.6.egg/paste/script/command.py",
line 84, in run
invoke(command, command_name, options, args[1:])
File
"/home/nat/work/software/galaxy-central/eggs/PasteScript-1.7.3-py2.6.egg/paste/script/command.py",
line 123, in invoke
exit_code = runner.run(args)
File
"/home/nat/work/software/galaxy-central/eggs/PasteScript-1.7.3-py2.6.egg/paste/script/command.py",
line 218, in run
result = self.command()
File
"/home/nat/work/software/galaxy-central/eggs/PasteScript-1.7.3-py2.6.egg/paste/script/serve.py",
line 274, in command
relative_to=base, global_conf=vars)
File
"/home/nat/work/software/galaxy-central/eggs/PasteScript-1.7.3-py2.6.egg/paste/script/serve.py",
line 308, in loadserver
relative_to=relative_to, **kw)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 210, in loadserver
return loadobj(SERVER, uri, name=name, **kw)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 224, in loadobj
global_conf=global_conf)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 248, in loadcontext
global_conf=global_conf)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 278, in _loadconfig
return loader.get_context(object_type, name, global_conf)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 409, in get_context
section)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 431, in _context_from_use
object_type, name=use, global_conf=global_conf)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 361, in get_context
global_conf=global_conf)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 248, in loadcontext
global_conf=global_conf)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 285, in _loadegg
return loader.get_context(object_type, name, global_conf)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 561, in get_context
object_type, name=name)
File
"/home/nat/work/software/galaxy-central/eggs/PasteDeploy-1.3.3-py2.6.egg/paste/deploy/loadwsgi.py",
line 600, in find_egg_entry_point
for prot in protocol_options] or '(no entry points)'))))
LookupError: Entry point 'gzip' not found in egg 'Paste' (dir:
/home/nat/work/software/galaxy-central/eggs/Paste-1.6-py2.6.egg;
protocols: paste.server_factory, paste.server_runner; entry_points: )
The strange thing is on another machine I don't get the error but I
can't find out what the missing dependency is on the machine the
generates the error despite comparing installed packages etc.
I'm running Ubunutu 9.1 64bit on both machines.
Can anyone tell me what I'm missing that leads to the above error?
Many thanks
Nathaniel
--
Nathaniel Street
Umeå Plant Science Centre
Department of Plant Physiology
University of Umeå
SE-901 87 Umeå
SWEDEN
email: nathaniel.street(a)plantphys.umu.se
tel: +46-90-786 5473
fax: +46-90-786 6676
www.popgenie.org
2
1
In universe_wsgi.ini there is a parameter log_level which is set to
DEBUG. I want to decrease the size of the log being output. What are
the other options for log_level?
Thanks,
Natalie
2
1
Hello,
I have a galaxy installation on OSX with a MySQL backend and galaxy running
as a daemon. After extended periods of non-use, I get the following error
when trying to access my galaxy installation via the web browser:
Error Traceback:
View as: Interactive <http://genomics06.bio.tamu.edu:8080/#> |
Text<http://genomics06.bio.tamu.edu:8080/#>
| XML <http://genomics06.bio.tamu.edu:8080/#>
(full)<http://genomics06.bio.tamu.edu:8080/#>
⇝ OperationalError: (OperationalError) (2006, 'MySQL server has gone away')
u'SELECT galaxy_session.id AS galaxy_session_id, galaxy_session.create_time
AS galaxy_session_create_time, galaxy_session.update_time AS
galaxy_session_update_time, galaxy_session.user_id AS
galaxy_session_user_id, galaxy_session.remote_host AS
galaxy_session_remote_host, galaxy_session.remote_addr AS
galaxy_session_remote_addr, galaxy_session.referer AS
galaxy_session_referer, galaxy_session.current_history_id AS
galaxy_session_current_history_id, galaxy_session.session_key AS
galaxy_session_session_key, galaxy_session.is_valid AS
galaxy_session_is_valid, galaxy_session.prev_session_id AS
galaxy_session_prev_session_id \nFROM galaxy_session \nWHERE
galaxy_session.session_key = %s AND galaxy_session.is_valid = %s \n LIMIT 0,
1' ['8f166da7c3aa375a667392ff4c5fb20b', 1]
URL: http://genomics06.bio.tamu.edu:8080/
Module weberror.evalexception.middleware:*364* in respond
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>app_iter *=* self*.*application*
(*environ*,* detect_start_response*)*
Module paste.debug.prints:*98* in __call__
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>environ*,* self*.*app*)*
Module paste.wsgilib:*539* in intercept_output
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>app_iter *=* application*(*
environ*,* replacement_start_response*)*
Module paste.recursive:*80* in __call__
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>*return* self*.*application*(*
environ*,* start_response*)*
Module paste.httpexceptions:*632* in __call__
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>*return* self*.*application*(*
environ*,* start_response*)*
Module galaxy.web.framework.base:*99* in __call__
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>trans *=* self*.*
transaction_factory*(* environ *)*
Module galaxy.web.framework:*112* in <lambda>
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>self*.*set_transaction_factory*(
* *lambda* e*:* UniverseWebTransaction*(* e*,* galaxy_app*,* self*,*
session_cookie *)* *)*
Module galaxy.web.framework:*152* in __init__
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>self*.*__ensure_valid_session*(*
session_cookie *)*
Module galaxy.web.framework:*281* in __ensure_valid_session
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>self*.*app*.*model*.*
GalaxySession*.*table*.*c*.*is_valid*==*True *)* *)*
Module sqlalchemy.orm.query:*1300* in first
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>ret *=* list*(*self*[**0**:**1**
]**)*
Module sqlalchemy.orm.query:*1221* in __getitem__
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>*return* list*(*res*)*
Module sqlalchemy.orm.query:*1361* in __iter__
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>*return* self*.*
_execute_and_instances*(*context*)*
Module sqlalchemy.orm.query:*1364* in _execute_and_instances
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>result *=* self*.*session*.*
execute*(*querycontext*.*statement*,* params*=*self*.*_params*,* mapper*=*
self*.*_mapper_zero_or_none*(**)**)*
Module sqlalchemy.orm.session:*755* in execute
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>clause*,* params *or* *{**}**)*
Module sqlalchemy.engine.base:*824* in execute
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>*return* Connection*.*executors*
[*c*]**(*self*,* object*,* multiparams*,* params*)*
Module sqlalchemy.engine.base:*874* in _execute_clauseelement
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>*return* self*.*
__execute_context*(*context*)*
Module sqlalchemy.engine.base:*896* in __execute_context
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>self*.*_cursor_execute*(*context
*.*cursor*,* context*.*statement*,* context*.*parameters*[**0**]**,* context
*=*context*)*
Module sqlalchemy.engine.base:*950* in _cursor_execute
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>self*.*_handle_dbapi_exception*(
*e*,* statement*,* parameters*,* cursor*,* context*)*
Module sqlalchemy.engine.base:*931* in _handle_dbapi_exception
<http://genomics06.bio.tamu.edu:8080/#>
view <http://genomics06.bio.tamu.edu:8080/#>
>> <http://genomics06.bio.tamu.edu:8080/#>*raise* exc*.*DBAPIError*.*
instance*(*statement*,* parameters*,* e*,* connection_invalidated*=*
is_disconnect*)*
*OperationalError: (OperationalError) (2006, 'MySQL server has gone away')
u'SELECT galaxy_session.id AS galaxy_session_id, galaxy_session.create_time
AS galaxy_session_create_time, galaxy_session.update_time AS
galaxy_session_update_time, galaxy_session.user_id AS
galaxy_session_user_id, galaxy_session.remote_host AS
galaxy_session_remote_host, galaxy_session.remote_addr AS
galaxy_session_remote_addr, galaxy_session.referer AS
galaxy_session_referer, galaxy_session.current_history_id AS
galaxy_session_current_history_id, galaxy_session.session_key AS
galaxy_session_session_key, galaxy_session.is_valid AS
galaxy_session_is_valid, galaxy_session.prev_session_id AS
galaxy_session_prev_session_id \nFROM galaxy_session \nWHERE
galaxy_session.session_key = %s AND galaxy_session.is_valid = %s \n LIMIT 0,
1' ['8f166da7c3aa375a667392ff4c5fb20b', 1]*
*
*
*The error only appears once, though, and galaxy works fine if I attempt to
access it again.*
*
*
*
*
*Any ideas as to why it is doing this?*
*
*
*
*
*
*
*Rgds,*
*
*
*
*
*Roy W.*
--
Roy Weckiewicz
Texas A&M University
2
2
Hello, could I please get some more information on running multiple web
server processes? I'd like to set up our local installation on a web server
farm. I'm currently using SGE for all the heavy lifting, but am wary of
having a single server on the front end. Any guidance would be
appreciated. I'm currently using MySql for the db but am not adverse to
switching to PostgreSQL if there was a reason to do so.
And anything you'd like to share from your experience regarding hardware
selection would be appreciated as well; I'm currently thinking of ordering
several "inexpensive" servers. Have you noticed an "optimal" number of web
servers, before traffic jams at the db server start to affect performance?
Thanks,
Ed Kirton
US DOE JGI
2
1
Hello,
A quick question:
If I recall correctly, it was possible to set the galaxy session cookie name with the "session_key" variable in "universe_wsgi.ini".
I'm not sure about that, but I think it was possible, because I'm running two instances (at least) from the same server, and I explicitly set the cookie names to by different.
Now it seems that the cookie is always "galaxysession" - was that changed recently, or am I missing something?
One reason that I ask:
The "path" of the cookie is always hard-coded to "/" (probably in lib/galaxy/web/framework/__init__.py:set_cookie as the default parameter) - so when I run two galaxies from the same server (with different "prefix" filter) - they are now forced to share the same session cookie.
I think this is causing some history related problems in one of my servers: galaxy always thinks there is no active history selected.
Example:
1. I click "list saved histories"
2. Select a history
3. The history pane is updated.
4. I click on "refresh" history
5. a new, "unnamed history" is created, without any datasets.
The log shows error like:
alaxy.web.framework DEBUG 2010-04-04 23:48:39,512 Error: this request returned None from get_history(): http://rave.cshl.edu/devglx/history/list
Any ideas ?
Thanks,
-gordon
2
2
Hi,
The files "intervals.py" and "genetics.py" in "/lib/galaxy/datatypes/" contains "hacks" for turning HTTPS into HTTP because the genome-browser didn't support https.
I think that recent versions of the genome browser do support HTTPS (at least there's an option for that in the source code),
so this hack can be removed,
-gordon
2
1