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
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/f29af7c51377
changeset: 3592:f29af7c51377
user: Kanwei Li <kanwei(a)gmail.com>
date: Thu Apr 01 14:24:47 2010 -0400
description:
- Simple converter dependency system where converter won't run until its deps finish
- Fix issue with trying to treat binary data as unicode
trackster:
- Make BAM use summary tree
- Refactor converter code
diffstat:
datatypes_conf.xml.sample | 2 +-
lib/galaxy/datatypes/binary.py | 2 +-
lib/galaxy/datatypes/converters/bam_to_bai.xml | 8 +-
lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py | 32 +---
lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.xml | 4 +-
lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.py | 2 +-
lib/galaxy/datatypes/data.py | 14 +-
lib/galaxy/datatypes/display_applications/parameters.py | 2 +-
lib/galaxy/datatypes/interval.py | 4 +-
lib/galaxy/datatypes/registry.py | 12 +-
lib/galaxy/model/__init__.py | 51 +++++-
lib/galaxy/visualization/tracks/data/array_tree.py | 3 +
lib/galaxy/visualization/tracks/data/bam.py | 5 +-
lib/galaxy/visualization/tracks/data/interval_index.py | 2 +-
lib/galaxy/web/controllers/tracks.py | 82 ++-------
static/scripts/packed/trackster.js | 2 +-
static/scripts/trackster.js | 12 +-
17 files changed, 118 insertions(+), 121 deletions(-)
diffs (513 lines):
diff -r 40e8c99829e0 -r f29af7c51377 datatypes_conf.xml.sample
--- a/datatypes_conf.xml.sample Thu Apr 01 13:08:48 2010 -0400
+++ b/datatypes_conf.xml.sample Thu Apr 01 14:24:47 2010 -0400
@@ -5,7 +5,7 @@
<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_summary_tree_converter.xml" target_datatype="summary_tree"/>
+ <converter file="bam_to_summary_tree_converter.xml" target_datatype="summary_tree" depends_on="bai"/>
<display file="ucsc/bam.xml" />
</datatype>
<datatype extension="bed" type="galaxy.datatypes.interval:Bed" display_in_upload="true">
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/datatypes/binary.py
--- a/lib/galaxy/datatypes/binary.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/datatypes/binary.py Thu Apr 01 14:24:47 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", "summary_tree"]
+ return "ReadTrack", {"data": "bai", "index": "summary_tree"}
class Binseq( Binary ):
"""Class describing a zip archive of binary sequence files"""
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/datatypes/converters/bam_to_bai.xml
--- a/lib/galaxy/datatypes/converters/bam_to_bai.xml Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/datatypes/converters/bam_to_bai.xml Thu Apr 01 14:24:47 2010 -0400
@@ -1,12 +1,12 @@
-<tool id="INDEXER_Bam_Bai_0" name="Bam to Bai">
- <command>samtools index $input $output</command>
+<tool id="CONVERTER_Bam_Bai_0" name="Bam to Bai">
+ <command>samtools index $input1 $output1</command>
<inputs>
<page>
- <param format="bam" name="input" type="data" label="Choose BAM"/>
+ <param format="bam" name="input1" type="data" label="Choose BAM"/>
</page>
</inputs>
<outputs>
- <data format="bai" name="output"/>
+ <data format="bai" name="output1"/>
</outputs>
<help>
</help>
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py
--- a/lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.py Thu Apr 01 14:24:47 2010 -0400
@@ -4,26 +4,10 @@
import sys
from galaxy import eggs
-import pkg_resources; pkg_resources.require( "bx-python" ); pkg_resources.require( "pysam" )
+import pkg_resources; 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
-
+from galaxy.visualization.tracks.summary import *
def main():
@@ -31,15 +15,13 @@
index_fname = sys.argv[2]
out_fname = sys.argv[3]
- reader = BamReader( input_fname, index_fname )
+ bamfile = csamtools.Samfile( filename=input_fname, mode='rb', index_filename=index_fname )
- # Fill array from reader
- d = array_tree_dict_from_reader( reader, {}, block_size = BLOCK_SIZE )
+ st = SummaryTree(block_size=100, levels=4, draw_cutoff=100, detail_cutoff=20)
+ for read in bamfile.fetch():
+ st.insert_range(read.rname, read.mpos, read.pos + read.rlen)
- for array_tree in d.itervalues():
- array_tree.root.build_summary()
-
- FileArrayTreeDict.dict_to_file( d, open( out_fname, "w" ), no_leaves=True )
+ st.write(out_fname)
if __name__ == "__main__":
main()
\ No newline at end of file
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.xml
--- a/lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.xml Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/datatypes/converters/bam_to_summary_tree_converter.xml Thu Apr 01 14:24:47 2010 -0400
@@ -1,10 +1,10 @@
<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>
+ <command interpreter="python">bam_to_summary_tree_converter.py $input1 $bai $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"/>
+ <param format="bai" name="bai" type="data" label="BAI index file"/>
</page>
</inputs>
<outputs>
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.py
--- a/lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/datatypes/converters/bed_to_summary_tree_converter.py Thu Apr 01 14:24:47 2010 -0400
@@ -19,7 +19,7 @@
for chrom, chrom_start, chrom_end, name, score in reader:
st.insert_range(chrom, chrom_start, chrom_end)
- st.write(out_fname)
+ st.write(out_fname)
if __name__ == "__main__":
main()
\ No newline at end of file
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/datatypes/data.py
--- a/lib/galaxy/datatypes/data.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/datatypes/data.py Thu Apr 01 14:24:47 2010 -0400
@@ -251,9 +251,10 @@
def find_conversion_destination( self, dataset, accepted_formats, datatypes_registry, **kwd ):
"""Returns ( target_ext, existing converted dataset )"""
return datatypes_registry.find_conversion_destination_for_dataset_by_extensions( dataset, accepted_formats, **kwd )
- def convert_dataset(self, trans, original_dataset, target_type, return_output = False, visible = True ):
+ def convert_dataset(self, trans, original_dataset, target_type, return_output = False, visible = True, deps=None):
"""This function adds a job to the queue to convert a dataset to another type. Returns a message about success/failure."""
converter = trans.app.datatypes_registry.get_converter_by_target_type( original_dataset.ext, target_type )
+
if converter is None:
raise Exception( "A converter does not exist for %s to %s." % ( original_dataset.ext, target_type ) )
#Generate parameter dictionary
@@ -261,9 +262,11 @@
#determine input parameter name and add to params
input_name = 'input1'
for key, value in converter.inputs.items():
- if value.type == 'data':
+ if value.name in deps:
+ params[value.name] = deps[value.name]
+ elif value.type == 'data':
input_name = key
- break
+
params[input_name] = original_dataset
#Run converter, job is dispatched through Queue
converted_dataset = converter.execute( trans, incoming = params, set_output_hid = visible )[1]
@@ -481,5 +484,8 @@
if file_type in [ 'gzipped', 'binary' ]:
text = "%s file" % file_type
else:
- text = unicode( '\n'.join( lines ), 'utf-8' )
+ try:
+ text = unicode( '\n'.join( lines ), 'utf-8' )
+ except UnicodeDecodeError:
+ text = "binary/unknown file"
return text
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/datatypes/display_applications/parameters.py
--- a/lib/galaxy/datatypes/display_applications/parameters.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/datatypes/display_applications/parameters.py Thu Apr 01 14:24:47 2010 -0400
@@ -73,7 +73,7 @@
for ext in self.extensions:
rval = data.get_converted_files_by_type( ext )
if rval:
- return rval[0]
+ return rval
assert data.find_conversion_destination( self.formats )[0] is not None, "No conversion path found for data param: %s" % self.name
return None
return data
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/datatypes/interval.py
--- a/lib/galaxy/datatypes/interval.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/datatypes/interval.py Thu Apr 01 14:24:47 2010 -0400
@@ -504,7 +504,7 @@
except: return False
def get_track_type( self ):
- return "FeatureTrack", ["interval_index", "summary_tree"]
+ return "FeatureTrack", {"data": "interval_index", "index": "summary_tree"}
class BedStrict( Bed ):
"""Tab delimited data in strict BED format - no non-standard columns allowed"""
@@ -965,7 +965,7 @@
resolution = max( resolution, 1 )
return resolution
def get_track_type( self ):
- return "LineTrack", ["array_tree"]
+ return "LineTrack", {"data": "array_tree"}
class CustomTrack ( Tabular ):
"""UCSC CustomTrack"""
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/datatypes/registry.py
--- a/lib/galaxy/datatypes/registry.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/datatypes/registry.py Thu Apr 01 14:24:47 2010 -0400
@@ -19,6 +19,7 @@
self.datatype_converters = odict()
self.datatype_indexers = odict()
self.converters = []
+ self.converter_deps = {}
self.available_tracks = []
self.set_external_metadata_tool = None
self.indexers = []
@@ -68,6 +69,11 @@
# into the calling app's toolbox.
converter_config = converter.get( 'file', None )
target_datatype = converter.get( 'target_datatype', None )
+ depends_on = converter.get( 'depends_on', None )
+ if depends_on and target_datatype:
+ if extension not in self.converter_deps:
+ self.converter_deps[extension] = {}
+ self.converter_deps[extension][target_datatype] = depends_on.split(',')
if converter_config and target_datatype:
self.converters.append( ( converter_config, extension, target_datatype ) )
for indexer in elem.findall( 'indexer' ):
@@ -363,9 +369,9 @@
"""Returns ( target_ext, existing converted dataset )"""
for convert_ext in self.get_converters_by_datatype( dataset.ext ):
if isinstance( self.get_datatype_by_extension( convert_ext ), accepted_formats ):
- datasets = dataset.get_converted_files_by_type( convert_ext )
- if datasets:
- ret_data = datasets[0]
+ dataset = dataset.get_converted_files_by_type( convert_ext )
+ if dataset:
+ ret_data = dataset
elif not converter_safe:
continue
else:
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/model/__init__.py Thu Apr 01 14:24:47 2010 -0400
@@ -577,11 +577,54 @@
def display_info( self ):
return self.datatype.display_info( self )
def get_converted_files_by_type( self, file_type ):
- valid = []
for assoc in self.implicitly_converted_datasets:
if not assoc.deleted and assoc.type == file_type:
- valid.append( assoc.dataset )
- return valid
+ return assoc.dataset
+ return None
+ def get_converted_dataset(self, trans, target_ext):
+ """
+ Return converted dataset(s) if they exist. If not converted yet, do so and return None (the first time).
+ If unconvertible, raise exception.
+ """
+ # See if we can convert the dataset
+ if target_ext not in self.get_converter_types():
+ raise ValueError("Conversion from '%s' to '%s' not possible", self.extension, target_ext)
+
+ # See if converted dataset already exists
+ converted_dataset = self.get_converted_files_by_type( target_ext )
+ if converted_dataset:
+ return converted_dataset
+
+ # Conversion is possible but hasn't been done yet, run converter.
+ # Check if we have dependencies
+ deps = {}
+ try:
+ fail_dependencies = False
+ depends_on = trans.app.datatypes_registry.converter_deps[self.extension][target_ext]
+ for dependency in depends_on:
+ dep_dataset = self.get_converted_dataset(trans, dependency)
+ if dep_dataset is None or dep_dataset.state != trans.app.model.Job.states.OK:
+ fail_dependencies = True
+ else:
+ deps[dependency] = dep_dataset
+ if fail_dependencies:
+ return None
+ except ValueError:
+ log.debug("WTF")
+ raise ValueError("A dependency could not be converted.")
+ except KeyError:
+ pass # No deps
+
+ assoc = ImplicitlyConvertedDatasetAssociation( parent=self, file_type=target_ext, metadata_safe=False )
+ new_dataset = self.datatype.convert_dataset( trans, self, target_ext, return_output=True, visible=False, deps=deps ).values()[0]
+ new_dataset.hid = self.hid
+ new_dataset.name = self.name
+ trans.sa_session.add( new_dataset )
+ trans.sa_session.flush()
+ assoc.dataset = new_dataset
+ trans.sa_session.add( assoc )
+ trans.sa_session.flush()
+ return None
def clear_associated_files( self, metadata_safe = False, purge = False ):
raise 'Unimplemented'
def get_child_by_designation(self, designation):
@@ -590,7 +633,7 @@
return child
return None
def get_converter_types(self):
- return self.datatype.get_converter_types( self, datatypes_registry)
+ return self.datatype.get_converter_types( self, datatypes_registry )
def find_conversion_destination( self, accepted_formats, **kwd ):
"""Returns ( target_ext, existing converted dataset )"""
return self.datatype.find_conversion_destination( self, accepted_formats, datatypes_registry, **kwd )
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/visualization/tracks/data/array_tree.py
--- a/lib/galaxy/visualization/tracks/data/array_tree.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/visualization/tracks/data/array_tree.py Thu Apr 01 14:24:47 2010 -0400
@@ -44,6 +44,9 @@
return float(n)
def get_data( self, chrom, start, end, **kwargs ):
+ if 'stats' in kwargs:
+ return self.get_stats(chrom)
+
f = open( self.dataset.file_name )
d = FileArrayTreeDict( f )
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/visualization/tracks/data/bam.py
--- a/lib/galaxy/visualization/tracks/data/bam.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/visualization/tracks/data/bam.py Thu Apr 01 14:24:47 2010 -0400
@@ -1,5 +1,6 @@
"""
Visualization data provider for BAM format.
+Kanwei Li, 2010
"""
import pkg_resources; pkg_resources.require( "pysam" )
@@ -7,7 +8,7 @@
from pysam import csamtools
from math import floor, ceil, log
import logging
-# log = logging.getLogger(__name__)
+log = logging.getLogger(__name__)
class BamDataProvider( object ):
"""
@@ -36,7 +37,7 @@
# Encode reads as list of dictionaries
results = []
for read in data:
- payload = { 'uid': str(read.pos) + str(read.seq), 'start': read.pos, 'end': read.pos + read.rlen, 'name': read.seq }
+ payload = [ str(read.pos) + str(read.seq), read.pos, read.pos + read.rlen, read.seq ]
results.append(payload)
bamfile.close()
return results
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/visualization/tracks/data/interval_index.py
--- a/lib/galaxy/visualization/tracks/data/interval_index.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/visualization/tracks/data/interval_index.py Thu Apr 01 14:24:47 2010 -0400
@@ -1,6 +1,6 @@
"""
Interval index data provider for the Galaxy track browser.
-Kanwei Li, 2009
+Kanwei Li, 2010
Payload format: [ uid (offset), start, end, name, strand, thick_start, thick_end, blocks ]
"""
diff -r 40e8c99829e0 -r f29af7c51377 lib/galaxy/web/controllers/tracks.py
--- a/lib/galaxy/web/controllers/tracks.py Thu Apr 01 13:08:48 2010 -0400
+++ b/lib/galaxy/web/controllers/tracks.py Thu Apr 01 14:24:47 2010 -0400
@@ -199,78 +199,38 @@
if dataset.state != trans.app.model.Job.states.OK:
return messages.PENDING
- 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:
+ track_type, data_sources = dataset.datatype.get_track_type()
+ for source_type, data_source in data_sources.iteritems():
+ try:
+ converted_dataset = dataset.get_converted_dataset(trans, data_source)
+ except ValueError:
return messages.NO_CONVERTER
# Need to check states again for the converted version
+ if not converted_dataset or converted_dataset.state != model.Dataset.states.OK:
+ return messages.PENDING
+
if converted_dataset.state == model.Dataset.states.ERROR:
return messages.ERROR
- if converted_dataset.state != model.Dataset.states.OK:
- return messages.PENDING
-
- if len(converted) > 1:
- # Have to choose between array_tree and other provider
- summary_tree = SummaryTreeDataProvider( converted['summary_tree'], dataset )
- freqs = summary_tree.get_summary( chrom, low, high, **kwargs )
- if freqs is not None:
- frequencies, max_v, avg_v = freqs
+
+ extra_info = None
+ if 'index' in data_sources:
+ # Have to choose between indexer and data provider
+ indexer = dataset_type_to_data_provider[data_sources['index']]( dataset.get_converted_dataset(trans, data_sources['index']), dataset )
+ summary = indexer.get_summary( chrom, low, high, **kwargs )
+ if summary is not None:
+ frequencies, max_v, avg_v = summary
if frequencies != "no_detail":
- return { "dataset_type": "summary_tree", "data": frequencies, "max": max_v, "avg": avg_v }
+ return { "dataset_type": data_sources['index'], "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]
-
- data_provider = dataset_type_to_data_provider[ dataset_type ]( converted[dataset_type], dataset )
+
+ dataset_type = data_sources['data']
+ data_provider = dataset_type_to_data_provider[ dataset_type ]( dataset.get_converted_dataset(trans, dataset_type), dataset )
- if 'stats' in kwargs:
- data = data_provider.get_stats( chrom )
- else:
- data = data_provider.get_data( chrom, low, high, **kwargs )
-
+ data = data_provider.get_data( chrom, low, high, **kwargs )
return { "dataset_type": dataset_type, "extra_info": extra_info, "data": data }
-
- def __dataset_as_type( self, trans, dataset, type ):
- """
- Given a dataset, try to find a way to adapt it to a different type. If the
- dataset is already of that type it is returned, if it can be converted a
- converted dataset (possibly new) is returned, if it cannot be converted,
- None is returned.
- """
- # Already of correct type
- if dataset.extension == type:
- return dataset
- # See if we can convert the dataset
- if type not in dataset.get_converter_types():
- log.debug( "Conversion from '%s' to '%s' not possible", dataset.extension, type )
- return None
- # See if converted dataset already exists
- converted_datasets = [c for c in dataset.get_converted_files_by_type( type ) if c != None]
- if converted_datasets:
- if converted_datasets[0].state != 'error':
- return converted_datasets[0]
- else:
- return None
-
- # Conversion is possible but hasn't been done yet, run converter here
- # FIXME: this is largely duplicated from DefaultToolAction
- assoc = model.ImplicitlyConvertedDatasetAssociation( parent = dataset, file_type = type, metadata_safe = False )
- new_dataset = dataset.datatype.convert_dataset( trans, dataset, type, return_output = True, visible = False ).values()[0]
- new_dataset.hid = dataset.hid # Hrrmmm....
- new_dataset.name = dataset.name
- trans.sa_session.add( new_dataset )
- trans.sa_session.flush()
- assoc.dataset = new_dataset
- trans.sa_session.add( assoc )
- trans.sa_session.flush()
- return new_dataset
@web.json
def save( self, trans, **kwargs ):
diff -r 40e8c99829e0 -r f29af7c51377 static/scripts/packed/trackster.js
--- a/static/scripts/packed/trackster.js Thu Apr 01 13:08:48 2010 -0400
+++ b/static/scripts/packed/trackster.js Thu Apr 01 14:24:47 2010 -0400
@@ -1,1 +1,1 @@
-var DEBUG=false;var DENSITY=1000,FEATURE_LEVELS=10,DATA_ERROR="There was an error in indexing this dataset.",DATA_NOCONVERTER="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",DATA_NONE="No data for this chrom/contig.",DATA_PENDING="Currently indexing... please wait",DATA_LOADING="Loading data...",CACHED_TILES_FEATURE=10,CACHED_TILES_LINE=30,CACHED_DATA=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
+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){FeatureTrack.call(this,c,a,b);this.track_type="ReadTrack"};$.extend(ReadT!
rack.prototype,TiledTrack.prototype,FeatureTrack.prototype,{});
\ No newline at end of file
diff -r 40e8c99829e0 -r f29af7c51377 static/scripts/trackster.js
--- a/static/scripts/trackster.js Thu Apr 01 13:08:48 2010 -0400
+++ b/static/scripts/trackster.js Thu Apr 01 14:24:47 2010 -0400
@@ -89,7 +89,6 @@
drawer = new Drawer();
-
var View = function( chrom, title, vis_id, dbkey ) {
this.vis_id = vis_id;
this.dbkey = dbkey;
@@ -852,7 +851,7 @@
}
j++;
}
- }
+ }
parent_element.append( new_canvas );
return new_canvas;
@@ -885,15 +884,12 @@
});
var ReadTrack = function ( name, dataset_id, prefs ) {
+ FeatureTrack.call( this, name, dataset_id, prefs );
this.track_type = "ReadTrack";
- this.tile_cache = new Cache(CACHED_TILES_FEATURE);
- Track.call( this, name, $("#viewport") );
- TiledTrack.call( this );
- FeatureTrack.call( this, name, dataset_id, prefs );
};
$.extend( ReadTrack.prototype, TiledTrack.prototype, FeatureTrack.prototype, {
- draw_tile: function( resolution, tile_index, parent_element, w_scale ) {
+ /*draw_tile: function( resolution, tile_index, parent_element, w_scale ) {
if (!this.values) {
return;
}
@@ -947,5 +943,5 @@
parent_element.append( new_canvas );
return new_canvas;
- }
+ }*/
});
1
0
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/40e8c99829e0
changeset: 3591:40e8c99829e0
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Thu Apr 01 13:08:48 2010 -0400
description:
Add bed6 and bed12 datatypes, which are subclasses of bedstrict; converters are available to turn any interval datatype into these types. Change GeneTrack Indexer tool and converter to use bed6 as input.
diffstat:
datatypes_conf.xml.sample | 7 +-
display_applications/genetrack.xml | 2 +-
lib/galaxy/datatypes/converters/bed_to_genetrack_converter.xml | 4 +-
lib/galaxy/datatypes/converters/interval_to_bed12_converter.xml | 15 +
lib/galaxy/datatypes/converters/interval_to_bed6_converter.xml | 15 +
lib/galaxy/datatypes/converters/interval_to_bedstrict_converter.py | 81 +++++++--
lib/galaxy/datatypes/interval.py | 10 +
tools/genetrack/genetrack_indexer.xml | 4 +-
8 files changed, 111 insertions(+), 27 deletions(-)
diffs (261 lines):
diff -r fa70c688cda1 -r 40e8c99829e0 datatypes_conf.xml.sample
--- a/datatypes_conf.xml.sample Thu Apr 01 10:56:59 2010 -0400
+++ b/datatypes_conf.xml.sample Thu Apr 01 13:08:48 2010 -0400
@@ -13,11 +13,14 @@
<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_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" />
</datatype>
<datatype extension="bedstrict" type="galaxy.datatypes.interval:BedStrict" />
+ <datatype extension="bed6" type="galaxy.datatypes.interval:Bed6">
+ <converter file="bed_to_genetrack_converter.xml" target_datatype="genetrack"/>
+ </datatype>
+ <datatype extension="bed12" type="galaxy.datatypes.interval:Bed12" />
<datatype extension="binseq.zip" type="galaxy.datatypes.binary:Binseq" mimetype="application/zip" display_in_upload="true"/>
<datatype extension="len" type="galaxy.datatypes.chrominfo:ChromInfo" display_in_upload="true">
<!-- no converters yet -->
@@ -49,6 +52,8 @@
<datatype extension="interval" type="galaxy.datatypes.interval:Interval" display_in_upload="true">
<converter file="interval_to_bed_converter.xml" target_datatype="bed"/>
<converter file="interval_to_bedstrict_converter.xml" target_datatype="bedstrict"/>
+ <converter file="interval_to_bed6_converter.xml" target_datatype="bed6"/>
+ <converter file="interval_to_bed12_converter.xml" target_datatype="bed12"/>
<indexer file="interval_awk.xml" />
<!-- <display file="ucsc/interval_as_bed.xml" inherit="True" /> -->
<display file="genetrack.xml" inherit="True"/>
diff -r fa70c688cda1 -r 40e8c99829e0 display_applications/genetrack.xml
--- a/display_applications/genetrack.xml Thu Apr 01 10:56:59 2010 -0400
+++ b/display_applications/genetrack.xml Thu Apr 01 13:08:48 2010 -0400
@@ -1,7 +1,7 @@
<display id="genetrack_interval" version="1.0.0" name="view in">
<link id="genetrack" name="GeneTrack">
<url target_frame="galaxy_main">http://genetrack.g2.bx.psu.edu/galaxy?filename=${encoded_filename.qp}&h…</url>
- <param type="data" name="bed_file" viewable="False" format="bed,genetrack"/> <!-- for now, we'll explicitly take care of the multi-step conversion; walk genetrack datatype down as a conversion of genetrack to genetrack doesn't exist and would likely be pointless -->
+ <param type="data" name="bed_file" viewable="False" format="bed6,genetrack"/> <!-- for now, we'll explicitly take care of the multi-step conversion; walk genetrack datatype down as a conversion of genetrack to genetrack doesn't exist and would likely be pointless -->
<param type="data" dataset="bed_file" name="genetrack_file" format="genetrack" viewable="False" />
<param type="template" name="galaxy_url" strip="True" >
${BASE_URL}/tool_runner?tool_id=predict2genetrack
diff -r fa70c688cda1 -r 40e8c99829e0 lib/galaxy/datatypes/converters/bed_to_genetrack_converter.xml
--- a/lib/galaxy/datatypes/converters/bed_to_genetrack_converter.xml Thu Apr 01 10:56:59 2010 -0400
+++ b/lib/galaxy/datatypes/converters/bed_to_genetrack_converter.xml Thu Apr 01 13:08:48 2010 -0400
@@ -1,4 +1,4 @@
-<tool id="CONVERTER_bed_to_genetrack_0" name="Convert BED to GeneTrack Index" version="1.0.0">
+<tool id="CONVERTER_bed_to_genetrack_0" name="Convert BED to GeneTrack Index" version="1.0.1">
<!-- FIXME: THIS IS ALMOST 1:1 COPY OF THE SAME FUNCTIONED TOOL - ALLOW REGULAR TOOLS TO MASCARADE AS CONVERTERS
Using a shift of 0, but tool allows specifying...
-->
@@ -6,7 +6,7 @@
<command interpreter="python">bed_to_genetrack_converter.py -i $input1 -o $output1 -s 0 -v 0 -f BED -x</command>
<inputs>
<page>
- <param format="bed" name="input1" type="data" label="Choose BED file"/>
+ <param format="bed6" name="input1" type="data" label="Choose BED file"/>
</page>
</inputs>
<outputs>
diff -r fa70c688cda1 -r 40e8c99829e0 lib/galaxy/datatypes/converters/interval_to_bed12_converter.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/datatypes/converters/interval_to_bed12_converter.xml Thu Apr 01 13:08:48 2010 -0400
@@ -0,0 +1,15 @@
+<tool id="CONVERTER_interval_to_bed12_0" name="Convert Genomic Intervals To Strict BED12">
+ <!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
+ <!-- Used on the metadata edit page. -->
+ <command interpreter="python">interval_to_bedstrict_converter.py $output1 $input1 ${input1.metadata.chromCol} ${input1.metadata.startCol} ${input1.metadata.endCol} ${input1.metadata.strandCol} ${input1.metadata.nameCol} ${input1.extension} 12</command>
+ <inputs>
+ <page>
+ <param format="interval" name="input1" type="data" label="Choose intervals"/>
+ </page>
+ </inputs>
+ <outputs>
+ <data format="bed12" name="output1"/>
+ </outputs>
+ <help>
+ </help>
+</tool>
diff -r fa70c688cda1 -r 40e8c99829e0 lib/galaxy/datatypes/converters/interval_to_bed6_converter.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/datatypes/converters/interval_to_bed6_converter.xml Thu Apr 01 13:08:48 2010 -0400
@@ -0,0 +1,15 @@
+<tool id="CONVERTER_interval_to_bed6_0" name="Convert Genomic Intervals To Strict BED6">
+ <!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> -->
+ <!-- Used on the metadata edit page. -->
+ <command interpreter="python">interval_to_bedstrict_converter.py $output1 $input1 ${input1.metadata.chromCol} ${input1.metadata.startCol} ${input1.metadata.endCol} ${input1.metadata.strandCol} ${input1.metadata.nameCol} ${input1.extension} 6</command>
+ <inputs>
+ <page>
+ <param format="interval" name="input1" type="data" label="Choose intervals"/>
+ </page>
+ </inputs>
+ <outputs>
+ <data format="bed6" name="output1"/>
+ </outputs>
+ <help>
+ </help>
+</tool>
diff -r fa70c688cda1 -r 40e8c99829e0 lib/galaxy/datatypes/converters/interval_to_bedstrict_converter.py
--- a/lib/galaxy/datatypes/converters/interval_to_bedstrict_converter.py Thu Apr 01 10:56:59 2010 -0400
+++ b/lib/galaxy/datatypes/converters/interval_to_bedstrict_converter.py Thu Apr 01 13:08:48 2010 -0400
@@ -12,6 +12,27 @@
sys.stderr.write( msg )
sys.exit()
+def force_bed_field_count( fields, region_count, force_num_columns ):
+ if force_num_columns >= 4 and len( fields ) < 4:
+ fields.append( 'region_%i' % ( region_count ) )
+ if force_num_columns >= 5 and len( fields ) < 5:
+ fields.append( '0' )
+ if force_num_columns >= 6 and len( fields ) < 6:
+ fields.append( '+' )
+ if force_num_columns >= 7 and len( fields ) < 7:
+ fields.append( fields[1] )
+ if force_num_columns >= 8 and len( fields ) < 8:
+ fields.append( fields[2] )
+ if force_num_columns >= 9 and len( fields ) < 9:
+ fields.append( '0' )
+ if force_num_columns >= 10 and len( fields ) < 10:
+ fields.append( '0' )
+ if force_num_columns >= 11 and len( fields ) < 11:
+ fields.append( ',' )
+ if force_num_columns >= 12 and len( fields ) < 12:
+ fields.append( ',' )
+ return fields[:force_num_columns]
+
def __main__():
output_name = sys.argv[1]
input_name = sys.argv[2]
@@ -39,6 +60,10 @@
extension = sys.argv[8]
except:
extension = 'interval' #default extension
+ try:
+ force_num_columns = int( sys.argv[9] )
+ except:
+ force_num_columns = None
skipped_lines = 0
first_skipped_line = None
@@ -47,40 +72,52 @@
#does file already conform to bed strict?
#if so, we want to keep extended columns, otherwise we'll create a generic 6 column bed file
strict_bed = True
- if extension in [ 'bed', 'bedstrict' ] and ( chromCol, startCol, endCol, nameCol, strandCol ) == ( 0, 1, 2, 3, 5 ):
+ if extension in [ 'bed', 'bedstrict', 'bed6', 'bed12' ] and ( chromCol, startCol, endCol) == ( 0, 1, 2) and ( nameCol < 0 or nameCol == 3 ) and ( strandCol < 0 or strandCol == 5 ):
for count, line in enumerate( open( input_name ) ):
- line = line.strip()
+ line = line.rstrip( '\n\r' )
if line == "" or line.startswith("#"):
skipped_lines += 1
if first_skipped_line is None:
first_skipped_line = count + 1
continue
fields = line.split('\t')
+ assert len( fields ) >= 3, 'A BED file requires at least 3 columns' #we can't fix this
try:
if len(fields) > 12:
strict_bed = False
break
- if len(fields) > 6:
- int(fields[6])
- if len(fields) > 7:
- int(fields[7])
- if len(fields) > 8:
- if int(fields[8]) != 0:
- strict_bed = False
- break
- if len(fields) > 9:
- int(fields[9])
- if len(fields) > 10:
- fields2 = fields[10].rstrip(",").split(",") #remove trailing comma and split on comma
- for field in fields2:
- int(field)
- if len(fields) > 11:
- fields2 = fields[11].rstrip(",").split(",") #remove trailing comma and split on comma
+ #name (fields[3]) can be anything, no verification needed
+ if len( fields ) > 4:
+ float( fields[4] ) #score - A score between 0 and 1000. If the track line useScore attribute is set to 1 for this annotation data set, the score value will determine the level of gray in which this feature is displayed (higher numbers = darker gray).
+ if len( fields ) > 5:
+ assert fields[5] in [ '+', '-' ], 'Invalid strand' #strand - Defines the strand - either '+' or '-'.
+ if len( fields ) > 6:
+ int( fields[6] ) #thickStart - The starting position at which the feature is drawn thickly (for example, the start codon in gene displays).
+ if len( fields ) > 7:
+ int( fields[7] ) #thickEnd - The ending position at which the feature is drawn thickly (for example, the stop codon in gene displays).
+ if len( fields ) > 8:
+ if fields[8] != '0': #itemRgb - An RGB value of the form R,G,B (e.g. 255,0,0). If the track line itemRgb attribute is set to "On", this RBG value will determine the display color of the data contained in this BED line. NOTE: It is recommended that a simple color scheme (eight colors or less) be used with this attribute to avoid overwhelming the color resources of the Genome Browser and your Internet browser.
+ fields2 = fields[8].split( ',' )
+ assert len( fields2 ) == 3, 'RGB value must be 0 or have length of 3'
for field in fields2:
- int(field)
+ int( field ) #rgb values are integers
+ if len( fields ) > 9:
+ int( fields[9] ) #blockCount - The number of blocks (exons) in the BED line.
+ if len( fields ) > 10:
+ if fields[10] != ',': #blockSizes - A comma-separated list of the block sizes. The number of items in this list should correspond to blockCount.
+ fields2 = fields[10].rstrip( "," ).split( "," ) #remove trailing comma and split on comma
+ for field in fields2:
+ int( field )
+ if len( fields ) > 11:
+ if fields[11] != ',': #blockStarts - A comma-separated list of block starts. All of the blockStart positions should be calculated relative to chromStart. The number of items in this list should correspond to blockCount.
+ fields2 = fields[11].rstrip( "," ).split( "," ) #remove trailing comma and split on comma
+ for field in fields2:
+ int( field )
except:
strict_bed = False
break
+ if force_num_columns is not None and len( fields ) != force_num_columns:
+ line = '\t'.join( force_bed_field_count( fields, count, force_num_columns ) )
out.write( "%s\n" % line )
else:
strict_bed = False
@@ -100,8 +137,10 @@
except:
name = "region_%i" % count
try:
-
- out.write( "%s\t%i\t%i\t%s\t%i\t%s\n" % ( region.chrom, region.start, region.end, name, 0, region.strand ) )
+ fields = map( str, [ region.chrom, region.start, region.end, name, 0, region.strand ] )
+ if force_num_columns is not None and len( fields ) != force_num_columns:
+ fields = force_bed_field_count( fields, count, force_num_columns )
+ out.write( "%s\n" % '\t'.join( fields ) )
except:
skipped_lines += 1
if first_skipped_line is None:
diff -r fa70c688cda1 -r 40e8c99829e0 lib/galaxy/datatypes/interval.py
--- a/lib/galaxy/datatypes/interval.py Thu Apr 01 10:56:59 2010 -0400
+++ b/lib/galaxy/datatypes/interval.py Thu Apr 01 13:08:48 2010 -0400
@@ -536,6 +536,16 @@
def sniff( self, filename ):
return False #NOTE: This would require aggressively validating the entire file
+class Bed6( BedStrict ):
+ """Tab delimited data in strict BED format - no non-standard columns allowed; column count forced to 6"""
+
+ file_ext = "bed6"
+
+class Bed12( BedStrict ):
+ """Tab delimited data in strict BED format - no non-standard columns allowed; column count forced to 12"""
+
+ file_ext = "bed12"
+
class _RemoteCallMixin:
def _get_remote_call_url( self, redirect_url, site_name, dataset, type, app, base_url ):
"""Retrieve the URL to call out to an external site and retrieve data.
diff -r fa70c688cda1 -r 40e8c99829e0 tools/genetrack/genetrack_indexer.xml
--- a/tools/genetrack/genetrack_indexer.xml Thu Apr 01 10:56:59 2010 -0400
+++ b/tools/genetrack/genetrack_indexer.xml Thu Apr 01 13:08:48 2010 -0400
@@ -1,4 +1,4 @@
-<tool id="bed2genetrack" name="GeneTrack indexer">
+<tool id="bed2genetrack" name="GeneTrack indexer" version="1.0.1">
<description>on a BED file</description>
@@ -8,7 +8,7 @@
<inputs>
- <param format="bed" name="input" type="data" help="Input data">
+ <param format="bed6" name="input" type="data" help="Input data">
<label>Select input bed file</label>
</param>
1
0
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/fa70c688cda1
changeset: 3590:fa70c688cda1
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Thu Apr 01 10:56:59 2010 -0400
description:
Importing a workflow makes a copy rather than sharing it.
diffstat:
lib/galaxy/web/controllers/workflow.py | 13 ++++++++-----
1 files changed, 8 insertions(+), 5 deletions(-)
diffs (25 lines):
diff -r ac96e6e33164 -r fa70c688cda1 lib/galaxy/web/controllers/workflow.py
--- a/lib/galaxy/web/controllers/workflow.py Wed Mar 31 17:46:25 2010 -0400
+++ b/lib/galaxy/web/controllers/workflow.py Thu Apr 01 10:56:59 2010 -0400
@@ -299,13 +299,16 @@
# TODO: this is only reasonable as long as import creates a sharing relation.
return trans.show_error_message( "You can't import this workflow because it is already shared with you.<br>You can %s" % referer_message, use_panels=True )
else:
- # TODO: Shouldn't an import provide a copy of a workflow?
- share = model.StoredWorkflowUserShareAssociation()
- share.stored_workflow = stored
- share.user = trans.user
+ # Create imported workflow via copy.
+ imported_stored = model.StoredWorkflow()
+ imported_stored.name = "imported: " + stored.name
+ imported_stored.latest_workflow = stored.latest_workflow
+ imported_stored.user = trans.user
+ # Save new workflow.
session = trans.sa_session
- session.add( share )
+ session.add( imported_stored )
session.flush()
+
# Redirect to load galaxy frames.
return trans.show_ok_message(
message="""Workflow "%s" has been imported. <br>You can <a href="%s">start using this workflow</a> or %s."""
1
0
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/ac96e6e33164
changeset: 3589:ac96e6e33164
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Wed Mar 31 17:46:25 2010 -0400
description:
Add Tophat tool. Components: a wrapper script, indicecs file, test data, and functional test. It may be useful to have a single indices file for both Tophat and Bowtie because Tophat uses Bowtie.
diffstat:
test-data/tophat_in1.fq | 400 ++++++++++++++++++++++++++++++++++++
test-data/tophat_in2.fq | 400 ++++++++++++++++++++++++++++++++++++
test-data/tophat_out1.sam | 181 ++++++++++++++++
test-data/tophat_out2.wig | 175 +++++++++++++++
test-data/tophat_out3.bed | 3 +
tool-data/tophat_indices.loc.sample | 29 ++
tool_conf.xml.sample | 5 +-
tools/tophat/tophat_wrapper.py | 80 +++++++
tools/tophat/tophat_wrapper.xml | 129 +++++++++++
9 files changed, 1401 insertions(+), 1 deletions(-)
diffs (1444 lines):
diff -r c30c7c98ce61 -r ac96e6e33164 test-data/tophat_in1.fq
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/tophat_in1.fq Wed Mar 31 17:46:25 2010 -0400
@@ -0,0 +1,400 @@
+@test_mRNA_150_290_0/1
+TCCTAAAAAGTCCGCCTCGGTCTCAGTCTCAAGTAGAAAAAGTCCCGTTGGCGATCCGTCTACGTCCGAGTAAGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_8_197_1/1
+TCTGACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGACACTACGGGGATGGCGACTAGGACTACGGACGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_82_255_2/1
+GAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAATATAGTAAAGTAATAGTGGCGTATCGCAAGCTCGACG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_96_238_3/1
+GATCCGTCTACGTCCGCGTAAGATAATAAAGTACTAGTAGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_72_258_4/1
+GTAGAAAAAGTCCCGTTGCCCATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_107_286_5/1
+AAAAAGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_122_299_6/1
+CAAGTCCCGTCCTAAAAAGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGCTCCGTCTACGTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_58_234_7/1
+AGTCTACGTCCGAGTCAGATAATAAACTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_57_231_8/1
+GGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCACCGACTGGACTATTTAGGACGATCGGACTG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_8_155_9/1
+TACGTAGCGTCCTACTGCCCTCCTCAGTCCGATCGTCCTAAATAGTACAGTCGCTGCATCTGACGCTCGAAGTCC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_51_237_a/1
+ACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_89_230_b/1
+TACGTCCGAGTGAGTTAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_105_276_c/1
+CCTCGATCCCAGTCTCAAGTAGAAAAAGCCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_111_268_d/1
+CCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAATAATAGTGGCGTAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_151_286_e/1
+ACGTATTTGGCGCGCGGCCGTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_118_297_f/1
+AGTCCCGTCCTAAAAAGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_16_194_10/1
+TCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCGATCGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_28_188_11/1
+TTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGAACGGACTTAGAGCGTCAGATGCAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_36_218_12/1
+GAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGCCTTAGAGCGTCAGATGCAGCGACTGGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_105_266_13/1
+AGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGGATCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_51_248_14/1
+ACTACGGGGATGACGACGAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGAACTTTTTAGGACGATC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_89_245_15/1
+AGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_58_218_16/1
+AGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_46_195_17/1
+ATCCCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGACAAATATGTAGCGTCCTACTGCCCTCCTCAGTCCAATCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_126_282_18/1
+AGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_53_212_19/1
+TACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGAATATTTAGGACGATCGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_11_190_1a/1
+GACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_52_261_1b/1
+CTACGGGAATGACGACTAGGGCTACGGAGGGACTTACAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_104_274_1c/1
+TCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_151_297_1d/1
+ACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_44_225_1e/1
+CCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCATATACGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_28_206_1f/1
+TTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGACGCAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_48_249_20/1
+GTCCCGTTGCCGATCCGTCTCCGTCCGAGTAAGATAGTAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_75_235_21/1
+ACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGCACGATCGGACTGAGGAGGGCAGTAGAACGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_110_267_22/1
+CAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_69_229_23/1
+ACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTAGACGCTCAGCCGTAGGGCCGCGCGCCAAAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_21_208_24/1
+GTAATAGTGGCGTATCGCAAGCTCGACGCTCAGGCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_42_209_25/1
+GGACGTGCCACTACGTGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_97_275_26/1
+ATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_36_146_27/1
+ACCTACTGCACTCCTCAGTCCGATCGTCCTAAATAGTCCAGTCGCTGCATCTGACGCTCTAAGTCCGTCCGTAGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_110_271_28/1
+ACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_38_199_29/1
+GCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_103_284_2a/1
+AAAGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_116_271_2b/1
+ATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCTGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_77_256_2c/1
+GGACGGACTTAGAGCATCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_50_224_2d/1
+CGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_65_238_2e/1
+GACTAGGACTACGGACGGACTTAGAGCGTCAGAAGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_46_232_2f/1
+GTGCCACTACGGGGATGACGACTAGGACTACGGCCGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_26_189_30/1
+AGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTACCGTCCTACTGCCCTCCTCAGTCCGATCGTCCTAA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_79_256_31/1
+AGAAAAAGTCCCGTTGCCGATCCGGCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATGGCAAGCTCGAC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_89_267_32/1
+CAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGAAAGATAATAAAGTAATAGTGCCGTATC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_131_260_33/1
+GAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_73_240_34/1
+CTACGGACGGACTTAGAGCGTCAGATGCAGCGAATGGACTATTTAGGACGCTCGGACTGAGGAGGGCAGTAGGAC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_44_197_35/1
+ACGTGCAACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_128_252_36/1
+ACTGAGGAGGGCAGTAGGACGCTACGCATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATAGGCCAC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_145_300_37/1
+GCAAGTCCCGTCCTAAAAAGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTTCCGATCCGTCTACGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_85_275_38/1
+TTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGAAGCTACGTCTTTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_48_207_39/1
+GCCCCTACGGGGATGACGACTAGGACTACGGACGGATTTAGACCGTCAGATGCAGCGACTGGACTATTTAGGACG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_81_228_3a/1
+CCTACGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCATAGGGCCGCGCGCCAAATA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_75_277_3b/1
+ACGGACGGACTTAAAGCTTCAGATGCAGCGACAGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_30_231_3c/1
+CTACGTGCGAGTAAGATATTAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTTAGCCGTAGGGCCGCGCGCCAA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_58_220_3d/1
+GAAGATAATAAAGTAATAGTGGCGTATCGCAACCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_104_278_3e/1
+CGCCTCGATTCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_44_193_3f/1
+ACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGTCTATTTAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_94_291_40/1
+CAGATGCAGCGACTGTACTATTTAGGACGACCTGACTGAGGAGGGTAGTAGGACGCTACGTATTTGGCGCGCGGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_91_256_41/1
+CGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_23_186_42/1
+TCGACGCTCAGTCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTTCTGCCCTCCTCCGTCCGATCGTCCTAAATA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_92_266_43/1
+GTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTCAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_92_250_44/1
+GTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_106_253_45/1
+AAAAGTCCCGTTGCCGATCCGTTTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_5_197_46/1
+CTATCTGACTAGACTCGAGGCGCTTGCGTCTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_51_194_47/1
+TCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCGATCGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_125_280_48/1
+CGGACTGAGGAGGGCAGTAGGACGCTATGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGAAACGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_51_194_49/1
+ACTACGGGGATGACGACTAGGCCTACGGATGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_33_189_4a/1
+AGCCCGACGCTCAGCCGTAGGGCCGCGCGCCAAATAGGTAGCGTCCTACTGCCCTCCTCAGTCCGATCGTCCTAA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_78_276_4b/1
+GACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGGCGCTAC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_63_229_4c/1
+ACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACACTCAGCCGTAGGGCCGCGCGCCAAAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_81_245_4d/1
+CGTTGCCGATCCGTCTACGTCCGAGTAAGATTATAAAGTAATAGTGGCGTATCGCAACCTCGACGCTCAGCCGTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_33_223_4e/1
+ACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_172_294_4f/1
+ACGGATGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTCCTCGGACGTAGACGGATCGCCAACGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_88_257_50/1
+TAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_3_187_51/1
+TACTATTTGACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTCGGACTACG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_9_179_52/1
+TCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCGATCGTCCTAAATGGTCCAGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_85_268_53/1
+TTAGTGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_75_204_54/1
+ACGGACGGACTTCGAGCCTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_41_236_55/1
+AGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGAATATT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_56_183_56/1
+GGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTGGGACGATCGGACT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_87_250_57/1
+AGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_82_271_58/1
+GACTTAGAGCGTCAGTTGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_6_182_59/1
+TATCTGACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGCCAGTACGGGGATGACGACTAGGACTACGGAC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_53_272_5a/1
+GATCCCAGTGTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_114_277_5b/1
+GCCTCGATCCCAGTCTCAAGCAGAAAAAGTCCCGTTGCCGTTCCGTCTACCTCCGAGTAAGATAATAAAGTAATA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_39_219_5c/1
+CTAGGACGTCCCACTATGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGGCTGGACTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_4_191_5d/1
+CAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGTGTCCTACTGCCCTACTCAGTCCGATCGTCCT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_73_259_5e/1
+CTACGGACGGACTTAGAGCGTCAGATGCTGCGACTGGACTATTTGGGACGATCGGACTGAGGAGGGCAGTAGGAC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_87_279_5f/1
+CCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_125_293_60/1
+CCGTCCTAAAAAGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_111_297_61/1
+AGTCCCGTCCTAAAAAGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCGGATCCGTCTACGTCCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_22_173_62/1
+AGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_116_295_63/1
+TCCCGTCCTAAAAAGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
diff -r c30c7c98ce61 -r ac96e6e33164 test-data/tophat_in2.fq
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/tophat_in2.fq Wed Mar 31 17:46:25 2010 -0400
@@ -0,0 +1,400 @@
+@test_mRNA_150_290_0/2
+TACGTATTTGTCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATCCGCCACTATTACTTTATTATCTTACTCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_8_197_1/2
+GTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCGAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_82_255_2/2
+GACTTAGAGCGTCAGATGCAGCGACTGGACTTTTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_96_238_3/2
+GATGCAGCGACTGGACTATTTAGGACGATCGGACGGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGACC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_72_258_4/2
+ACTACGGACGGACTTAGAGCGTCAGATGCAGCAACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_107_286_5/2
+TGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGCATTTGGCGCGCGGCCCTACGGCTGAGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_122_299_6/2
+GATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_58_234_7/2
+GGATGACGCCTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_57_231_8/2
+CTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCCTAGGGCCGCGCGCCAA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_8_155_9/2
+TGTGACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_51_237_a/2
+ATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_89_230_b/2
+AGCGTCAGGTGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_105_276_c/2
+ACTGGACTATTTAGGACGATCGGACTGAGGAAGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_111_268_d/2
+CTATTTAAGACGTTCCGCCTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_151_286_e/2
+AAAAAGTCCGCCTCGATCCCAGTCTCAAGTAGATAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_118_297_f/2
+GGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_16_194_10/2
+GACTGGATGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTCGGACTACGGACGGACTTAAAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_28_188_11/2
+GCTCGACGCTCAGCCGTAGGGCCTCGCGCCAAATACGAAGCGTCCTACTGCCTTCCTCAGTCCGATCGTCCTAAA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_36_218_12/2
+AGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_105_266_13/2
+ACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_51_248_14/2
+TCCCGTTGCCGTTCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_89_245_15/2
+CGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAGAGAAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_58_218_16/2
+GGATGACGACTAGGACTACGGACGGACTTAGAACGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_46_195_17/2
+GTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_126_282_18/2
+GGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_53_212_19/2
+TAAAGAAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_11_190_1a/2
+AAGCTCGACGCTCAGCCGTAGGGCCACGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCCATCGACCTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_52_261_1b/2
+CAAGTAGAAAAAGTCCCGTTGCCGATCCTTCTACGTCCGAGTAAGATAATTAAGTAATAGTGGCGTATCGCAAGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_104_274_1c/2
+GAGTGTACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATGTGCCGCGCGGCCCTACGGCTG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_151_297_1d/2
+AGTCCCGTCCTAAAATGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_44_225_1e/2
+ACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCGGGTGCAGCGACTGGACTATTTAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_28_206_1f/2
+AATAGTGGCTTATCGCAAGCTCGACTCTCAGCCGTAGGGCCGCGCGCCAAATACGTGGCGTCCTACTGCCCTCCT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_48_249_20/2
+GCCACTACGGGGATGACGACTAGGACGACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_75_235_21/2
+CCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCAACGCTCAGCCGTAGGGCCGTGCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_110_267_22/2
+ACTAGTTAGGGCGATCGGACTGAGGAGGGCAGTAGGACGCTACGTAGTTGGCGCGCGGCCCTACGACTGAGCGTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_69_229_23/2
+AGGACTACGGACGGACTTATAGGGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_21_208_24/2
+GAGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_42_209_25/2
+AGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_97_275_26/2
+CTCGATCCCAGTCTCAAGTAGAAAGAGTCCCGTTTCCGATCCGTCTACGTCCGACTAAGATAATAAAGTAATAGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_36_146_27/2
+GCGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACAGACGGACTTAGAGCGTCAGATGCAGCGACTGGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_110_271_28/2
+ATCCCAGTCTCAAGTAGAAAAAGCCCCGTTGCCGATCCGTCTTCGTCCGAGTAAGATAATAAAGTAATAGTGGCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_38_199_29/2
+GCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_103_284_2a/2
+CGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_116_271_2b/2
+TAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_77_256_2c/2
+AGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGAC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_50_224_2d/2
+CACTACGAGGATGACGTCTAGGACTACGGACGGACTTAGAGCGTCAGACGCAGCGACTGGACTATTTAGGACGAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_65_238_2e/2
+GATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCGCAGCCGTAGGGCCGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_46_232_2f/2
+TCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_26_189_30/2
+GCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_79_256_31/2
+ACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_89_267_32/2
+AGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGAGTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_131_260_33/2
+AAGTAAAAAAAGTCCCGTGGCCGATCCGTTTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCACAAGCT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_73_240_34/2
+CCGATCCGTCTACGTCCGAGAAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_44_197_35/2
+GTATCGCAAGCTCGACGATCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCGAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_128_252_36/2
+AAAGTCCCGTTCCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_145_300_37/2
+GACGCTACGTATTTGGCGCGGGGCCCTATGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTAGTATATT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_85_275_38/2
+CTCGATCCCAGTCTCAAGTAGTAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAAGAGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_48_207_39/2
+TAAGAGTGGCGTATCGCAAGATCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTTCCCTCC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_81_228_3a/2
+GGACTGAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGTAGTAGGACGCTACGTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_75_277_3b/2
+GCCTCGATCCCAGTCTCAGGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_30_231_3c/2
+GCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_58_220_3d/2
+GGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_104_278_3e/2
+GACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTTTTTGGCGCGCGGCCCTACGGCTG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_44_193_3f/2
+CGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCTCTCCCCAGTCCGATCGTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_94_291_40/2
+GTCCCAAAAAGTCCGCCTCGATCCCAGTCTCAAGTAGAAAATGTCGCGTTGCCGATCCGTCTACGTCCCAGGAAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_91_256_41/2
+AGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGAC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_23_186_42/2
+GGCGCTTGTGACTGAGCTAGGACGTGCCACTACGGGGATGAAGACTAGGACTACGGACGGACTTAGAGCGTCAGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_92_266_43/2
+GGTCTCAAGTAGAAAAAGTCCCGTTGCCGCTCCGTCTACGTCCGAGTAAGATAAGAAAGTAATAGTGGCGTATCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_92_250_44/2
+AGTCCCGTACCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_106_253_45/2
+CTGGACTATTTAGGTCGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_5_197_46/2
+GTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCCCGCCAAATACGTAGCGTCCTACTGCCCTCCTCCGTCCGAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_51_194_47/2
+ACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_125_280_48/2
+TCCGCCTCGCTCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCAGAGTAAGATAATAAAGTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_51_194_49/2
+CCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTGGCGTCCTACTGCCCTCCTCAGTCCGAACGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_33_189_4a/2
+ACTGAGCTAGGACGTGCCACTACGGGGATTACCACTAGGGCTACGGACGGACTTAGAGCGTCAGATGCAGCGACT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_78_276_4b/2
+CCTCGATCCTAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_63_229_4c/2
+ACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGGGACTGGACTATTTAGGACGATCGGACTGAGGAGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_81_245_4d/2
+GGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGATGAGGGCAGTAGGACGCTACGTA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_33_223_4e/2
+GAGTTAGATAATAAAGTAATAGTGGCTTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACCTAG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_172_294_4f/2
+CCCGTCCTAAAACGTCCGCCTCGATCCCAGTCTCAAGTAGAAAAAGTCCCGCTGCCGACCCGTCTACGTCCGAGT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_88_257_50/2
+GAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_3_187_51/2
+CTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCGATCGTCCTAAAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_9_179_52/2
+CTGACTAGACTGGAGGCGCTCGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_85_268_53/2
+CCAGTCTCAAGTAGAAAAAGTCCCGTTGACGATCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTAT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_75_204_54/2
+TCGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_41_236_55/2
+TCCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCGTATCGCAAGCTCGACGCTCAGCCGTAGGGCCGCGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_56_183_56/2
+ACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCGATCGTCCTAAATAGTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_87_250_57/2
+AGAGCGTCAGATGCAGAGACTGGACTATTTAGGACGATCGGACTGAGGAGTGCAGTAGGACGCTACGTATTTGGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_82_271_58/2
+ATCCCAGTCTCAAGTAGAAAAAGTCCCGTTGCCGATGCGTCTACGTCCGAGTAAGATAATAAAGTAATAGTGGCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_6_182_59/2
+CGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCGATCGTCCTAAATAGTCC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_53_272_5a/2
+TACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_114_277_5b/2
+TTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGCCTGAGCGTCGAGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_39_219_5c/2
+AAGATAATAAAGTAATAGTGGCGTATCGCAAGCTGGACGCTCAGCCGTAGGGCCGCGCGCCAAATACGTAGCGTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_4_191_5d/2
+ACTATCTGACGAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTACCATTACGCGGATGACGACTAGGACTACGG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_73_259_5e/2
+AGTAGAAAAAGTCCCGTTGCCGATCCGTCTACGTCCGAGTAAGATAATACAGTAATAGTGGCGTATCGCAAGCTC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_87_279_5f/2
+AGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACCGAGGAGGGCAGTAGGACGCTACGTATTTGGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_125_293_60/2
+CGGACTGAGGAGGGCAGTAGGACGCTATGTATTTGGCGCGCGGCCCTACGGCTGAGCTTCGAGGTTGCGATACGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_111_297_61/2
+CTATTTAGGACGATCGGACTGGGGAGGGCAGTAGGACGCTACGGATTTGGCGCGCGGCCCTACGGCTGAGCGTCG
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_22_173_62/2
+GTAGGGCCGCGCGCCAAATACGTAGCGTCCTACTGCCCTCCTCAGTCCGATCGTCCTAAATAGTCCAGTCGCTGC
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+@test_mRNA_116_295_63/2
+TAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTT
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
diff -r c30c7c98ce61 -r ac96e6e33164 test-data/tophat_out1.sam
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/tophat_out1.sam Wed Mar 31 17:46:25 2010 -0400
@@ -0,0 +1,181 @@
+@HD VN:1.0 SO:sorted
+@PG TopHat VN:1.0.13 CL:/Users/jeremy/projects/bx_tools/tophat-1.0.13/bin/tophat -r 20 test_ref reads_1.fq reads_2.fq
+test_mRNA_3_187_51 99 test_chromosome 53 255 75M = 163 0 TACTATTTGACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTCGGACTACG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_4_191_5d 163 test_chromosome 54 255 75M = 167 0 ACTATCTGACGAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTACCATTACGCGGATGACGACTAGGACTACGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4
+test_mRNA_5_197_46 97 test_chromosome 55 255 75M = 173 0 CTATCTGACTAGACTCGAGGCGCTTGCGTCTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_6_182_59 99 test_chromosome 56 255 75M = 158 0 TATCTGACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGCCAGTACGGGGATGACGACTAGGACTACGGAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_8_155_9 163 test_chromosome 58 255 75M = 131 0 TGTGACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_8_197_1 99 test_chromosome 58 255 75M = 173 0 TCTGACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGACACTACGGGGATGGCGACTAGGACTACGGACGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_9_179_52 163 test_chromosome 59 255 75M = 155 0 CTGACTAGACTGGAGGCGCTCGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_11_190_1a 99 test_chromosome 61 255 75M = 166 0 GACTAGACTGGAGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_16_194_10 163 test_chromosome 66 255 75M = 170 0 GACTGGATGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTCGGACTACGGACGGACTTAAAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_21_208_24 163 test_chromosome 71 255 75M = 184 0 GAGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_22_173_62 99 test_chromosome 72 255 75M = 149 0 AGGCGCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_23_186_42 163 test_chromosome 73 255 75M = 162 0 GGCGCTTGTGACTGAGCTAGGACGTGCCACTACGGGGATGAAGACTAGGACTACGGACGGACTTAGAGCGTCAGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_26_189_30 163 test_chromosome 76 255 75M = 165 0 GCTTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_28_188_11 99 test_chromosome 78 255 75M = 164 0 TTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGAACGGACTTAGAGCGTCAGATGCAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_28_206_1f 73 test_chromosome 78 255 75M * 0 0 TTGCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGACGCAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_30_231_3c 161 test_chromosome 80 255 75M = 207 0 GCGACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_33_223_4e 73 test_chromosome 83 255 75M * 0 0 ACTGAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_36_146_27 163 test_chromosome 86 255 75M = 122 0 GCGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACAGACGGACTTAGAGCGTCAGATGCAGCGACTGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_36_218_12 99 test_chromosome 86 255 75M = 194 0 GAGCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGCCTTAGAGCGTCAGATGCAGCGACTGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_38_199_29 99 test_chromosome 88 255 75M = 175 0 GCTAGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_39_219_5c 99 test_chromosome 89 255 75M = 195 0 CTAGGACGTCCCACTATGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGGCTGGACTA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_41_236_55 97 test_chromosome 91 255 75M = 212 0 AGGACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGAATATT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_42_209_25 99 test_chromosome 92 255 75M = 185 0 GGACGTGCCACTACGTGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_44_193_3f 99 test_chromosome 94 255 75M = 169 0 ACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGTCTATTTAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_44_197_35 99 test_chromosome 94 255 75M = 173 0 ACGTGCAACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_44_225_1e 163 test_chromosome 94 255 75M = 201 0 ACGTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCGGGTGCAGCGACTGGACTATTTAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_46_195_17 137 test_chromosome 96 255 75M * 0 0 GTGCCACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_46_232_2f 99 test_chromosome 96 255 75M = 208 0 GTGCCACTACGGGGATGACGACTAGGACTACGGCCGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_48_207_39 73 test_chromosome 98 255 75M * 0 0 GCCCCTACGGGGATGACGACTAGGACTACGGACGGATTTAGACCGTCAGATGCAGCGACTGGACTATTTAGGACG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_48_249_20 161 test_chromosome 98 255 75M = 225 0 GCCACTACGGGGATGACGACTAGGACGACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_50_224_2d 163 test_chromosome 100 255 75M = 200 0 CACTACGAGGATGACGTCTAGGACTACGGACGGACTTAGAGCGTCAGACGCAGCGACTGGACTATTTAGGACGAT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_51_194_47 163 test_chromosome 101 255 75M = 170 0 ACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_51_194_49 99 test_chromosome 101 255 75M = 170 0 ACTACGGGGATGACGACTAGGCCTACGGATGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_51_237_a 99 test_chromosome 101 255 75M = 213 0 ACTACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_51_248_14 97 test_chromosome 101 255 75M = 224 0 ACTACGGGGATGACGACGAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGAACTTTTTAGGACGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_52_261_1b 97 test_chromosome 102 255 75M = 237 0 CTACGGGAATGACGACTAGGGCTACGGAGGGACTTACAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4
+test_mRNA_53_212_19 99 test_chromosome 103 255 75M = 188 0 TACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGAATATTTAGGACGATCGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_53_272_5a 161 test_chromosome 103 255 75M = 248 0 TACGGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_56_183_56 99 test_chromosome 106 255 75M = 159 0 GGGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTGGGACGATCGGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_57_231_8 99 test_chromosome 107 255 75M = 207 0 GGGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCACCGACTGGACTATTTAGGACGATCGGACTG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_58_218_16 163 test_chromosome 108 255 75M = 194 0 GGATGACGACTAGGACTACGGACGGACTTAGAACGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_58_220_3d 163 test_chromosome 108 255 75M = 196 0 GGATGACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_58_234_7 163 test_chromosome 108 255 75M = 210 0 GGATGACGCCTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_63_229_4c 163 test_chromosome 113 255 75M = 205 0 ACGACTAGGACTACGGACGGACTTAGAGCGTCAGATGCAGGGACTGGACTATTTAGGACGATCGGACTGAGGAGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_65_238_2e 99 test_chromosome 115 255 75M = 214 0 GACTAGGACTACGGACGGACTTAGAGCGTCAGAAGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_69_229_23 163 test_chromosome 119 255 75M = 205 0 AGGACTACGGACGGACTTATAGGGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_36_146_27 83 test_chromosome 122 255 75M = 86 0 ACTACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGTGCAGTAGGT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_72_258_4 163 test_chromosome 122 255 75M = 234 0 ACTACGGACGGACTTAGAGCGTCAGATGCAGCAACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_73_240_34 99 test_chromosome 123 255 75M = 216 0 CTACGGACGGACTTAGAGCGTCAGATGCAGCGAATGGACTATTTAGGACGCTCGGACTGAGGAGGGCAGTAGGAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_73_259_5e 99 test_chromosome 123 255 75M = 235 0 CTACGGACGGACTTAGAGCGTCAGATGCTGCGACTGGACTATTTGGGACGATCGGACTGAGGAGGGCAGTAGGAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_75_204_54 73 test_chromosome 125 255 75M * 0 0 ACGGACGGACTTCGAGCCTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_75_235_21 73 test_chromosome 125 255 75M * 0 0 ACGGACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGCACGATCGGACTGAGGAGGGCAGTAGAACGT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_75_277_3b 97 test_chromosome 125 255 75M = 353 0 ACGGACGGACTTAAAGCTTCAGATGCAGCGACAGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_77_256_2c 73 test_chromosome 127 255 75M * 0 0 GGACGGACTTAGAGCATCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_78_276_4b 97 test_chromosome 128 255 75M = 352 0 GACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGGCGCTAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_79_256_31 137 test_chromosome 129 255 75M * 0 0 ACGGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_81_228_3a 163 test_chromosome 131 255 75M = 204 0 GGACTGAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGTAGTAGGACGCTACGTA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_81_245_4d 163 test_chromosome 131 255 75M = 221 0 GGACTTAGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGATGAGGGCAGTAGGACGCTACGTA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_8_155_9 83 test_chromosome 131 255 75M = 58 0 GGACTTCGAGCGTCAGATGCAGCGACTGTACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_82_255_2 137 test_chromosome 132 255 75M * 0 0 GACTTAGAGCGTCAGATGCAGCGACTGGACTTTTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTAT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_82_271_58 99 test_chromosome 132 255 75M = 247 0 GACTTAGAGCGTCAGTTGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTAT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_85_268_53 99 test_chromosome 135 255 75M = 244 0 TTAGTGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_87_250_57 163 test_chromosome 137 255 75M = 226 0 AGAGCGTCAGATGCAGAGACTGGACTATTTAGGACGATCGGACTGAGGAGTGCAGTAGGACGCTACGTATTTGGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_87_279_5f 161 test_chromosome 137 255 75M = 355 0 AGAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACCGAGGAGGGCAGTAGGACGCTACGTATTTGGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_88_257_50 137 test_chromosome 138 255 75M * 0 0 GAGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_89_230_b 163 test_chromosome 139 255 75M = 206 0 AGCGTCAGGTGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_89_245_15 99 test_chromosome 139 255 75M = 221 0 AGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_89_267_32 163 test_chromosome 139 255 75M = 243 0 AGCGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGAGTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_91_256_41 73 test_chromosome 141 255 75M * 0 0 CGTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_92_250_44 99 test_chromosome 142 255 75M = 226 0 GTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0
+test_mRNA_92_266_43 99 test_chromosome 142 255 75M = 242 0 GTCAGATGCAGCGACTGGACTATTTAGGACGATCGGACTCAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_96_238_3 163 test_chromosome 146 255 75M = 214 0 GATGCAGCGACTGGACTATTTAGGACGATCGGACGGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGACC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_97_275_26 97 test_chromosome 147 255 75M = 351 0 ATGCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_22_173_62 147 test_chromosome 149 255 75M = 72 0 GCAGCGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_103_284_2a 161 test_chromosome 153 255 75M = 360 0 CGACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_104_278_3e 161 test_chromosome 154 255 75M = 354 0 GACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTTTTTGGCGCGCGGCCCTACGGCTG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_105_266_13 163 test_chromosome 155 255 75M = 242 0 ACTGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_105_276_c 161 test_chromosome 155 255 75M = 352 0 ACTGGACTATTTAGGACGATCGGACTGAGGAAGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_9_179_52 83 test_chromosome 155 255 75M = 59 0 ACTGGACCATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_106_253_45 137 test_chromosome 156 255 75M * 0 0 CTGGACTATTTAGGTCGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_107_286_5 161 test_chromosome 157 255 75M = 362 0 TGGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGCATTTGGCGCGCGGCCCTACGGCTGAGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_6_182_59 147 test_chromosome 158 255 75M = 56 0 GGACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_56_183_56 147 test_chromosome 159 255 75M = 106 0 GACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_110_267_22 163 test_chromosome 160 255 75M = 243 0 ACTAGTTAGGGCGATCGGACTGAGGAGGGCAGTAGGACGCTACGTAGTTGGCGCGCGGCCCTACGACTGAGCGTC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:5
+test_mRNA_110_271_28 99 test_chromosome 160 255 75M = 247 0 ACTATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_111_297_61 161 test_chromosome 161 255 75M = 373 0 CTATTTAGGACGATCGGACTGGGGAGGGCAGTAGGACGCTACGGATTTGGCGCGCGGCCCTACGGCTGAGCGTCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_23_186_42 83 test_chromosome 162 255 75M = 73 0 TATTTAGGACGATCGGACGGAGGAGGGCAGAAGGACGCTACGTATTTGGCGCGCGGCCCTACGACTGAGCGTCGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4
+test_mRNA_3_187_51 147 test_chromosome 163 255 75M = 53 0 ATTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_114_277_5b 161 test_chromosome 164 255 75M = 353 0 TTTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGCCTGAGCGTCGAGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_28_188_11 147 test_chromosome 164 255 75M = 78 0 TTTAGGACGATCGGACTGAGGAAGGCAGTAGGACGCTTCGTATTTGGCGCGAGGCCCTACGGCTGAGCGTCGAGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4
+test_mRNA_26_189_30 83 test_chromosome 165 255 75M = 76 0 TTAGGACGATCGGACTGAGGAGGGCAGTAGGACGGTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_33_189_4a 73 test_chromosome 165 255 75M * 0 0 TTAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACCTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGGGCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_116_271_2b 163 test_chromosome 166 255 75M = 247 0 TAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_116_295_63 161 test_chromosome 166 255 75M = 371 0 TAGGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_11_190_1a 147 test_chromosome 166 255 75M = 61 0 TAGGTCGATGGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGTGGCCCTACGGCTGAGCGTCGAGCTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4
+test_mRNA_4_191_5d 83 test_chromosome 167 255 75M = 54 0 AGGACGATCGGACTGAGTAGGGCAGTAGGACACTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_118_297_f 161 test_chromosome 168 255 75M = 373 0 GGACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_44_193_3f 147 test_chromosome 169 255 75M = 94 0 GACGATCGGACTGGGGAGAGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_16_194_10 83 test_chromosome 170 255 75M = 66 0 ACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_51_194_47 83 test_chromosome 170 255 75M = 101 0 ACGATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_51_194_49 147 test_chromosome 170 255 75M = 101 0 ACGTTCGGACTGAGGAGGGCAGTAGGACGCCACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4
+test_mRNA_122_299_6 161 test_chromosome 172 255 75M = 375 0 GATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_44_197_35 147 test_chromosome 173 255 75M = 94 0 ATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGATCGTCGAGCTTGCGATAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2
+test_mRNA_5_197_46 145 test_chromosome 173 255 75M = 55 0 ATCGGACGGAGGAGGGCAGTAGGACGCTACGTATTTGGCGGGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_8_197_1 147 test_chromosome 173 255 75M = 58 0 ATCGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_125_280_48 97 test_chromosome 175 255 75M = 356 0 CGGACTGAGGAGGGCAGTAGGACGCTATGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGAAACGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3
+test_mRNA_125_293_60 161 test_chromosome 175 255 75M = 369 0 CGGACTGAGGAGGGCAGTAGGACGCTATGTATTTGGCGCGCGGCCCTACGGCTGAGCTTCGAGGTTGCGATACGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4
+test_mRNA_38_199_29 147 test_chromosome 175 255 75M = 88 0 CGGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_126_282_18 161 test_chromosome 176 255 75M = 358 0 GGACTGAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1
+test_mRNA_131_260_33 99 test_chromosome 181 255 70M100N5M = 236 0 GAGGAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTAT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_21_208_24 83 test_chromosome 184 255 67M100N8M = 71 0 GAGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGCCTGAGCGTCGAGCTTGCGATACGCCACTATTAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_42_209_25 147 test_chromosome 185 255 66M100N9M = 92 0 AGGGCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_53_212_19 147 test_chromosome 188 255 63M100N12M = 103 0 GCAGTAGGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTTCTTTA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:1
+test_mRNA_36_218_12 147 test_chromosome 194 255 57M100N18M = 86 0 GGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_58_218_16 83 test_chromosome 194 255 57M100N18M = 108 0 GGACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_145_300_37 163 test_chromosome 195 255 56M100N19M = 376 0 GACGCTACGTATTTGGCGCGGGGCCCTATGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTAGTATATT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:5 XS:A:+ NS:i:2
+test_mRNA_39_219_5c 147 test_chromosome 195 255 56M100N19M = 89 0 GACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCCAGCTTGCGATACGCCACTATTACTTTATTATCTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_58_220_3d 83 test_chromosome 196 255 55M100N20M = 108 0 ACGCTACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGGTTGCGATACGCCACTATTACTTTATTATCTTC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3 XS:A:+ NS:i:1
+test_mRNA_50_224_2d 83 test_chromosome 200 255 51M100N24M = 100 0 TACGTATTTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_44_225_1e 83 test_chromosome 201 255 50M100N25M = 94 0 ACGTATATGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_81_228_3a 83 test_chromosome 204 255 47M100N28M = 131 0 TATTTGGCGCGCGGCCCTATGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGTAGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4 XS:A:+ NS:i:0
+test_mRNA_63_229_4c 83 test_chromosome 205 255 46M100N29M = 113 0 ATTTGGCGCGCGGCCCTACGGCTGAGTGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:1
+test_mRNA_69_229_23 83 test_chromosome 205 255 46M100N29M = 119 0 CTTTGGCGCGCGGCCCTACGGCTGAGCGTCTAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3 XS:A:+ NS:i:1
+test_mRNA_89_230_b 83 test_chromosome 206 255 45M100N30M = 139 0 TCTGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTAACTCACTCGGACGTA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4 XS:A:+ NS:i:0
+test_mRNA_30_231_3c 81 test_chromosome 207 255 44M100N31M = 80 0 TTGGCGCGCGGCCCTACGGCTAAGCGTCGAGCTTGCGATACGCCACTATTACTTTAATATCTTACTCGCACGTAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4 XS:A:+ NS:i:0
+test_mRNA_57_231_8 147 test_chromosome 207 255 44M100N31M = 107 0 TTGGCGCGCGGCCCTAGGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_46_232_2f 147 test_chromosome 208 255 43M100N32M = 96 0 TGGCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_58_234_7 83 test_chromosome 210 255 41M100N34M = 108 0 GCGCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTAGTTTATTATCTGACTCGGACGTAGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4 XS:A:+ NS:i:1
+test_mRNA_41_236_55 145 test_chromosome 212 255 39M100N36M = 91 0 GCGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_51_237_a 147 test_chromosome 213 255 38M100N37M = 101 0 CGCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGAT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_65_238_2e 147 test_chromosome 214 255 37M100N38M = 115 0 GCGGCCCTACGGCTGCGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_96_238_3 83 test_chromosome 214 255 37M100N38M = 146 0 GCGGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCTACTAGTACTTTATTATCTTACGCGGACGTAGACGGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4 XS:A:+ NS:i:2
+test_mRNA_73_240_34 147 test_chromosome 216 255 35M100N40M = 123 0 GGCCCTACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTTCTCGGACGTAGACGGATCGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_81_245_4d 83 test_chromosome 221 255 30M100N45M = 131 0 TACGGCTGAGCGTCGAGGTTGCGATACGCCACTATTACTTTATAATCTTACTCGGACGTAGACGGATCGGCAACG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:1
+test_mRNA_89_245_15 147 test_chromosome 221 255 30M100N45M = 139 0 TACGGCTGAGCGTCGAGCTTGCGATACGCCACTATTTCTCTATTATCTTACTCGGACGTAGACGGATCGGCAACG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:2
+test_mRNA_172_294_4f 99 test_chromosome 222 255 29M100N46M = 370 0 ACGGATGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTCCTCGGACGTAGACGGATCGCCAACGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3 XS:A:+ NS:i:1
+test_mRNA_51_248_14 145 test_chromosome 224 255 27M100N48M = 101 0 GGCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGAACGGCAACGGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3 XS:A:+ NS:i:0
+test_mRNA_48_249_20 81 test_chromosome 225 255 26M100N49M = 98 0 GCTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTACTATCTTACTCGGACGGAGACGGATCGGCAACGGGAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3 XS:A:+ NS:i:0
+test_mRNA_87_250_57 83 test_chromosome 226 255 25M100N50M = 137 0 ATGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_92_250_44 147 test_chromosome 226 255 25M100N50M = 142 0 CTGAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGATCGGGTACGGGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_128_252_36 137 test_chromosome 228 255 23M100N52M * 0 0 GAGCGTCGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGATCGGGAACGGGACTTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4 XS:A:+ NS:i:0
+test_mRNA_72_258_4 83 test_chromosome 234 255 17M100N50M100N8M = 122 0 CGAGCTTGCGATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGATGGGCAACGGGACTTTTTCTAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:1
+test_mRNA_73_259_5e 147 test_chromosome 235 255 16M100N50M100N9M = 123 0 GAGCTTGCGATACGCCACTATTACTGTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_131_260_33 147 test_chromosome 236 255 15M100N50M100N10M = 181 0 AGCTTGTGATACGCCACTATTACTTTATTATCTTACTCGGACGTAAACGGATCGGCCACGGGACTTTTTTTACTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4 XS:A:+ NS:i:3
+test_mRNA_52_261_1b 145 test_chromosome 237 255 14M100N50M100N11M = 102 0 GCTTGCGATACGCCACTATTACTTAATTATCTTACTCGGACGTAGAAGGATCGGCAACGGGACTTTTTCTACTTG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:1
+test_mRNA_105_266_13 83 test_chromosome 242 255 9M100N50M100N16M = 155 0 CGATCCGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:1
+test_mRNA_92_266_43 147 test_chromosome 242 255 9M100N50M100N16M = 142 0 CGATACGCCACTATTACTTTCTTATCTTACTCGGACGTAGACGGAGCGGCAACGGGACTTTTTCTACTTGAGACC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3 XS:A:+ NS:i:2
+test_mRNA_110_267_22 83 test_chromosome 243 255 8M100N50M100N17M = 160 0 GATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 XS:A:+ NS:i:0
+test_mRNA_89_267_32 83 test_chromosome 243 255 8M100N50M100N17M = 139 0 GATACGGCACTATTACTTTATTATCTTTCTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:1
+test_mRNA_111_268_d 73 test_chromosome 244 255 7M100N50M100N18M * 0 0 ATACGCCACTATTATTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:1
+test_mRNA_85_268_53 147 test_chromosome 244 255 7M100N50M100N18M = 135 0 ATACGCCACTATTACTTTATTATCTTACTCGGACGTAGACGGATCGTCAACGGGACTTTTTCTACTTGAGACTGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_110_271_28 147 test_chromosome 247 255 4M100N50M100N21M = 160 0 CGCCACTATTACTTTATTATCTTACTCGGACGAAGACGGATCGGCAACGGGGCTTTTTCTACTTGAGACTGGGAT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:1
+test_mRNA_116_271_2b 83 test_chromosome 247 255 4M100N50M100N21M = 166 0 CGCCACTATTACTTTATTATCTTACTCGGACGTAGACAGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGAT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_82_271_58 147 test_chromosome 247 255 4M100N50M100N21M = 132 0 CGCCACTATTACTTTATTATCTTACTCGGACGTAGACGCATCGGCAACGGGACTTTTTCTACTTGAGACTGGGAT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_53_272_5a 81 test_chromosome 248 255 3M100N50M100N22M = 103 0 GCCACTATTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGACACTGGGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:1
+test_mRNA_104_274_1c 73 test_chromosome 350 255 51M100N24M * 0 0 CACTATTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_85_275_38 137 test_chromosome 351 255 50M100N25M * 0 0 ACTCTTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTACTACTTGAGACTGGGATCGAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_97_275_26 145 test_chromosome 351 255 50M100N25M = 147 0 ACTATTACTTTATTATCTTAGTCGGACGTAGACGGATCGGAAACGGGACTCTTTCTACTTGAGACTGGGATCGAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3 XS:A:+ NS:i:0
+test_mRNA_105_276_c 81 test_chromosome 352 255 49M100N26M = 155 0 CTATTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGGCTTTTTCTACTTGAGACTGGGATCGAGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_78_276_4b 145 test_chromosome 352 255 49M100N26M = 128 0 CTATTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTAGGATCGAGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_114_277_5b 81 test_chromosome 353 255 48M100N27M = 164 0 TATTACTTTATTATCTTACTCGGAGGTAGACGGAACGGCAACGGGACTTTTTCTGCTTGAGACTGGGATCGAGGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:4 XS:A:+ NS:i:0
+test_mRNA_75_277_3b 145 test_chromosome 353 255 48M100N27M = 125 0 TATTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACCTGAGACTGGGATCGAGGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_104_278_3e 81 test_chromosome 354 255 47M100N28M = 154 0 ATTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGAATCGAGGCG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_87_279_5f 81 test_chromosome 355 255 46M100N29M = 137 0 TTACTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 XS:A:+ NS:i:0
+test_mRNA_125_280_48 145 test_chromosome 356 255 45M100N30M = 175 0 TACTTTATTATCTTACTCTGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGAGCGAGGCGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_126_282_18 81 test_chromosome 358 255 43M100N32M = 176 0 CTTTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 XS:A:+ NS:i:0
+test_mRNA_103_284_2a 81 test_chromosome 360 255 41M100N34M = 153 0 TTATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACTTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 XS:A:+ NS:i:0
+test_mRNA_107_286_5 81 test_chromosome 362 255 39M100N36M = 157 0 ATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACTTTTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 XS:A:+ NS:i:0
+test_mRNA_151_286_e 137 test_chromosome 362 255 39M100N36M * 0 0 ATTATCTTACTCGGACGTAGACGGATCGGCAACGGGACTTTATCTACTTGAGACTGGGATCGAGGCGGACTTTTT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:1
+test_mRNA_150_290_0 73 test_chromosome 366 255 35M100N40M * 0 0 TCTTACTCGGACGTAGACGGATCGCCAACGGGACTTTTTCTACTTGAGACTGAGACCGAGGCGGACTTTTTAGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3 XS:A:+ NS:i:0
+test_mRNA_94_291_40 137 test_chromosome 367 255 34M100N41M * 0 0 CTTCCTGGGACGTAGACGGATCGGCAACGCGACATTTTCTACTTGAGACTGGGATCGAGGCGGACTTTTTGGGAC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:5 XS:A:+ NS:i:2
+test_mRNA_125_293_60 81 test_chromosome 369 255 32M100N43M = 175 0 TACTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACTTTTTAGGACGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 XS:A:+ NS:i:0
+test_mRNA_172_294_4f 147 test_chromosome 370 255 31M100N44M = 222 0 ACTCGGACGTAGACGGGTCGGCAGCGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACGTTTTAGGACGGG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:3 XS:A:+ NS:i:0
+test_mRNA_116_295_63 81 test_chromosome 371 255 30M100N45M = 166 0 CTCGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACTTTTTAGGACGGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 XS:A:+ NS:i:0
+test_mRNA_111_297_61 81 test_chromosome 373 255 28M100N47M = 161 0 CGGACGTAGACGGATCCGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACTTTTTAGGACGGGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_118_297_f 81 test_chromosome 373 255 28M100N47M = 168 0 CGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACTTTTTAGGACGGGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:0 XS:A:+ NS:i:0
+test_mRNA_151_297_1d 137 test_chromosome 373 255 28M100N47M * 0 0 CGGACGTAGACGGATCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACATTTTAGGACGGGACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
+test_mRNA_122_299_6 81 test_chromosome 375 255 26M100N49M = 172 0 GACGTAGACGGAGCGGCAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACTTTTTAGGACGGGACTTG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:2 XS:A:+ NS:i:0
+test_mRNA_145_300_37 83 test_chromosome 376 255 25M100N50M = 195 0 ACGTAGACGGATCGGAAACGGGACTTTTTCTACTTGAGACTGGGATCGAGGCGGACTTTTTAGGACGGGACTTGC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII NM:i:1 XS:A:+ NS:i:0
diff -r c30c7c98ce61 -r ac96e6e33164 test-data/tophat_out2.wig
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/tophat_out2.wig Wed Mar 31 17:46:25 2010 -0400
@@ -0,0 +1,175 @@
+track type=bedGraph name="TopHat - read coverage"
+test_chromosome 0 52 0
+test_chromosome 52 53 1
+test_chromosome 53 54 2
+test_chromosome 54 55 3
+test_chromosome 55 57 4
+test_chromosome 57 58 6
+test_chromosome 58 60 7
+test_chromosome 60 65 8
+test_chromosome 65 70 9
+test_chromosome 70 71 10
+test_chromosome 71 72 11
+test_chromosome 72 75 12
+test_chromosome 75 77 13
+test_chromosome 77 79 15
+test_chromosome 79 82 16
+test_chromosome 82 85 17
+test_chromosome 85 87 19
+test_chromosome 87 88 20
+test_chromosome 88 90 21
+test_chromosome 90 91 22
+test_chromosome 91 93 23
+test_chromosome 93 95 26
+test_chromosome 95 97 28
+test_chromosome 97 99 30
+test_chromosome 99 100 31
+test_chromosome 100 101 35
+test_chromosome 101 102 36
+test_chromosome 102 105 38
+test_chromosome 105 106 39
+test_chromosome 106 107 40
+test_chromosome 107 112 43
+test_chromosome 112 114 44
+test_chromosome 114 118 45
+test_chromosome 118 121 46
+test_chromosome 121 122 48
+test_chromosome 122 124 50
+test_chromosome 124 126 53
+test_chromosome 126 129 54
+test_chromosome 129 130 53
+test_chromosome 130 131 55
+test_chromosome 131 132 57
+test_chromosome 132 133 55
+test_chromosome 133 134 54
+test_chromosome 134 135 55
+test_chromosome 135 136 54
+test_chromosome 136 137 56
+test_chromosome 137 138 57
+test_chromosome 138 141 60
+test_chromosome 141 147 62
+test_chromosome 147 148 61
+test_chromosome 148 150 62
+test_chromosome 150 152 61
+test_chromosome 152 153 60
+test_chromosome 153 154 61
+test_chromosome 154 155 63
+test_chromosome 155 156 64
+test_chromosome 156 158 65
+test_chromosome 158 159 66
+test_chromosome 159 160 68
+test_chromosome 160 161 67
+test_chromosome 161 163 68
+test_chromosome 163 164 69
+test_chromosome 164 165 71
+test_chromosome 165 167 73
+test_chromosome 167 168 74
+test_chromosome 168 169 72
+test_chromosome 169 170 75
+test_chromosome 170 171 73
+test_chromosome 171 172 74
+test_chromosome 172 174 75
+test_chromosome 174 175 77
+test_chromosome 175 176 74
+test_chromosome 176 177 73
+test_chromosome 177 181 71
+test_chromosome 181 182 70
+test_chromosome 182 183 67
+test_chromosome 183 184 68
+test_chromosome 184 189 69
+test_chromosome 189 193 68
+test_chromosome 193 194 69
+test_chromosome 194 195 71
+test_chromosome 195 196 72
+test_chromosome 196 197 70
+test_chromosome 197 199 68
+test_chromosome 199 200 66
+test_chromosome 200 201 67
+test_chromosome 201 202 66
+test_chromosome 202 204 65
+test_chromosome 204 205 67
+test_chromosome 205 207 65
+test_chromosome 207 211 66
+test_chromosome 211 213 65
+test_chromosome 213 216 64
+test_chromosome 216 220 62
+test_chromosome 220 224 63
+test_chromosome 224 225 64
+test_chromosome 225 228 66
+test_chromosome 228 229 65
+test_chromosome 229 230 62
+test_chromosome 230 231 61
+test_chromosome 231 232 60
+test_chromosome 232 234 59
+test_chromosome 234 237 58
+test_chromosome 237 238 57
+test_chromosome 238 239 55
+test_chromosome 239 240 53
+test_chromosome 240 241 50
+test_chromosome 241 242 51
+test_chromosome 242 243 52
+test_chromosome 243 244 53
+test_chromosome 244 246 50
+test_chromosome 246 247 52
+test_chromosome 247 249 50
+test_chromosome 249 250 47
+test_chromosome 250 349 0
+test_chromosome 349 350 1
+test_chromosome 350 351 49
+test_chromosome 351 352 51
+test_chromosome 352 353 53
+test_chromosome 353 354 54
+test_chromosome 354 357 55
+test_chromosome 357 358 56
+test_chromosome 358 361 55
+test_chromosome 361 362 57
+test_chromosome 362 365 56
+test_chromosome 365 366 57
+test_chromosome 366 368 58
+test_chromosome 368 369 57
+test_chromosome 369 372 56
+test_chromosome 372 375 59
+test_chromosome 375 378 60
+test_chromosome 378 379 59
+test_chromosome 379 380 57
+test_chromosome 380 381 56
+test_chromosome 381 382 54
+test_chromosome 382 384 53
+test_chromosome 384 386 52
+test_chromosome 386 387 51
+test_chromosome 387 388 50
+test_chromosome 388 390 48
+test_chromosome 390 395 47
+test_chromosome 395 396 45
+test_chromosome 396 398 44
+test_chromosome 398 399 43
+test_chromosome 399 400 42
+test_chromosome 400 402 1
+test_chromosome 402 500 0
+test_chromosome 500 508 39
+test_chromosome 508 509 38
+test_chromosome 509 510 37
+test_chromosome 510 511 36
+test_chromosome 511 516 35
+test_chromosome 516 517 33
+test_chromosome 517 518 31
+test_chromosome 518 521 29
+test_chromosome 521 522 26
+test_chromosome 522 524 25
+test_chromosome 524 525 24
+test_chromosome 525 526 22
+test_chromosome 526 527 20
+test_chromosome 527 528 18
+test_chromosome 528 529 17
+test_chromosome 529 530 16
+test_chromosome 530 532 15
+test_chromosome 532 534 14
+test_chromosome 534 536 13
+test_chromosome 536 540 11
+test_chromosome 540 541 10
+test_chromosome 541 543 9
+test_chromosome 543 544 8
+test_chromosome 544 545 7
+test_chromosome 545 547 6
+test_chromosome 547 549 3
+test_chromosome 549 549 2
diff -r c30c7c98ce61 -r ac96e6e33164 test-data/tophat_out3.bed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/tophat_out3.bed Wed Mar 31 17:46:25 2010 -0400
@@ -0,0 +1,3 @@
+track name=junctions description="TopHat junctions"
+test_chromosome 180 402 JUNC00000001 46 + 180 402 255,0,0 2 70,52 0,170
+test_chromosome 349 550 JUNC00000002 38 + 349 550 255,0,0 2 51,50 0,151
diff -r c30c7c98ce61 -r ac96e6e33164 tool-data/tophat_indices.loc.sample
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool-data/tophat_indices.loc.sample Wed Mar 31 17:46:25 2010 -0400
@@ -0,0 +1,29 @@
+#This is a sample file distributed with Galaxy that enables tools
+#to use a directory of Tophat and Bowtie indexed sequences data files. You will need
+#to create these data files and then create a tophat_indices.loc file
+#similar to this one (store it in this directory) that points to
+#the directories in which those files are stored. The tophat_indices.loc
+#file has this format (white space characters are TAB characters):
+#
+#<build> <file_base>
+#
+#So, for example, if you had hg18 indexed stored in
+#/depot/data2/galaxy/tophat/hg18/,
+#then the tophat_indices.loc entry would look like this:
+#
+#hg18 /depot/data2/galaxy/tophat/hg18/hg18
+#
+#and your /depot/data2/galaxy/tophat/hg18/ directory
+#would contain hg18.*.ebwt files:
+#
+#-rw-r--r-- 1 james universe 830134 2005-09-13 10:12 hg18.1.ebwt
+#-rw-r--r-- 1 james universe 527388 2005-09-13 10:12 hg18.2.ebwt
+#-rw-r--r-- 1 james universe 269808 2005-09-13 10:12 gh18.3.ebwt
+#...etc...
+#
+#Your tophat_indices.loc file should include an entry per line for
+#each index set you have stored. The "file" in the path does not actually
+#exist, but it is the prefix for the actual index files. For example:
+#
+#hg18 /depot/data2/galaxy/bowtie/hg18/hg18
+#hg19 /depot/data2/galaxy/bowtie/hg19/hg19
diff -r c30c7c98ce61 -r ac96e6e33164 tool_conf.xml.sample
--- a/tool_conf.xml.sample Wed Mar 31 16:25:21 2010 -0400
+++ b/tool_conf.xml.sample Wed Mar 31 17:46:25 2010 -0400
@@ -221,7 +221,10 @@
<tool file="metag_tools/megablast_wrapper.xml" />
<tool file="metag_tools/megablast_xml_parser.xml" />
<tool file="sr_mapping/PerM.xml" />
- </section>
+ </section>
+ <section name="NGS: Expression Analysis" id="rnatools">
+ <tool file="tophat/tophat_wrapper.xml" />
+ </section>
<section name="NGS: SAM Tools" id="samtools">
<tool file="samtools/sam_bitwise_flag_filter.xml" />
<tool file="samtools/sam2interval.xml" />
diff -r c30c7c98ce61 -r ac96e6e33164 tools/tophat/tophat_wrapper.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/tophat/tophat_wrapper.py Wed Mar 31 17:46:25 2010 -0400
@@ -0,0 +1,80 @@
+#! /usr/bin/python
+
+import optparse, os, shutil, sys, tempfile
+
+def stop_err( msg ):
+ sys.stderr.write( "%s\n" % msg )
+ sys.exit()
+
+def __main__():
+ #Parse Command Line
+ parser = optparse.OptionParser()
+ parser.add_option( '-1', '--input1', dest='input1', help='The (forward or single-end) reads file in Sanger FASTQ format' )
+ parser.add_option( '-2', '--input2', dest='input2', help='The reverse reads file in Sanger FASTQ format' )
+ parser.add_option( '-a', '--min-anchor-length', dest='min_anchor_length',
+ help='The "anchor length". TopHat will report junctions spanned by reads with at least this many bases on each side of the junction.' )
+ parser.add_option( '-i', '--min-intron-length', dest='min_intron_length',
+ help='The minimum intron length. TopHat will ignore donor/acceptor pairs closer than this many bases apart.' )
+ parser.add_option( '-I', '--max-intron-length', dest='max_intron_length',
+ help='The maximum intron length. When searching for junctions ab initio, TopHat will ignore donor/acceptor pairs farther than this many bases apart, except when such a pair is supported by a split segment alignment of a long read.' )
+ parser.add_option( '-s', '--solexa-quals', dest='solexa_quals', help='Use the Solexa scale for quality values in FASTQ files.' )
+ parser.add_option( '-S', '--solexa.3-quals', dest='solexa_quals',
+ help='As of the Illumina GA pipeline version 1.3, quality scores are encoded in Phred-scaled base-64. Use this option for FASTQ files from pipeline 1.3 or later.' )
+ parser.add_option( '-p', '--num-threads', dest='num_threads', help='Use this many threads to align reads. The default is 1.' )
+ parser.add_option( '-C', '--coverage-output', dest='coverage_output_file', help='Coverage output file; formate is WIG.' )
+ parser.add_option( '-J', '--junctions-output', dest='junctions_output_file', help='Junctions output file; formate is BED.' )
+ parser.add_option( '-H', '--hits-output', dest='accepted_hits_output_file', help='Accepted hits output file; formate is SAM.' )
+ parser.add_option( '-D', '--indexes-dir', dest='indexes_directory', help='Indexes directory; location of .ebwt and .fa files.' )
+ parser.add_option( '-r', '--mate-inner-dist', dest='mate_inner_dist', help='This is the expected (mean) inner distance between mate pairs. \
+ For, example, for paired end runs with fragments selected at 300bp, \
+ where each end is 50bp, you should set -r to be 200. There is no default, \
+ and this parameter is required for paired end runs.')
+ (options, args) = parser.parse_args()
+
+ # Make temp directory for output.
+ tmp_output_dir = tempfile.mkdtemp()
+
+ # Build command.
+
+ # Base.
+ cmd = "tophat -o %s " % ( tmp_output_dir )
+
+ # Add options.
+ if options.mate_inner_dist:
+ cmd += ( " -r %i" % int ( options.mate_inner_dist ) )
+
+ # Add index prefix.
+ cmd += " " + options.indexes_directory
+
+ # Add input files.
+ cmd += " " + options.input1
+ if options.mate_inner_dist:
+ # Using paired-end reads.
+ cmd += " " + options.input2
+
+ # Route program output to file.
+ cmd += " > %s" % tmp_output_dir + "/std_out.txt"
+ # Route program error output to file.
+ cmd += " 2> %s" % tmp_output_dir + "/std_err.txt"
+
+ # Run.
+ try:
+ os.system( cmd )
+ except Exception, e:
+ stop_err( 'Error in tophat:\n' + str( e ) )
+
+ # TODO: look for errors in program output.
+
+ # Copy output files from tmp directory to specified files.
+ try:
+ shutil.copyfile( tmp_output_dir + "/coverage.wig", options.coverage_output_file )
+ shutil.copyfile( tmp_output_dir + "/junctions.bed", options.junctions_output_file )
+ shutil.copyfile( tmp_output_dir + "/accepted_hits.sam", options.accepted_hits_output_file )
+ except Exception, e:
+ stop_err( 'Error in tophat:\n' + str( e ) )
+
+ # Clean up temp dirs
+ if os.path.exists( tmp_output_dir ):
+ shutil.rmtree( tmp_output_dir )
+
+if __name__=="__main__": __main__()
diff -r c30c7c98ce61 -r ac96e6e33164 tools/tophat/tophat_wrapper.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/tophat/tophat_wrapper.xml Wed Mar 31 17:46:25 2010 -0400
@@ -0,0 +1,129 @@
+<tool id="tophat" name="Tophat" version="1.0.13">
+ <description>Find splice junctions using RNA-seq data</description>
+ <command interpreter="python">
+ tophat_wrapper.py
+ --num-threads="4"
+ --coverage-output=$coverage
+ --junctions-output=$junctions
+ --hits-output=$accepted_hits
+ #if $refGenomeSource.genomeSource == "history":
+ --indexes-dir=$refGenomeSource.ownFile
+ #else:
+ --indexes-dir=$refGenomeSource.index.value
+ #end if
+ #if $singlePaired.sPaired == "single":
+ --input1=$singlePaired.input1
+ --input2="None"
+ #else:
+ -r $singlePaired.mean_inner_distance
+ --input1=$singlePaired.input1
+ --input2=$singlePaired.input2
+ #end if
+ </command>
+ <inputs>
+ <conditional name="refGenomeSource">
+ <param name="genomeSource" type="select" label="Will you select a reference genome from your history or use a built-in index?" help="Built-ins were indexed using default options">
+ <option value="indexed">Use a built-in index</option>
+ <option value="history">Use one from the history</option>
+ </param>
+ <when value="indexed">
+ <param name="index" type="select" label="Select a reference genome" help="If your genome of interest is not listed, contact the Galaxy team">
+ <options from_file="tophat_indices.loc">
+ <column name="value" index="1" />
+ <column name="name" index="0" />
+ </options>
+ </param>
+ </when>
+ <when value="history">
+ <param name="ownFile" type="data" format="fasta" metadata_name="dbkey" label="Select the reference genome" />
+ </when> <!-- history -->
+ </conditional> <!-- refGenomeSource -->
+ <conditional name="singlePaired">
+ <param name="sPaired" type="select" label="Is this library mate-paired?">
+ <option value="single">Single-end</option>
+ <option value="paired">Paired-end</option>
+ </param>
+ <when value="single">
+ <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/>
+ </when>
+ <when value="paired">
+ <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/>
+ <param format="fastqsanger" name="input2" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/>
+ <param format="fastqsanger" name="mean_inner_distance" type="integer" value="20" label="Mean Inner Distance between Mate Pairs"/>
+ </when>
+ </conditional>
+ </inputs>
+
+ <outputs>
+ <data format="sam" name="accepted_hits"/>
+ <data format="wig" name="coverage" />
+ <data format="bed" name="junctions" />
+ </outputs>
+
+ <tests>
+ <test>
+ <param name="genomeSource" value="indexed"/>
+ <param name="index" value="test_ref"/>
+ <param name="sPaired" value="paired"/>
+ <param name="input1" ftype="fastqsanger" value="tophat_in1.fq"/>
+ <param name="input2" ftype="fastqsanger" value="tophat_in2.fq"/>
+ <param name="mean_inner_distance" value="20"/>
+ <!--
+ Can't test this right now because first lines of file are run-specific.
+ <output name="accepted_hits" file="tophat_out1.sam"/>
+ -->
+ <output name="coverage" file="tophat_out2.wig"/>
+ <output name="junctions" file="tophat_out3.bed"/>
+ </test>
+ </tests>
+
+ <help>
+**Tophat Overview**
+
+TopHat_ is a fast splice junction mapper for RNA-Seq reads. It aligns RNA-Seq reads to mammalian-sized genomes using the ultra high-throughput short read aligner Bowtie, and then analyzes the mapping results to identify splice junctions between exons. Please cite: Trapnell, C., Pachter, L. and Salzberg, S.L. TopHat: discovering splice junctions with RNA-Seq. Bioinformatics 25, 1105-1111 (2009).
+
+.. _Tophat: http://tophat.cbcb.umd.edu/
+
+------
+
+**Know what you are doing**
+
+.. class:: warningmark
+
+There is no such thing (yet) as an automated gearshift in splice junction identification. It is all like stick-shift driving in San Francisco. In other words, running this tool with default parameters will probably not give you meaningful results. A way to deal with this is to **understand** the parameters by carefully reading the `documentation`__ and experimenting. Fortunately, Galaxy makes experimenting easy.
+
+.. __: http://tophat.cbcb.umd.edu/manual.html
+
+------
+
+**Input formats**
+
+Tophat accepts files in Sanger FASTQ format. Use the FASTQ Groomer to prepare your files.
+
+------
+
+**Outputs**
+
+Tophat produces three output files::
+
+ coverage.wig -- coverage of reads
+ accepted_hits.sam -- reads that were mapped onto genome
+ junctions.bed -- splice junctions identified by Tophat
+
+-------
+
+**Tophat settings**
+
+All of the options have a default value. You can change any of them. Some of the options in Tophat have been implemented here.
+
+------
+
+**Tophat parameter list**
+
+This is a list of implemented Tophat options::
+
+ -r This is the expected (mean) inner distance between mate pairs. For, example, for paired end runs with fragments
+ selected at 300bp, where each end is 50bp, you should set -r to be 200. There is no default, and this parameter
+ is required for paired end runs.
+ </help>
+</tool>
1
0
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/c30c7c98ce61
changeset: 3588:c30c7c98ce61
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Wed Mar 31 16:25:21 2010 -0400
description:
Eliminate the use of message.mako from certain methods in the user controller, and fix an issue with the handle_user_login method in the framework.
diffstat:
lib/galaxy/web/controllers/user.py | 101 +++++++++++++++++++++++++++++-----
lib/galaxy/web/framework/__init__.py | 63 +++++++++++----------
2 files changed, 118 insertions(+), 46 deletions(-)
diffs (264 lines):
diff -r 273535c97761 -r c30c7c98ce61 lib/galaxy/web/controllers/user.py
--- a/lib/galaxy/web/controllers/user.py Wed Mar 31 13:11:05 2010 -0400
+++ b/lib/galaxy/web/controllers/user.py Wed Mar 31 16:25:21 2010 -0400
@@ -29,9 +29,7 @@
return trans.fill_template( '/user/index.mako', user=trans.get_user(), webapp=webapp )
@web.expose
def login( self, trans, webapp='galaxy', **kwd ):
- use_panels = kwd.get( 'use_panels', 'True' )
- # Convert use_panels to Boolean.
- use_panels = use_panels in [ 'True', 'true', 't', 'T' ]
+ use_panels = util.string_as_bool( kwd.get( 'use_panels', True ) )
msg = kwd.get( 'msg', '' )
messagetype = kwd.get( 'messagetype', 'done' )
if kwd.get( 'login_button', False ):
@@ -43,6 +41,8 @@
refresh_frames = [ 'masthead', 'history', 'tools' ]
else:
refresh_frames = [ 'masthead', 'history' ]
+ else:
+ refresh_frames = []
user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email==email ).first()
if not user:
msg = "No such user"
@@ -63,7 +63,11 @@
( user.email, referer, url_for( '/' ) )
if trans.app.config.require_login:
msg += ' <a href="%s">Click here</a> to continue to the home page.' % web.url_for( '/static/welcome.html' )
- return trans.show_ok_message( msg, refresh_frames=refresh_frames, use_panels=use_panels, active_view="user" )
+ return trans.response.send_redirect( web.url_for( controller='user',
+ action='login',
+ use_panels=use_panels,
+ msg=msg,
+ message_type='done' ) )
if trans.app.config.require_login:
if trans.app.config.allow_user_creation:
return trans.fill_template( '/user/login.mako',
@@ -99,11 +103,12 @@
# Since logging an event requires a session, we'll log prior to ending the session
trans.log_event( "User logged out" )
trans.handle_user_logout()
- msg = "You have been logged out.<br>You can <a href='%s'>go back to the page you were visiting</a> or <a href='%s'>go to the home page</a>." % \
+ msg = "You have been logged out.<br>You can log in again, <a href='%s'>go back to the page you were visiting</a> or <a href='%s'>go to the home page</a>." % \
( trans.request.referer, url_for( '/' ) )
- if trans.app.config.require_login:
- msg += ' <a href="%s">Click here</a> to return to the login page.' % web.url_for( controller='user', action='login' )
- return trans.show_ok_message( msg, refresh_frames=refresh_frames, use_panels=True, active_view="user" )
+ return trans.response.send_redirect( web.url_for( controller='user',
+ action='login',
+ msg=msg,
+ message_type='done' ) )
@web.expose
def create( self, trans, webapp='galaxy', **kwd ):
params = util.Params( kwd )
@@ -126,8 +131,24 @@
refresh_frames = [ 'masthead', 'history', 'tools' ]
else:
refresh_frames = [ 'masthead', 'history' ]
+ else:
+ refresh_frames = []
if not trans.app.config.allow_user_creation and not trans.user_is_admin():
- return trans.show_error_message( 'User registration is disabled. Please contact your Galaxy administrator for an account.' )
+ msg = 'User registration is disabled. Please contact your Galaxy administrator for an account.'
+ return trans.response.send_redirect( web.url_for( controller='user',
+ action='create',
+ webapp=webapp,
+ email=email,
+ password=password,
+ confirm=confirm,
+ username=username,
+ subscribe=subscribe,
+ subscribe_checked=subscribe_checked,
+ admin_view=admin_view,
+ use_panels=use_panels,
+ refresh_frames=refresh_frames,
+ msg=error,
+ messagetype='error' ) )
# Create the user, save all the user info and login to Galaxy
if params.get( 'create_user_button', False ):
# Check email and password validity
@@ -135,7 +156,8 @@
if error:
return trans.response.send_redirect( web.url_for( controller='user',
action='create',
- webapp=webapp,email=email,
+ webapp=webapp,
+ email=email,
password=password,
confirm=confirm,
username=username,
@@ -143,6 +165,7 @@
subscribe_checked=subscribe_checked,
admin_view=admin_view,
use_panels=use_panels,
+ refresh_frames=refresh_frames,
msg=error,
messagetype='error' ) )
# all the values are valid
@@ -162,8 +185,21 @@
mail = os.popen( "%s -t" % trans.app.config.sendmail_path, 'w' )
mail.write( "To: %s\nFrom: %s\nSubject: Join Mailing List\n\nJoin Mailing list." % ( trans.app.config.mailing_join_addr,email ) )
if mail.close():
- return trans.show_warn_message( "Now logged in as " + user.email+". However, subscribing to the mailing list has failed.",
- refresh_frames=refresh_frames )
+ msg = "Now logged in as " + user.email + ". However, subscribing to the mailing list has failed."
+ return trans.response.send_redirect( web.url_for( controller='user',
+ action='create',
+ webapp=webapp,
+ email=email,
+ password=password,
+ confirm=confirm,
+ username=username,
+ subscribe=subscribe,
+ subscribe_checked=subscribe_checked,
+ admin_view=admin_view,
+ use_panels=use_panels,
+ refresh_frames=refresh_frames,
+ msg=error,
+ messagetype='warn' ) )
if not admin_view:
# The handle_user_login() method has a call to the history_set_default_permissions() method
# (needed when logging in with a history), user needs to have default permissions set before logging in
@@ -171,16 +207,42 @@
trans.log_event( "User created a new account" )
trans.log_event( "User logged in" )
# subscribe user to email list
- return trans.show_ok_message( "Now logged in as %s.<br><a href='%s'>Return to the home page.</a>" % \
- ( user.email, url_for( '/' ) ), refresh_frames=refresh_frames, use_panels=True )
+ msg = "Now logged in as %s.<br><a href='%s'>Return to the home page.</a>" % ( user.email, url_for( '/' ) )
+ return trans.response.send_redirect( web.url_for( controller='user',
+ action='create',
+ webapp=webapp,
+ email=email,
+ password=password,
+ confirm=confirm,
+ username=username,
+ subscribe=subscribe,
+ subscribe_checked=subscribe_checked,
+ admin_view=admin_view,
+ use_panels=True,
+ refresh_frames=refresh_frames,
+ msg=msg,
+ messagetype='done' ) )
else:
trans.response.send_redirect( web.url_for( controller='admin',
action='users',
message='Created new user account (%s)' % user.email,
status='done' ) )
else:
- return trans.show_ok_message( "Now logged in as %s.<br><a href='%s'>Return to the home page.</a>" % \
- ( user.email, url_for( '/' ) ), use_panels=False )
+ msg = "Now logged in as %s.<br><a href='%s'>Return to the home page.</a>" % ( user.email, url_for( '/' ) )
+ return trans.response.send_redirect( web.url_for( controller='user',
+ action='create',
+ webapp=webapp,
+ email=email,
+ password=password,
+ confirm=confirm,
+ username=username,
+ subscribe=subscribe,
+ subscribe_checked=subscribe_checked,
+ admin_view=admin_view,
+ use_panels=False,
+ refresh_frames=refresh_frames,
+ msg=error,
+ messagetype='done' ) )
if webapp == 'galaxy':
user_info_select, user_info_form, widgets = self.__user_info_ui( trans, **kwd )
else:
@@ -414,6 +476,7 @@
else:
user = trans.user
if not user:
+ # TODO: handle this without the deprecated exception.
raise "In show_info, we don't have a valid user"
email = util.restore_text( params.get( 'email', user.email ) )
# Do not sanitize passwords, so take from kwd
@@ -594,7 +657,11 @@
trans.sa_session.add( reset_user )
trans.sa_session.flush()
trans.log_event( "User reset password: %s" % email )
- return trans.show_ok_message( "Password has been reset and emailed to: %s. <a href='%s'>Click here</a> to return to the login form." % ( email, web.url_for( action='login' ) ) )
+ msg = "Password has been reset and emailed to: %s. <a href='%s'>Click here</a> to return to the login form." % ( email, web.url_for( action='login' ) )
+ return trans.response.send_redirect( web.url_for( controller='user',
+ action='reset_password',
+ msg=msg,
+ messagetype='done' ) )
elif email != None:
msg = "The specified user does not exist"
messagetype = 'error'
diff -r 273535c97761 -r c30c7c98ce61 lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py Wed Mar 31 13:11:05 2010 -0400
+++ b/lib/galaxy/web/framework/__init__.py Wed Mar 31 16:25:21 2010 -0400
@@ -424,37 +424,42 @@
prev_galaxy_session.is_valid = False
# Define a new current_session
self.galaxy_session = self.__create_new_session( prev_galaxy_session, user )
- # Associated the current user's last accessed history (if exists) with their new session
- history = None
- try:
- users_last_session = user.galaxy_sessions[0]
- last_accessed = True
- except:
- users_last_session = None
- last_accessed = False
- if prev_galaxy_session.current_history and prev_galaxy_session.current_history.datasets:
- if prev_galaxy_session.current_history.user is None or prev_galaxy_session.current_history.user == user:
- # If the previous galaxy session had a history, associate it with the new
- # session, but only if it didn't belong to a different user.
- history = prev_galaxy_session.current_history
- elif self.galaxy_session.current_history:
- history = self.galaxy_session.current_history
- if not history and users_last_session and users_last_session.current_history:
- history = users_last_session.current_history
- elif not history:
- history = self.get_history( create=True )
- if history not in self.galaxy_session.histories:
- self.galaxy_session.add_history( history )
- if history.user is None:
- history.user = user
- self.galaxy_session.current_history = history
- if not last_accessed:
- # Only set default history permissions if current history is not from a previous session
- self.app.security_agent.history_set_default_permissions( history, dataset=True, bypass_manage_permission=True )
- self.sa_session.add_all( ( prev_galaxy_session, self.galaxy_session, history ) )
+ if webapp == 'galaxy':
+ cookie_name = 'galaxysession'
+ # Associated the current user's last accessed history (if exists) with their new session
+ history = None
+ try:
+ users_last_session = user.galaxy_sessions[0]
+ last_accessed = True
+ except:
+ users_last_session = None
+ last_accessed = False
+ if prev_galaxy_session.current_history and prev_galaxy_session.current_history.datasets:
+ if prev_galaxy_session.current_history.user is None or prev_galaxy_session.current_history.user == user:
+ # If the previous galaxy session had a history, associate it with the new
+ # session, but only if it didn't belong to a different user.
+ history = prev_galaxy_session.current_history
+ elif self.galaxy_session.current_history:
+ history = self.galaxy_session.current_history
+ if not history and users_last_session and users_last_session.current_history:
+ history = users_last_session.current_history
+ elif not history:
+ history = self.get_history( create=True )
+ if history not in self.galaxy_session.histories:
+ self.galaxy_session.add_history( history )
+ if history.user is None:
+ history.user = user
+ self.galaxy_session.current_history = history
+ if not last_accessed:
+ # Only set default history permissions if current history is not from a previous session
+ self.app.security_agent.history_set_default_permissions( history, dataset=True, bypass_manage_permission=True )
+ self.sa_session.add_all( ( prev_galaxy_session, self.galaxy_session, history ) )
+ else:
+ cookie_name = 'galaxycommunitysession'
+ self.sa_session.add_all( ( prev_galaxy_session, self.galaxy_session ) )
self.sa_session.flush()
# This method is not called from the Galaxy reports, so the cookie will always be galaxysession
- self.__update_session_cookie( name='galaxysession' )
+ self.__update_session_cookie( name=cookie_name )
def handle_user_logout( self ):
"""
Logout the current user:
1
0
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/273535c97761
changeset: 3587:273535c97761
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Wed Mar 31 13:11:05 2010 -0400
description:
Decouple the masthead from base_panels.mako.
diffstat:
templates/admin/index.mako | 2 +-
templates/base_panels.mako | 148 +--------------------------
templates/cloud/index.mako | 2 +-
templates/display_base.mako | 2 +-
templates/form.mako | 2 +-
templates/grid_base.mako | 2 +-
templates/history/list_published.mako | 2 +-
templates/history/view.mako | 2 +-
templates/library/common/browse_library.mako | 2 +-
templates/library/index.mako | 2 +-
templates/message.mako | 2 +-
templates/page/editor.mako | 2 +-
templates/page/index.mako | 2 +-
templates/page/list_published.mako | 2 +-
templates/panels.mako | 2 +-
templates/requests/index.mako | 2 +-
templates/root/index.mako | 2 +-
templates/sample/index.mako | 2 +-
templates/tracks/browser.mako | 2 +-
templates/visualization/list.mako | 2 +-
templates/visualization/list_published.mako | 2 +-
templates/webapps/galaxy/base_panels.mako | 152 +++++++++++++++++++++++++++
templates/workflow/editor.mako | 2 +-
templates/workflow/index.mako | 2 +-
templates/workflow/list.mako | 2 +-
templates/workflow/list_published.mako | 2 +-
26 files changed, 177 insertions(+), 171 deletions(-)
diffs (552 lines):
diff -r 9f32d8c55e30 -r 273535c97761 templates/admin/index.mako
--- a/templates/admin/index.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/admin/index.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/base_panels.mako
--- a/templates/base_panels.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/base_panels.mako Wed Mar 31 13:11:05 2010 -0400
@@ -15,9 +15,6 @@
## Override
</%def>
-## Default title
-<%def name="title()">Galaxy</%def>
-
## Default stylesheets
<%def name="stylesheets()">
${h.css('base','panel_layout')}
@@ -152,150 +149,7 @@
## Masthead
<%def name="masthead()">
-
- ## Tab area, fills entire width
- <div style="position: absolute; top: 0; left: 0; width: 100%; text-align: center">
-
- <table class="tab-group" border="0" cellspacing="0" style="margin: auto;">
- <tr>
-
- <%def name="tab( id, display, href, target='_parent', visible=True, extra_class='' )">
- <%
- cls = "tab"
- if extra_class:
- cls += " " + extra_class
- if self.active_view == id:
- cls += " active"
- style = ""
- if not visible:
- style = "display: none;"
- %>
- <td class="${cls}" style="${style}"><a target="${target}" href="${href}">${display}</a></td>
- </%def>
-
- %if app.config.cloud_controller_instance:
- ${tab( "cloud", "Cloud", h.url_for( controller='/cloud', action='index' ))}
- %else:
- ${tab( "analysis", "Analyze Data", h.url_for( controller='/root', action='index' ))}
-
- ${tab( "workflow", "Workflow", h.url_for( controller='/workflow', action='index' ))}
-
- ${tab( "libraries", "Data Libraries", h.url_for( controller='/library', action='index' ))}
- %endif
-
- %if trans.user and trans.request_types():
- <td class="tab">
- <a>Lab</a>
- <div class="submenu">
- <ul>
- <li><a href="${h.url_for( controller='/requests', action='index' )}">Sequencing Requests</a></li>
- <li><a target="_blank" href="${app.config.get( "lims_doc_url", "http://main.g2.bx.psu.edu/u/rc/p/sts" )}">Help</a></li>
- </ul>
- </div>
- </td>
- %endif
-
- %if app.config.get_bool( 'enable_tracks', False ):
- <%
- cls = "tab"
- if self.active_view == 'visualization':
- cls += " active"
- %>
- <td class="${cls}">
- Visualization
- <div class="submenu">
- <ul>
- <li><a href="${h.url_for( controller='/tracks', action='index' )}">New Track Browser</a></li>
- <li><hr style="color: inherit; background-color: gray"/></li>
- <li><a href="${h.url_for( controller='/visualization', action='list' )}">Saved Visualizations</a></li>
- </ul>
- </div>
- </td>
- %endif
-
- ${tab( "admin", "Admin", h.url_for( controller='/admin', action='index' ), extra_class="admin-only", visible=( trans.user and app.config.is_admin_user( trans.user ) ) )}
-
- <td class="tab">
- <a>Help</a>
- <div class="submenu">
- <ul>
- <li><a href="${app.config.get( "bugs_email", "mailto:galaxy-bugs@bx.psu.edu" )}">Email comments, bug reports, or suggestions</a></li>
- <li><a target="_blank" href="${app.config.get( "wiki_url", "http://bitbucket.org/galaxy/galaxy-central/wiki" )}">Galaxy Wiki</a></li>
- <li><a target="_blank" href="${app.config.get( "screencasts_url", "http://galaxycast.org" )}">Video tutorials (screencasts)</a></li>
- <li><a target="_blank" href="${app.config.get( "citation_url", "http://bitbucket.org/galaxy/galaxy-central/wiki/Citations" )}">How to Cite Galaxy</a></li>
- </ul>
- </div>
- </td>
-
- ## User tab.
- <%
- cls = "tab"
- if self.active_view == 'user':
- cls += " active"
- %>
- <td class="${cls}">
- <a>User</a>
- <%
- if trans.user:
- user_email = trans.user.email
- style1 = "display: none;"
- style2 = "";
- else:
- user_email = ""
- style1 = ""
- style2 = "display: none;"
- %>
- <div class="submenu">
- <ul class="loggedout-only" style="${style1}">
- <li><a href="${h.url_for( controller='/user', action='login' )}">Login</a></li>
- %if app.config.allow_user_creation:
- <li><a href="${h.url_for( controller='/user', action='create' )}">Register</a></li>
- %endif
- </ul>
- <ul class="loggedin-only" style="${style2}">
- %if app.config.use_remote_user:
- %if app.config.remote_user_logout_href:
- <li><a href="${app.config.remote_user_logout_href}" target="_top">Logout</a></li>
- %endif
- %else:
- <li>Logged in as <span id="user-email">${user_email}</span></li>
- <li><a target="galaxy_main" href="${h.url_for( controller='/user', action='index' )}">Preferences</a></li>
- <%
- if app.config.require_login:
- logout_target = ""
- logout_url = h.url_for( controller='/root', action='index', m_c='user', m_a='logout' )
- else:
- logout_target = ""
- logout_url = h.url_for( controller='/user', action='logout' )
- %>
- <li><a target="${logout_target}" href="${logout_url}">Logout</a></li>
- %endif
- <li><hr style="color: inherit; background-color: gray"/></li>
- <li><a target="galaxy_main" href="${h.url_for( controller='/history', action='list' )}">Histories</a></li>
- <li><a target="galaxy_main" href="${h.url_for( controller='/dataset', action='list' )}">Datasets</a></li>
- %if app.config.get_bool( 'enable_pages', False ):
- <li><a href="${h.url_for( controller='/page', action='list' )}">Pages</a></li>
- %endif
- </ul>
- </div>
- </td>
-
- </tr>
- </table>
-
- </div>
-
- ## Logo, layered over tabs to be clickable
- <div class="title" style="position: absolute; top: 0; left: 0;">
- <a href="${app.config.get( 'logo_url', '/' )}">
- <img border="0" src="${h.url_for('/static/images/galaxyIcon_noText.png')}" style="width: 26px; vertical-align: top;">
- Galaxy
- %if app.config.brand:
- <span class='brand'>/ ${app.config.brand}</span>
- %endif
- </a>
- </div>
-
+ ## Override
</%def>
<%def name="overlay( title='', content='' )">
diff -r 9f32d8c55e30 -r 273535c97761 templates/cloud/index.mako
--- a/templates/cloud/index.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/cloud/index.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/display_base.mako
--- a/templates/display_base.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/display_base.mako Wed Mar 31 13:11:05 2010 -0400
@@ -3,7 +3,7 @@
if context.get('no_panels'):
return '/base.mako'
else:
- return '/base_panels.mako'
+ return '/webapps/galaxy/base_panels.mako'
from galaxy.model import History, StoredWorkflow, Page
from galaxy.web.framework.helpers import iff
diff -r 9f32d8c55e30 -r 273535c97761 templates/form.mako
--- a/templates/form.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/form.mako Wed Mar 31 13:11:05 2010 -0400
@@ -2,7 +2,7 @@
def inherit(context):
if context.get('use_panels') is True:
print "here"
- return '/base_panels.mako'
+ return '/webapps/galaxy/base_panels.mako'
else:
return '/base.mako'
%>
diff -r 9f32d8c55e30 -r 273535c97761 templates/grid_base.mako
--- a/templates/grid_base.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/grid_base.mako Wed Mar 31 13:11:05 2010 -0400
@@ -4,7 +4,7 @@
import galaxy.util
def inherit(context):
if context.get('use_panels'):
- return '/base_panels.mako'
+ return '/webapps/galaxy/base_panels.mako'
else:
return '/base.mako'
%>
diff -r 9f32d8c55e30 -r 273535c97761 templates/history/list_published.mako
--- a/templates/history/list_published.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/history/list_published.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/history/view.mako
--- a/templates/history/view.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/history/view.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%namespace file="/display_common.mako" import="get_history_link, get_controller_name" />
<%namespace file="/root/history_common.mako" import="render_dataset" />
<%namespace file="/tagging_common.mako" import="render_individual_tagging_element, render_community_tagging_element" />
diff -r 9f32d8c55e30 -r 273535c97761 templates/library/common/browse_library.mako
--- a/templates/library/common/browse_library.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/library/common/browse_library.mako Wed Mar 31 13:11:05 2010 -0400
@@ -5,7 +5,7 @@
<%!
def inherit(context):
if context.get('use_panels'):
- return '/base_panels.mako'
+ return '/webapps/galaxy/base_panels.mako'
else:
return '/base.mako'
%>
diff -r 9f32d8c55e30 -r 273535c97761 templates/library/index.mako
--- a/templates/library/index.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/library/index.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/message.mako
--- a/templates/message.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/message.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,7 +1,7 @@
<%!
def inherit(context):
if context.get('use_panels') is True:
- return '/base_panels.mako'
+ return '/webapps/galaxy/base_panels.mako'
else:
return '/base.mako'
%>
diff -r 9f32d8c55e30 -r 273535c97761 templates/page/editor.mako
--- a/templates/page/editor.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/page/editor.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/page/index.mako
--- a/templates/page/index.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/page/index.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/page/list_published.mako
--- a/templates/page/list_published.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/page/list_published.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/panels.mako
--- a/templates/panels.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/panels.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/requests/index.mako
--- a/templates/requests/index.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/requests/index.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/root/index.mako
--- a/templates/root/index.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/root/index.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="late_javascripts()">
${parent.late_javascripts()}
diff -r 9f32d8c55e30 -r 273535c97761 templates/sample/index.mako
--- a/templates/sample/index.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/sample/index.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/tracks/browser.mako
--- a/templates/tracks/browser.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/tracks/browser.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/visualization/list.mako
--- a/templates/visualization/list.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/visualization/list.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/visualization/list_published.mako
--- a/templates/visualization/list_published.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/visualization/list_published.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/webapps/galaxy/base_panels.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/webapps/galaxy/base_panels.mako Wed Mar 31 13:11:05 2010 -0400
@@ -0,0 +1,152 @@
+<%inherit file="/base_panels.mako"/>
+
+## Default title
+<%def name="title()">Galaxy</%def>
+
+## Masthead
+<%def name="masthead()">
+
+ ## Tab area, fills entire width
+ <div style="position: absolute; top: 0; left: 0; width: 100%; text-align: center">
+
+ <table class="tab-group" border="0" cellspacing="0" style="margin: auto;">
+ <tr>
+
+ <%def name="tab( id, display, href, target='_parent', visible=True, extra_class='' )">
+ <%
+ cls = "tab"
+ if extra_class:
+ cls += " " + extra_class
+ if self.active_view == id:
+ cls += " active"
+ style = ""
+ if not visible:
+ style = "display: none;"
+ %>
+ <td class="${cls}" style="${style}"><a target="${target}" href="${href}">${display}</a></td>
+ </%def>
+
+ %if app.config.cloud_controller_instance:
+ ${tab( "cloud", "Cloud", h.url_for( controller='/cloud', action='index' ))}
+ %else:
+ ${tab( "analysis", "Analyze Data", h.url_for( controller='/root', action='index' ))}
+
+ ${tab( "workflow", "Workflow", h.url_for( controller='/workflow', action='index' ))}
+
+ ${tab( "libraries", "Data Libraries", h.url_for( controller='/library', action='index' ))}
+ %endif
+
+ %if trans.user and trans.request_types():
+ <td class="tab">
+ <a>Lab</a>
+ <div class="submenu">
+ <ul>
+ <li><a href="${h.url_for( controller='/requests', action='index' )}">Sequencing Requests</a></li>
+ <li><a target="_blank" href="${app.config.get( "lims_doc_url", "http://main.g2.bx.psu.edu/u/rc/p/sts" )}">Help</a></li>
+ </ul>
+ </div>
+ </td>
+ %endif
+
+ %if app.config.get_bool( 'enable_tracks', False ):
+ <%
+ cls = "tab"
+ if self.active_view == 'visualization':
+ cls += " active"
+ %>
+ <td class="${cls}">
+ Visualization
+ <div class="submenu">
+ <ul>
+ <li><a href="${h.url_for( controller='/tracks', action='index' )}">New Track Browser</a></li>
+ <li><hr style="color: inherit; background-color: gray"/></li>
+ <li><a href="${h.url_for( controller='/visualization', action='list' )}">Saved Visualizations</a></li>
+ </ul>
+ </div>
+ </td>
+ %endif
+
+ ${tab( "admin", "Admin", h.url_for( controller='/admin', action='index' ), extra_class="admin-only", visible=( trans.user and app.config.is_admin_user( trans.user ) ) )}
+
+ <td class="tab">
+ <a>Help</a>
+ <div class="submenu">
+ <ul>
+ <li><a href="${app.config.get( "bugs_email", "mailto:galaxy-bugs@bx.psu.edu" )}">Email comments, bug reports, or suggestions</a></li>
+ <li><a target="_blank" href="${app.config.get( "wiki_url", "http://bitbucket.org/galaxy/galaxy-central/wiki" )}">Galaxy Wiki</a></li>
+ <li><a target="_blank" href="${app.config.get( "screencasts_url", "http://galaxycast.org" )}">Video tutorials (screencasts)</a></li>
+ <li><a target="_blank" href="${app.config.get( "citation_url", "http://bitbucket.org/galaxy/galaxy-central/wiki/Citations" )}">How to Cite Galaxy</a></li>
+ </ul>
+ </div>
+ </td>
+
+ ## User tab.
+ <%
+ cls = "tab"
+ if self.active_view == 'user':
+ cls += " active"
+ %>
+ <td class="${cls}">
+ <a>User</a>
+ <%
+ if trans.user:
+ user_email = trans.user.email
+ style1 = "display: none;"
+ style2 = "";
+ else:
+ user_email = ""
+ style1 = ""
+ style2 = "display: none;"
+ %>
+ <div class="submenu">
+ <ul class="loggedout-only" style="${style1}">
+ <li><a href="${h.url_for( controller='/user', action='login' )}">Login</a></li>
+ %if app.config.allow_user_creation:
+ <li><a href="${h.url_for( controller='/user', action='create' )}">Register</a></li>
+ %endif
+ </ul>
+ <ul class="loggedin-only" style="${style2}">
+ %if app.config.use_remote_user:
+ %if app.config.remote_user_logout_href:
+ <li><a href="${app.config.remote_user_logout_href}" target="_top">Logout</a></li>
+ %endif
+ %else:
+ <li>Logged in as <span id="user-email">${user_email}</span></li>
+ <li><a target="galaxy_main" href="${h.url_for( controller='/user', action='index' )}">Preferences</a></li>
+ <%
+ if app.config.require_login:
+ logout_target = ""
+ logout_url = h.url_for( controller='/root', action='index', m_c='user', m_a='logout' )
+ else:
+ logout_target = ""
+ logout_url = h.url_for( controller='/user', action='logout' )
+ %>
+ <li><a target="${logout_target}" href="${logout_url}">Logout</a></li>
+ %endif
+ <li><hr style="color: inherit; background-color: gray"/></li>
+ <li><a target="galaxy_main" href="${h.url_for( controller='/history', action='list' )}">Histories</a></li>
+ <li><a target="galaxy_main" href="${h.url_for( controller='/dataset', action='list' )}">Datasets</a></li>
+ %if app.config.get_bool( 'enable_pages', False ):
+ <li><a href="${h.url_for( controller='/page', action='list' )}">Pages</a></li>
+ %endif
+ </ul>
+ </div>
+ </td>
+
+ </tr>
+ </table>
+
+ </div>
+
+ ## Logo, layered over tabs to be clickable
+ <div class="title" style="position: absolute; top: 0; left: 0;">
+ <a href="${app.config.get( 'logo_url', '/' )}">
+ <img border="0" src="${h.url_for('/static/images/galaxyIcon_noText.png')}" style="width: 26px; vertical-align: top;">
+ Galaxy
+ %if app.config.brand:
+ <span class='brand'>/ ${app.config.brand}</span>
+ %endif
+ </a>
+ </div>
+
+</%def>
diff -r 9f32d8c55e30 -r 273535c97761 templates/workflow/editor.mako
--- a/templates/workflow/editor.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/workflow/editor.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/workflow/index.mako
--- a/templates/workflow/index.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/workflow/index.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/workflow/list.mako
--- a/templates/workflow/list.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/workflow/list.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
diff -r 9f32d8c55e30 -r 273535c97761 templates/workflow/list_published.mako
--- a/templates/workflow/list_published.mako Wed Mar 31 12:36:05 2010 -0400
+++ b/templates/workflow/list_published.mako Wed Mar 31 13:11:05 2010 -0400
@@ -1,4 +1,4 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
1
0
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/9f32d8c55e30
changeset: 3586:9f32d8c55e30
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Wed Mar 31 12:36:05 2010 -0400
description:
Fix old style display viewport generation when stop column is last column on a line.
diffstat:
lib/galaxy/datatypes/interval.py | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diffs (20 lines):
diff -r 56f4041ca926 -r 9f32d8c55e30 lib/galaxy/datatypes/interval.py
--- a/lib/galaxy/datatypes/interval.py Wed Mar 31 10:59:20 2010 -0400
+++ b/lib/galaxy/datatypes/interval.py Wed Mar 31 12:36:05 2010 -0400
@@ -150,7 +150,7 @@
peek = []
for idx, line in enumerate(file(dataset.file_name)):
if line[0] != '#':
- peek.append( line.split() )
+ peek.append( line.rstrip( '\n\r' ).split() )
if idx > 10:
break
@@ -975,6 +975,7 @@
wiggle_format = False
for line in open(dataset.file_name):
if (line.startswith("chr") or line.startswith("scaffold")):
+ line = line.rstrip( '\n\r' )
start = line.split("\t")[1].replace(",","")
end = line.split("\t")[2].replace(",","")
1
0
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/56f4041ca926
changeset: 3585:56f4041ca926
user: Dan Blankenberg <dan(a)bx.psu.edu>
date: Wed Mar 31 10:59:20 2010 -0400
description:
Fix header to column assignment in interval.set_meta().
diffstat:
lib/galaxy/datatypes/interval.py | 16 ++++++----------
1 files changed, 6 insertions(+), 10 deletions(-)
diffs (26 lines):
diff -r e34b76fcdb82 -r 56f4041ca926 lib/galaxy/datatypes/interval.py
--- a/lib/galaxy/datatypes/interval.py Wed Mar 31 10:32:23 2010 -0400
+++ b/lib/galaxy/datatypes/interval.py Wed Mar 31 10:59:20 2010 -0400
@@ -90,16 +90,12 @@
self.init_meta( dataset )
line = line.strip( '#' )
elems = line.split( '\t' )
- valid = dict( alias_helper ) # shrinks
- for index, col_name in enumerate( elems ):
- if col_name in valid:
- meta_name = valid[col_name]
- if overwrite or not dataset.metadata.element_is_set( meta_name ):
- setattr( dataset.metadata, meta_name, index+1 )
- values = alias_spec[ meta_name ]
- start = values.index( col_name )
- for lower in values[ start: ]:
- del valid[ lower ] # removes lower priority keys
+ for meta_name, header_list in alias_spec.iteritems():
+ for header_val in header_list:
+ if header_val in elems:
+ #found highest priority header to meta_name
+ setattr( dataset.metadata, meta_name, elems.index( header_val ) + 1 )
+ break #next meta_name
break # Our metadata is set, so break out of the outer loop
else:
# Header lines in Interval files are optional. For example, BED is Interval but has no header.
1
0
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/e34b76fcdb82
changeset: 3584:e34b76fcdb82
user: jeremy goecks <jeremy.goecks(a)emory.edu>
date: Wed Mar 31 10:32:23 2010 -0400
description:
Improve display of tables in pages; tables in pages now closely match tables in page editor.
diffstat:
templates/page/display.mako | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diffs (27 lines):
diff -r 193e5f4e2444 -r e34b76fcdb82 templates/page/display.mako
--- a/templates/page/display.mako Wed Mar 31 09:42:50 2010 -0400
+++ b/templates/page/display.mako Wed Mar 31 10:32:23 2010 -0400
@@ -230,6 +230,23 @@
.embedded-item h4 {
margin: 0px;
}
+ ## Format tables in pages so that they look like they do in the page editor.
+ .page-body table {
+ padding: 8px 5px 5px;
+ min-width: 500px;
+ border: none;
+ border-collapse: separate;
+ }
+ .page-body caption {
+ text-align: left;
+ background: #E4E4B0;
+ padding: 5px;
+ font-weight: bold;
+ }
+ .page-body td {
+ width: 25%;
+ padding: 0.2em 0.8em;
+ }
</style>
</%def>
1
0
15 Apr '10
details: http://www.bx.psu.edu/hg/galaxy/rev/193e5f4e2444
changeset: 3583:193e5f4e2444
user: Greg Von Kuster <greg(a)bx.psu.edu>
date: Wed Mar 31 09:42:50 2010 -0400
description:
De-couple the user controller from the model, adding a webapp param to some method signatures to allow for different webapps to use the controller. Clean up the methods in the controller, eliminating all that are no longer used. Fix the verification mehtod for resetting user names to use rules for setting user names. Add new mako templates for the login and reset password methods instead of the inline form building. Fix a bug where the user's private roles was not correctly updated when the user's email address was changed. Overhaul the test_user_info functional test script, cleaning up the mehtod code and to provide coverage for all of the above fixed bugs.
diffstat:
lib/galaxy/web/controllers/admin.py | 5 +-
lib/galaxy/web/controllers/mobile.py | 3 +-
lib/galaxy/web/controllers/user.py | 647 +++++++++++-------------
lib/galaxy/web/framework/__init__.py | 2 +-
lib/galaxy/webapps/__init__.py | 2 +-
lib/galaxy/webapps/reports/controllers/root.py | 12 +-
templates/user/index.mako | 6 +-
templates/user/info.mako | 98 +-
templates/user/login.mako | 30 +
templates/user/register.mako | 127 ++--
templates/user/reset_password.mako | 21 +
test/base/test_db_util.py | 13 +
test/base/twilltestcase.py | 70 +-
test/functional/test_admin_features.py | 8 +-
test/functional/test_data_security.py | 8 +-
test/functional/test_history_functions.py | 8 +-
test/functional/test_library_features.py | 8 +-
test/functional/test_library_security.py | 8 +-
test/functional/test_metadata_editing.py | 2 +-
test/functional/test_user_info.py | 227 +++++---
20 files changed, 688 insertions(+), 617 deletions(-)
diffs (2010 lines):
diff -r feff604427ee -r 193e5f4e2444 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py Tue Mar 30 17:03:29 2010 -0400
+++ b/lib/galaxy/web/controllers/admin.py Wed Mar 31 09:42:50 2010 -0400
@@ -710,7 +710,7 @@
def create_new_user( self, trans, **kwargs ):
return trans.response.send_redirect( web.url_for( controller='user',
action='create',
- admin_view='True' ) )
+ admin_view=True ) )
email = ''
password = ''
confirm = ''
@@ -956,7 +956,8 @@
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
user_id=user.id,
- admin_view=True, **kwd ) )
+ admin_view=True,
+ **kwd ) )
@web.expose
@web.require_admin
def name_autocomplete_data( self, trans, q=None, limit=None, timestamp=None ):
diff -r feff604427ee -r 193e5f4e2444 lib/galaxy/web/controllers/mobile.py
--- a/lib/galaxy/web/controllers/mobile.py Tue Mar 30 17:03:29 2010 -0400
+++ b/lib/galaxy/web/controllers/mobile.py Wed Mar 31 09:42:50 2010 -0400
@@ -55,7 +55,6 @@
elif not user.check_password( password ):
error = "Invalid password"
else:
- trans.handle_user_login( user )
+ trans.handle_user_login( user, 'galaxy' )
trans.log_event( "User logged in" )
return error
-
diff -r feff604427ee -r 193e5f4e2444 lib/galaxy/web/controllers/user.py
--- a/lib/galaxy/web/controllers/user.py Tue Mar 30 17:03:29 2010 -0400
+++ b/lib/galaxy/web/controllers/user.py Wed Mar 31 09:42:50 2010 -0400
@@ -6,9 +6,7 @@
from galaxy import util
import logging, os, string, re
from random import choice
-from galaxy.web.controllers.forms import get_all_forms
from galaxy.web.form_builder import *
-from galaxy.web.controllers import admin
log = logging.getLogger( __name__ )
@@ -26,182 +24,127 @@
VALID_USERNAME_RE = re.compile( "^[a-z0-9\-]+$" )
class User( BaseController ):
-
@web.expose
- def index( self, trans, **kwd ):
- return trans.fill_template( '/user/index.mako', user=trans.get_user() )
-
+ def index( self, trans, webapp='galaxy', **kwd ):
+ return trans.fill_template( '/user/index.mako', user=trans.get_user(), webapp=webapp )
@web.expose
- def change_password(self, trans, old_pass='', new_pass='', conf_pass='', **kwd):
- old_pass_err = new_pass_err = conf_pass_err = ''
- user = trans.get_user()
- if not user:
- trans.response.send_redirect( web.url_for( action='login' ) )
- if trans.request.method == 'POST':
- if not user.check_password( old_pass ):
- old_pass_err = "Invalid password"
- elif len( new_pass ) < 6:
- new_pass_err = "Please use a password of at least 6 characters"
- elif new_pass != conf_pass:
- conf_pass_err = "New passwords do not match."
- else:
- user.set_password_cleartext( new_pass )
- trans.sa_session.add( user )
- trans.sa_session.flush()
- trans.log_event( "User change password" )
- return trans.show_ok_message( "Password has been changed for " + user.email)
- # Generate input form
- return trans.show_form(
- web.FormBuilder( web.url_for() , "Change Password", submit_text="Submit" )
- .add_password( "old_pass", "Old Password", value='', error=old_pass_err )
- .add_password( "new_pass", "New Password", value='', error=new_pass_err )
- .add_password( "conf_pass", "Confirm Password", value='', error=conf_pass_err ) )
- @web.expose
- def change_email(self, trans, email='', conf_email='', password='', **kwd):
- email_err = conf_email_err = pass_err = ''
- user = trans.get_user()
- if not user:
- trans.response.send_redirect( web.url_for( action='login' ) )
- if trans.request.method == "POST":
- if not user.check_password( password ):
- pass_err = "Invalid password"
- elif len( email ) == 0 or "@" not in email or "." not in email:
- email_err = "Please enter a real email address"
- elif len( email) > 255:
- email_err = "Email address exceeds maximum allowable length"
- elif trans.sa_session.query( trans.app.model.User ).filter_by( email=email ).first():
- email_err = "User with that email already exists"
- elif email != conf_email:
- conf_email_err = "Email addresses do not match."
- else:
- user.email = email
- trans.sa_session.add( user )
- trans.sa_session.flush()
- trans.log_event( "User change email" )
- return trans.show_ok_message( "Email has been changed to: " + user.email, refresh_frames=['masthead', 'history'] )
- return trans.show_form(
- web.FormBuilder( web.url_for(), "Change Email", submit_text="Submit" )
- .add_text( "email", "Email", value=email, error=email_err )
- .add_text( "conf_email", "Confirm Email", value='', error=conf_email_err )
- .add_password( "password", "Password", value='', error=pass_err ) )
- @web.expose
- def change_username(self, trans, username='', **kwd):
- username_err = ''
- user = trans.get_user()
- if not user:
- trans.response.send_redirect( web.url_for( action='login' ) )
- if trans.request.method == "POST":
- if len( username ) < 4:
- username_err = "Username must be at least 4 characters in length"
- elif len( username ) > 255:
- username_err = "USername must be at most 255 characters in length"
- elif not( VALID_USERNAME_RE.match( username ) ):
- username_err = "Username must contain only letters, numbers, '-', and '_'"
- elif trans.sa_session.query( trans.app.model.User ).filter_by( username=username ).first():
- username_err = "This username is not available"
- else:
- user.username = username
- trans.sa_session.add( user )
- trans.sa_session.flush()
- trans.log_event( "User change username" )
- return trans.show_ok_message( "Username been set to: " + user.username )
- else:
- username = user.username or ''
- return trans.show_form(
- web.FormBuilder( web.url_for(), "Change username", submit_text="Submit" )
- .add_text( "username", "Username", value=username, error=username_err,
- help="""Your username is an optional identifier that
- will be used to generate adresses for information
- you share publicly. Usernames must be at least
- four characters in length and contain only lowercase
- letters, numbers, and the '-' character.""" ) )
-
- @web.expose
- def login( self, trans, email='', password='', referer='', use_panels='True' ):
- email_error = password_error = None
-
+ def login( self, trans, webapp='galaxy', **kwd ):
+ use_panels = kwd.get( 'use_panels', 'True' )
# Convert use_panels to Boolean.
use_panels = use_panels in [ 'True', 'true', 't', 'T' ]
-
- # Attempt login
- if trans.app.config.require_login:
- refresh_frames = [ 'masthead', 'history', 'tools' ]
- else:
- refresh_frames = [ 'masthead', 'history' ]
- if email or password:
+ msg = kwd.get( 'msg', '' )
+ messagetype = kwd.get( 'messagetype', 'done' )
+ if kwd.get( 'login_button', False ):
+ email = kwd.get( 'email', '' )
+ password = kwd.get( 'password', '' )
+ referer = kwd.get( 'referer', '' )
+ if webapp == 'galaxy':
+ if trans.app.config.require_login:
+ refresh_frames = [ 'masthead', 'history', 'tools' ]
+ else:
+ refresh_frames = [ 'masthead', 'history' ]
user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email==email ).first()
if not user:
- email_error = "No such user"
+ msg = "No such user"
+ messagetype = 'error'
elif user.deleted:
- email_error = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
+ msg = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
+ messagetype = 'error'
elif user.external:
- email_error = "This account was created for use with an external authentication method, contact your local Galaxy administrator to activate it."
+ msg = "This account was created for use with an external authentication method, contact your local Galaxy administrator to activate it."
+ messagetype = 'error'
elif not user.check_password( password ):
- password_error = "Invalid password"
+ msg = "Invalid password"
+ messagetype = 'error'
else:
- trans.handle_user_login( user )
+ trans.handle_user_login( user, webapp )
trans.log_event( "User logged in" )
- msg = "You are now logged in as %s.<br>You can <a href='%s'>go back to the page you were visiting</a> or <a href='%s'>go to the Galaxy homepage</a>." % ( user.email, referer, url_for( '/' ) )
+ msg = "You are now logged in as %s.<br>You can <a href='%s'>go back to the page you were visiting</a> or <a href='%s'>go to the home page</a>." % \
+ ( user.email, referer, url_for( '/' ) )
if trans.app.config.require_login:
- msg += ' <a href="%s">Click here</a> to continue to the front page.' % web.url_for( '/static/welcome.html' )
+ msg += ' <a href="%s">Click here</a> to continue to the home page.' % web.url_for( '/static/welcome.html' )
return trans.show_ok_message( msg, refresh_frames=refresh_frames, use_panels=use_panels, active_view="user" )
- form = web.FormBuilder( web.url_for(), "Login", submit_text="Login" ) \
- .add_text( "email", "Email address", value=email, error=email_error ) \
- .add_password( "password", "Password", value='', error=password_error,
- help="<a href='%s'>Forgot password? Reset here</a>" % web.url_for( action='reset_password' ) ) \
- .add_input( "hidden", "referer", "referer", value=trans.request.referer, use_label=False )
if trans.app.config.require_login:
if trans.app.config.allow_user_creation:
- return trans.show_form( form, header = require_login_creation_template % web.url_for( action = 'create' ), use_panels=use_panels, active_view="user" )
+ return trans.fill_template( '/user/login.mako',
+ webapp=webapp,
+ header=require_login_creation_template % web.url_for( action='create' ),
+ use_panels=use_panels,
+ msg=msg,
+ messagetype=messagetype,
+ active_view="user" )
else:
- return trans.show_form( form, header = require_login_nocreation_template, use_panels=use_panels, active_view="user" )
+ return trans.fill_template( '/user/login.mako',
+ webapp=webapp,
+ header=require_login_nocreation_template,
+ use_panels=use_panels,
+ msg=msg,
+ messagetype=messagetype,
+ active_view="user" )
+ return trans.fill_template( '/user/login.mako',
+ webapp=webapp,
+ use_panels=use_panels,
+ msg=msg,
+ messagetype=messagetype,
+ active_view="use" )
+ @web.expose
+ def logout( self, trans, webapp='galaxy' ):
+ if webapp == 'galaxy':
+ if trans.app.config.require_login:
+ refresh_frames = [ 'masthead', 'history', 'tools' ]
+ else:
+ refresh_frames = [ 'masthead', 'history' ]
else:
- return trans.show_form( form, use_panels=use_panels, active_view="user" )
-
- @web.expose
- def logout( self, trans ):
- if trans.app.config.require_login:
- refresh_frames = [ 'masthead', 'history', 'tools' ]
- else:
- refresh_frames = [ 'masthead', 'history' ]
+ refresh_frames = []
# Since logging an event requires a session, we'll log prior to ending the session
trans.log_event( "User logged out" )
trans.handle_user_logout()
- msg = "You have been logged out.<br>You can <a href='%s'>go back to the page you were visiting</a> or <a href='%s'>go to the Galaxy homepage</a>." % ( trans.request.referer, url_for( '/' ) )
+ msg = "You have been logged out.<br>You can <a href='%s'>go back to the page you were visiting</a> or <a href='%s'>go to the home page</a>." % \
+ ( trans.request.referer, url_for( '/' ) )
if trans.app.config.require_login:
msg += ' <a href="%s">Click here</a> to return to the login page.' % web.url_for( controller='user', action='login' )
return trans.show_ok_message( msg, refresh_frames=refresh_frames, use_panels=True, active_view="user" )
-
@web.expose
- def create( self, trans, **kwd ):
+ def create( self, trans, webapp='galaxy', **kwd ):
params = util.Params( kwd )
+ use_panels = kwd.get( 'use_panels', 'True' )
+ # Convert use_panels to Boolean.
+ use_panels = use_panels in [ 'True', 'true', 't', 'T' ]
email = util.restore_text( params.get( 'email', '' ) )
- username = util.restore_text( params.get( 'username', '' ) )
# Do not sanitize passwords, so take from kwd
# instead of params ( which were sanitized )
password = kwd.get( 'password', '' )
confirm = kwd.get( 'confirm', '' )
- subscribe = CheckboxField.is_checked( params.get( 'subscribe', '' ) )
- admin_view = params.get( 'admin_view', 'False' )
+ username = util.restore_text( params.get( 'username', '' ) )
+ subscribe = params.get( 'subscribe', '' )
+ subscribe_checked = CheckboxField.is_checked( subscribe )
+ admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
- if trans.app.config.require_login:
- refresh_frames = [ 'masthead', 'history', 'tools' ]
- else:
- refresh_frames = [ 'masthead', 'history' ]
+ if webapp == 'galaxy':
+ if trans.app.config.require_login:
+ refresh_frames = [ 'masthead', 'history', 'tools' ]
+ else:
+ refresh_frames = [ 'masthead', 'history' ]
if not trans.app.config.allow_user_creation and not trans.user_is_admin():
return trans.show_error_message( 'User registration is disabled. Please contact your Galaxy administrator for an account.' )
# Create the user, save all the user info and login to Galaxy
- if params.get('create_user_button', None) == "Submit":
- # check email and password validity
- error = self.__validate(trans, params, email, password, confirm)
+ if params.get( 'create_user_button', False ):
+ # Check email and password validity
+ error = self.__validate( trans, params, email, password, confirm, webapp )
if error:
- kwd[ 'msg' ] = error
- kwd[ 'messagetype' ] = 'error'
- kwd[ 'create_user_button' ] = None
return trans.response.send_redirect( web.url_for( controller='user',
action='create',
- **kwd ) )
+ webapp=webapp,email=email,
+ password=password,
+ confirm=confirm,
+ username=username,
+ subscribe=subscribe,
+ subscribe_checked=subscribe_checked,
+ admin_view=admin_view,
+ use_panels=use_panels,
+ msg=error,
+ messagetype='error' ) )
# all the values are valid
user = trans.app.model.User( email=email )
user.set_password_cleartext( password )
@@ -209,39 +152,55 @@
trans.sa_session.add( user )
trans.sa_session.flush()
trans.app.security_agent.create_private_user_role( user )
- # We set default user permissions, before we log in and set the default history permissions
- trans.app.security_agent.user_set_default_permissions( user, default_access_private = trans.app.config.new_user_dataset_access_role_default_private )
- # save user info
- self.__save_user_info(trans, user, action='create', new_user=True, **kwd)
- if subscribe:
- mail = os.popen("%s -t" % trans.app.config.sendmail_path, 'w')
- mail.write("To: %s\nFrom: %s\nSubject: Join Mailing List\n\nJoin Mailing list." % (trans.app.config.mailing_join_addr,email) )
- if mail.close():
- return trans.show_warn_message( "Now logged in as " + user.email+". However, subscribing to the mailing list has failed.", refresh_frames=refresh_frames )
- if admin_view == 'False':
- # The handle_user_login() method has a call to the history_set_default_permissions() method
- # (needed when logging in with a history), user needs to have default permissions set before logging in
- trans.handle_user_login( user )
- trans.log_event( "User created a new account" )
- trans.log_event( "User logged in" )
- # subscribe user to email list
- return trans.show_ok_message( "Now logged in as %s.<br><a href='%s'>Return to the Galaxy start page.</a>" % ( user.email, url_for( '/' ) ), refresh_frames=refresh_frames, use_panels=True )
+ if webapp == 'galaxy':
+ # We set default user permissions, before we log in and set the default history permissions
+ trans.app.security_agent.user_set_default_permissions( user,
+ default_access_private=trans.app.config.new_user_dataset_access_role_default_private )
+ # save user info
+ self.__save_user_info( trans, user, action='create', new_user=True, **kwd )
+ if subscribe_checked:
+ mail = os.popen( "%s -t" % trans.app.config.sendmail_path, 'w' )
+ mail.write( "To: %s\nFrom: %s\nSubject: Join Mailing List\n\nJoin Mailing list." % ( trans.app.config.mailing_join_addr,email ) )
+ if mail.close():
+ return trans.show_warn_message( "Now logged in as " + user.email+". However, subscribing to the mailing list has failed.",
+ refresh_frames=refresh_frames )
+ if not admin_view:
+ # The handle_user_login() method has a call to the history_set_default_permissions() method
+ # (needed when logging in with a history), user needs to have default permissions set before logging in
+ trans.handle_user_login( user, webapp )
+ trans.log_event( "User created a new account" )
+ trans.log_event( "User logged in" )
+ # subscribe user to email list
+ return trans.show_ok_message( "Now logged in as %s.<br><a href='%s'>Return to the home page.</a>" % \
+ ( user.email, url_for( '/' ) ), refresh_frames=refresh_frames, use_panels=True )
+ else:
+ trans.response.send_redirect( web.url_for( controller='admin',
+ action='users',
+ message='Created new user account (%s)' % user.email,
+ status='done' ) )
else:
- trans.response.send_redirect( web.url_for( controller='admin',
- action='users',
- message='Created new user account (%s)' % user.email,
- status='done' ) )
+ return trans.show_ok_message( "Now logged in as %s.<br><a href='%s'>Return to the home page.</a>" % \
+ ( user.email, url_for( '/' ) ), use_panels=False )
+ if webapp == 'galaxy':
+ user_info_select, user_info_form, widgets = self.__user_info_ui( trans, **kwd )
else:
- #
- # Show the user registration form
- #
- user_info_select, user_info_form, login_info, widgets = self.__user_info_ui(trans, **kwd)
- return trans.fill_template( '/user/register.mako',
- user_info_select=user_info_select,
- user_info_form=user_info_form, widgets=widgets,
- login_info=login_info, admin_view=admin_view,
- msg=msg, messagetype=messagetype)
-
+ user_info_select = []
+ user_info_form = []
+ widgets = []
+ return trans.fill_template( '/user/register.mako',
+ email=email,
+ password=password,
+ confirm=confirm,
+ username=username,
+ subscribe_checked=subscribe_checked,
+ admin_view=admin_view,
+ user_info_select=user_info_select,
+ user_info_form=user_info_form,
+ widgets=widgets,
+ webapp=webapp,
+ use_panels=use_panels,
+ msg=msg,
+ messagetype=messagetype )
def __save_user_info(self, trans, user, action, new_user=True, **kwd):
'''
This method saves the user information for new users as well as editing user
@@ -249,6 +208,10 @@
the one that user has selected. And for existing users, the user info form is
retrieved from the db.
'''
+ # TODO: the user controller must be decoupled from the model, so this import causes problems.
+ # The get_all_forms method is used only if Galaxy is the webapp, so it needs to be re-worked
+ # so that it can be imported with no problems if the controller is not 'galaxy'.
+ from galaxy.web.controllers.forms import get_all_forms
params = util.Params( kwd )
# get all the user information forms
user_info_forms = get_all_forms( trans, filter=dict(deleted=False),
@@ -325,53 +288,56 @@
trans.sa_session.add( user.values )
trans.sa_session.add( user )
trans.sa_session.flush()
- def __validate_email(self, trans, params, email, user=None):
+ def __validate_email( self, trans, email, user=None ):
error = None
- if user:
- if user.email == email:
- return None
- if len(email) == 0 or "@" not in email or "." not in email:
- error = "Please enter a real email address"
- elif len(email) > 255:
+ if user and user.email == email:
+ return None
+ if len( email ) == 0 or "@" not in email or "." not in email:
+ error = "Enter a real email address"
+ elif len( email ) > 255:
error = "Email address exceeds maximum allowable length"
- elif trans.sa_session.query( trans.app.model.User ).filter_by(email=email).all():
+ elif trans.sa_session.query( trans.app.model.User ).filter_by( email=email ).first():
error = "User with that email already exists"
return error
- def __validate_username(self, trans, params, username, user=None):
+ def __validate_username( self, trans, username, user=None ):
+ # User names must be at least four characters in length and contain only lower-case
+ # letters, numbers, and the '-' character.
+ if user and user.username == username:
+ return None
+ if len( username ) < 4:
+ return "User name must be at least 4 characters in length"
+ if len( username ) > 255:
+ return "User name cannot be more than 255 characters in length"
+ if not( VALID_USERNAME_RE.match( username ) ):
+ return "User name must contain only letters, numbers and '-'"
+ if trans.sa_session.query( trans.app.model.User ).filter_by( username=username ).first():
+ return "This user name is not available"
+ return None
+ def __validate_password( self, trans, password, confirm ):
error = None
- if user:
- if user.username == username:
- return None
- if len( username ) < 3:
- error = "Username must be at least 3 characters long"
- elif len( username ) > 255:
- error = "Username cannot be more than 255 characters"
- elif trans.sa_session.query( trans.app.model.User ).filter_by( username=username ).all():
- error = "User with that username already exists"
- return error
-
- def __validate_password(self, trans, params, password, confirm):
- error = None
- if len(password) < 6:
- error = "Please use a password of at least 6 characters"
+ if len( password ) < 6:
+ error = "Use a password of at least 6 characters"
elif password != confirm:
error = "Passwords do not match"
return error
-
- def __validate(self, trans, params, email, password, confirm):
- error = self.__validate_email(trans, params, email)
+ def __validate( self, trans, params, email, password, confirm, webapp ):
+ error = self.__validate_email( trans, email )
if error:
return error
- error = self.__validate_password(trans, params, password, confirm)
+ error = self.__validate_password( trans, password, confirm )
if error:
return error
- if len(get_all_forms( trans,
- filter=dict(deleted=False),
- form_type=trans.app.model.FormDefinition.types.USER_INFO )):
- if params.get('user_info_select', 'none') == 'none':
- return 'Select the user type and the user information'
+ if webapp == 'galaxy':
+ # TODO: the user controller must be decoupled from the model, so this import causes problems.
+ # The get_all_forms method is used only if Galaxy is the webapp, so it needs to be re-worked
+ # so that it can be imported with no problems if the controller is not 'galaxy'.
+ from galaxy.web.controllers.forms import get_all_forms
+ if len( get_all_forms( trans,
+ filter=dict( deleted=False ),
+ form_type=trans.app.model.FormDefinition.types.USER_INFO ) ):
+ if params.get( 'user_info_select', 'none' ) == 'none':
+ return 'Select the user type and the user information'
return None
-
def __user_info_ui(self, trans, user=None, **kwd):
'''
This method creates the user type select box & user information form widgets
@@ -381,6 +347,10 @@
show a selectbox containing all the forms, then the user can select
the one that fits the user's description the most
'''
+ # TODO: the user controller must be decoupled from the model, so this import causes problems.
+ # The get_all_forms method is used only if Galaxy is the webapp, so it needs to be re-worked
+ # so that it can be imported with no problems if the controller is not 'galaxy'.
+ from galaxy.web.controllers.forms import get_all_forms
params = util.Params( kwd )
# get all the user information forms
user_info_forms = get_all_forms( trans, filter=dict(deleted=False),
@@ -411,30 +381,11 @@
# when there is just one user information form the just render that form
elif len(user_info_forms) == 1:
selected_user_form_id = user_info_forms[0].id
- # now, create the selected user form widgets starting with the basic
- # login information
- if user:
- login_info = { 'Email': TextField( 'email', 40, user.email ),
- 'Public Username': TextField( 'username', 40, user.username ),
- 'Current Password': PasswordField( 'current', 40, '' ),
- 'New Password': PasswordField( 'password', 40, '' ),
- 'Confirm': PasswordField( 'confirm', 40, '' ) }
- else:
- login_info = { 'Email': TextField( 'email', 40,
- util.restore_text( params.get('email', '') ) ),
- 'Public Username': TextField( 'username', 40,
- util.restore_text( params.get( 'username', '' ) ) ),
- 'Password': PasswordField( 'password', 40,
- params.get( 'password', '' ) ),
- 'Confirm': PasswordField( 'confirm', 40,
- params.get( 'confirm', '' ) ),
- 'Subscribe To Mailing List': CheckboxField( 'subscribe',
- util.restore_text( params.get('subscribe', '') ) ) }
# user information
try:
user_info_form = trans.sa_session.query( trans.app.model.FormDefinition ).get(int(selected_user_form_id))
except:
- return user_info_select, None, login_info, None
+ return user_info_select, None, None
if user:
if user.values:
widgets = user_info_form.get_widgets(user=user,
@@ -444,32 +395,39 @@
widgets = user_info_form.get_widgets(None, contents=[], **kwd)
else:
widgets = user_info_form.get_widgets(None, contents=[], **kwd)
- return user_info_select, user_info_form, login_info, widgets
-
+ return user_info_select, user_info_form, widgets
@web.expose
def show_info( self, trans, **kwd ):
'''
This method displays the user information page which consists of login
- information, public username, reset password & other user information
+ information, public user name, reset password & other user information
obtained during registration
'''
+ # TODO: the user controller must be decoupled from the model, so this import causes problems.
+ # The get_all_forms method is used only if Galaxy is the webapp, so it needs to be re-worked
+ # so that it can be imported with no problems if the controller is not 'galaxy'.
+ from galaxy.web.controllers.forms import get_all_forms
params = util.Params( kwd )
+ user_id = params.get( 'user_id', None )
+ if user_id:
+ user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) )
+ else:
+ user = trans.user
+ if not user:
+ raise "In show_info, we don't have a valid user"
+ email = util.restore_text( params.get( 'email', user.email ) )
+ # Do not sanitize passwords, so take from kwd
+ # instead of params ( which were sanitized )
+ current = kwd.get( 'current', '' )
+ password = kwd.get( 'password', '' )
+ confirm = kwd.get( 'confirm', '' )
+ username = util.restore_text( params.get( 'username', '' ) )
+ if not username:
+ username = user.username
+ admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
- # check if this method is called from the admin perspective,
- if params.get('admin_view', 'False') == 'True':
- try:
- user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'user_id', None ) ) )
- except:
- return trans.response.send_redirect( web.url_for( controller='admin',
- action='users',
- message='Invalid user',
- status='error' ) )
- admin_view = True
- else:
- user = trans.user
- admin_view = False
- user_info_select, user_info_form, login_info, widgets = self.__user_info_ui(trans, user, **kwd)
+ user_info_select, user_info_form, widgets = self.__user_info_ui( trans, user, **kwd )
# user's addresses
show_filter = util.restore_text( params.get( 'show_filter', 'Active' ) )
if show_filter == 'All':
@@ -480,73 +438,75 @@
addresses = [address for address in user.addresses if not address.deleted]
user_info_forms = get_all_forms( trans, filter=dict(deleted=False),
form_type=trans.app.model.FormDefinition.types.USER_INFO )
- return trans.fill_template( '/user/info.mako', user=user, admin_view=admin_view,
+ return trans.fill_template( '/user/info.mako',
+ user=user,
+ email=email,
+ current=current,
+ password=password,
+ confirm=confirm,
+ username=username,
user_info_select=user_info_select,
- user_info_form=user_info_form, widgets=widgets,
- login_info=login_info, user_info_forms=user_info_forms,
- addresses=addresses, show_filter=show_filter,
- msg=msg, messagetype=messagetype)
+ user_info_forms=user_info_forms,
+ user_info_form=user_info_form,
+ widgets=widgets,
+ addresses=addresses,
+ show_filter=show_filter,
+ admin_view=admin_view,
+ msg=msg,
+ messagetype=messagetype )
@web.expose
def edit_info( self, trans, **kwd ):
params = util.Params( kwd )
+ user_id = params.get( 'user_id', None )
+ admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
- if params.get('admin_view', 'False') == 'True':
- try:
- user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'user_id', None ) ) )
- except:
- return trans.response.send_redirect( web.url_for( controller='admin',
- action='users',
- message='Invalid user',
- status='error' ) )
+ if user_id:
+ user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) )
else:
user = trans.user
- #
- # Editing login info (email & username)
- #
- if params.get('login_info_button', None) == 'Save':
- email = util.restore_text( params.get('email', '') ).lower()
- username = util.restore_text( params.get('username', '') ).lower()
+ # Editing login info ( email & username )
+ if params.get( 'login_info_button', False ):
+ email = util.restore_text( params.get( 'email', '' ) )
+ username = util.restore_text( params.get( 'username', '' ) ).lower()
# validate the new values
- error = self.__validate_email(trans, params, email, user)
+ error = self.__validate_email( trans, email, user )
+ if not error:
+ error = self.__validate_username( trans, username, user )
if error:
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
msg=error,
messagetype='error') )
- error = self.__validate_username( trans, params, username, user )
- if error:
- return trans.response.send_redirect( web.url_for( controller='user',
- action='show_info',
- msg=error,
- messagetype='error') )
- # the new email & username
+ # The user's private role name must match the user's login ( email )
+ private_role = trans.app.security_agent.get_private_user_role( user )
+ private_role.name = email
+ private_role.description = 'Private role for ' + email
+ # Now change the user info
user.email = email
user.username = username
- trans.sa_session.add( user )
+ trans.sa_session.add_all( ( user, private_role ) )
trans.sa_session.flush()
msg = 'The login information has been updated with the changes'
- if params.get('admin_view', 'False') == 'True':
+ if admin_view:
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
user_id=user.id,
- admin_view=True,
+ admin_view=admin_view,
msg=msg,
messagetype='done' ) )
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
msg=msg,
messagetype='done') )
- #
# Change password
- #
- elif params.get('change_password_button', None) == 'Save':
+ elif params.get( 'change_password_button', False ):
# Do not sanitize passwords, so get from kwd and not params
# ( which were sanitized ).
password = kwd.get( 'password', '' )
confirm = kwd.get( 'confirm', '' )
- # when from the user perspective, validate the current password
- if params.get('admin_view', 'False') == 'False':
+ # When from the user perspective, validate the current password
+ if not admin_view:
# Do not sanitize passwords, so get from kwd and not params
# ( which were sanitized ).
current = kwd.get( 'current', '' )
@@ -556,13 +516,13 @@
msg='Invalid current password',
messagetype='error') )
# validate the new values
- error = self.__validate_password(trans, params, password, confirm)
+ error = self.__validate_password( trans, password, confirm )
if error:
- if params.get('admin_view', 'False') == 'True':
+ if admin_view:
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
user_id=user.id,
- admin_view=True,
+ admin_view=admin_view,
msg=error,
messagetype='error' ) )
return trans.response.send_redirect( web.url_for( controller='user',
@@ -575,28 +535,26 @@
trans.sa_session.flush()
trans.log_event( "User change password" )
msg = 'The password has been changed.'
- if params.get('admin_view', 'False') == 'True':
+ if admin_view:
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
user_id=user.id,
- admin_view=True,
+ admin_view=admin_view,
msg=msg,
messagetype='done' ) )
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
msg=msg,
messagetype='done') )
- #
# Edit user information
- #
- elif params.get('edit_user_info_button', None) == 'Save':
+ elif params.get( 'edit_user_info_button', False ):
self.__save_user_info(trans, user, "show_info", new_user=False, **kwd)
msg = "The user information has been updated with the changes."
- if params.get('admin_view', 'False') == 'True':
+ if admin_view:
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
user_id=user.id,
- admin_view=True,
+ admin_view=admin_view,
msg=msg,
messagetype='done' ) )
return trans.response.send_redirect( web.url_for( controller='user',
@@ -604,43 +562,48 @@
msg=msg,
messagetype='done') )
else:
- if params.get('admin_view', 'False') == 'True':
+ if admin_view:
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
user_id=user.id,
- admin_view=True ) )
+ admin_view=admin_view ) )
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info' ) )
-
@web.expose
- def reset_password( self, trans, email=None, **kwd ):
- error = ''
- reset_user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email==email ).first()
- user = trans.get_user()
- if reset_user:
- if user and user.id != reset_user.id:
- error = "You may only reset your own password"
- else:
- chars = string.letters + string.digits
- new_pass = ""
- for i in range(15):
- new_pass = new_pass + choice(chars)
- mail = os.popen("%s -t" % trans.app.config.sendmail_path, 'w')
- mail.write("To: %s\nFrom: no-reply(a)nowhere.edu\nSubject: Galaxy Password Reset\n\nYour password has been reset to \"%s\" (no quotes)." % (email, new_pass) )
- if mail.close():
- return trans.show_error_message( 'Failed to reset password. If this problem persists, please submit a bug report.' )
- reset_user.set_password_cleartext( new_pass )
- trans.sa_session.add( reset_user )
- trans.sa_session.flush()
- trans.log_event( "User reset password: %s" % email )
- return trans.show_ok_message( "Password has been reset and emailed to: %s. <a href='%s'>Click here</a> to return to the login form." % ( email, web.url_for( action='login' ) ) )
- elif email != None:
- error = "The specified user does not exist"
- elif email is None:
- email = ""
- return trans.show_form(
- web.FormBuilder( web.url_for(), "Reset Password", submit_text="Submit" )
- .add_text( "email", "Email", value=email, error=error ) )
+ def reset_password( self, trans, email=None, webapp='galaxy', **kwd ):
+ msg = util.restore_text( kwd.get( 'msg', '' ) )
+ messagetype = 'done'
+ if kwd.get( 'reset_password_button', False ):
+ reset_user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email==email ).first()
+ user = trans.get_user()
+ if reset_user:
+ if user and user.id != reset_user.id:
+ msg = "You may only reset your own password"
+ messagetype = 'error'
+ else:
+ chars = string.letters + string.digits
+ new_pass = ""
+ for i in range(15):
+ new_pass = new_pass + choice(chars)
+ mail = os.popen("%s -t" % trans.app.config.sendmail_path, 'w')
+ mail.write("To: %s\nFrom: no-reply(a)nowhere.edu\nSubject: Galaxy Password Reset\n\nYour password has been reset to \"%s\" (no quotes)." % (email, new_pass) )
+ if mail.close():
+ msg = 'Failed to reset password. If this problem persists, please submit a bug report.'
+ messagetype = 'error'
+ reset_user.set_password_cleartext( new_pass )
+ trans.sa_session.add( reset_user )
+ trans.sa_session.flush()
+ trans.log_event( "User reset password: %s" % email )
+ return trans.show_ok_message( "Password has been reset and emailed to: %s. <a href='%s'>Click here</a> to return to the login form." % ( email, web.url_for( action='login' ) ) )
+ elif email != None:
+ msg = "The specified user does not exist"
+ messagetype = 'error'
+ elif email is None:
+ email = ""
+ return trans.fill_template( '/user/reset_password.mako',
+ webapp=webapp,
+ msg=msg,
+ messagetype=messagetype )
@web.expose
def set_default_permissions( self, trans, **kwd ):
"""Sets the user's default permissions for the new histories"""
@@ -687,7 +650,7 @@
params = util.Params( kwd )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
- admin_view = params.get( 'admin_view', 'False' )
+ admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
error = ''
user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'user_id', None ) ) )
if not trans.app.config.allow_user_creation and not trans.user_is_admin():
@@ -723,10 +686,10 @@
trans.sa_session.add( user_address )
trans.sa_session.flush()
msg = 'Address <b>%s</b> has been added' % user_address.desc
- if admin_view == 'True':
+ if admin_view:
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
- admin_view=True,
+ admin_view=admin_view,
user_id=user.id,
msg=msg,
messagetype='done') )
@@ -758,26 +721,23 @@
widget=TextField( 'country', 40, '' ) ) )
widgets.append(dict(label='Phone',
widget=TextField( 'phone', 40, '' ) ) )
- return trans.fill_template( 'user/new_address.mako', user=user,
+ return trans.fill_template( 'user/new_address.mako',
+ user=user,
admin_view=admin_view,
- widgets=widgets, msg=msg, messagetype=messagetype)
+ widgets=widgets,
+ msg=msg,
+ messagetype=messagetype)
@web.expose
def edit_address( self, trans, **kwd ):
params = util.Params( kwd )
+ user_id = params.get( 'user_id', None )
+ address_id = params.get( 'address_id', None )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
- admin_view = params.get( 'admin_view', 'False' )
+ admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
error = ''
- user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'user_id', None ) ) )
- try:
- user_address = trans.sa_session.query( trans.app.model.UserAddress ).get(int(params.get( 'address_id', None )))
- except:
- return trans.response.send_redirect( web.url_for( controller='user',
- action='show_info',
- user_id=user.id,
- admin_view=admin_view,
- msg='Invalid address ID',
- messagetype='error' ) )
+ user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) )
+ user_address = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) )
if params.get( 'edit_address_button', None ) == 'Save changes':
if not len( util.restore_text( params.get( 'short_desc', '' ) ) ):
error = 'Enter a short description for this address'
@@ -808,11 +768,11 @@
trans.sa_session.add( user_address )
trans.sa_session.flush()
msg = 'Changes made to address <b>%s</b> are saved.' % user_address.desc
- if admin_view == 'True':
+ if admin_view:
return trans.response.send_redirect( web.url_for( controller='user',
action='show_info',
user_id=user.id,
- admin_view=True,
+ admin_view=admin_view,
msg=msg,
messagetype='done' ) )
return trans.response.send_redirect( web.url_for( controller='user',
@@ -843,11 +803,15 @@
widget=TextField( 'country', 40, user_address.country ) ) )
widgets.append(dict(label='Phone',
widget=TextField( 'phone', 40, user_address.phone ) ) )
- return trans.fill_template( 'user/edit_address.mako', user=user,
- address=user_address, admin_view=admin_view,
- widgets=widgets, msg=msg, messagetype=messagetype)
+ return trans.fill_template( 'user/edit_address.mako',
+ user=user,
+ address=user_address,
+ admin_view=admin_view,
+ widgets=widgets,
+ msg=msg,
+ messagetype=messagetype)
@web.expose
- def delete_address( self, trans, address_id=None, user_id=None, admin_view='False'):
+ def delete_address( self, trans, address_id=None, user_id=None, admin_view=False ):
try:
user_address = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) )
except:
@@ -866,7 +830,7 @@
msg='Address <b>%s</b> deleted' % user_address.desc,
messagetype='done') )
@web.expose
- def undelete_address( self, trans, address_id=None, user_id=None, admin_view='False'):
+ def undelete_address( self, trans, address_id=None, user_id=None, admin_view=False ):
try:
user_address = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) )
except:
@@ -884,4 +848,3 @@
user_id=user_id,
msg='Address <b>%s</b> undeleted' % user_address.desc,
messagetype='done') )
-
diff -r feff604427ee -r 193e5f4e2444 lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py Tue Mar 30 17:03:29 2010 -0400
+++ b/lib/galaxy/web/framework/__init__.py Wed Mar 31 09:42:50 2010 -0400
@@ -411,7 +411,7 @@
Update the session cookie to match the current session.
"""
self.set_cookie( self.security.encode_session_key( self.galaxy_session.session_key ), name=name )
- def handle_user_login( self, user ):
+ def handle_user_login( self, user, webapp ):
"""
Login a new user (possibly newly created)
- create a new session
diff -r feff604427ee -r 193e5f4e2444 lib/galaxy/webapps/__init__.py
--- a/lib/galaxy/webapps/__init__.py Tue Mar 30 17:03:29 2010 -0400
+++ b/lib/galaxy/webapps/__init__.py Wed Mar 31 09:42:50 2010 -0400
@@ -1,3 +1,3 @@
-"""Galaxy Reports root package -- this is a namespace package."""
+"""Galaxy webapps root package -- this is a namespace package."""
__import__( "pkg_resources" ).declare_namespace( __name__ )
\ No newline at end of file
diff -r feff604427ee -r 193e5f4e2444 lib/galaxy/webapps/reports/controllers/root.py
--- a/lib/galaxy/webapps/reports/controllers/root.py Tue Mar 30 17:03:29 2010 -0400
+++ b/lib/galaxy/webapps/reports/controllers/root.py Wed Mar 31 09:42:50 2010 -0400
@@ -14,9 +14,11 @@
brand = trans.app.config.get( "brand", "" )
if brand:
brand ="<span class='brand'>/%s</span>" % brand
- wiki_url = trans.app.config.get( "wiki_url", "http://g2.trac.bx.psu.edu/" )
+ wiki_url = trans.app.config.get( "wiki_url", "http://bitbucket.org/galaxy/galaxy-central/wiki/Home" )
bugs_email = trans.app.config.get( "bugs_email", "mailto:galaxy-bugs@bx.psu.edu" )
- blog_url = trans.app.config.get( "blog_url", "http://g2.trac.bx.psu.edu/blog" )
- screencasts_url = trans.app.config.get( "screencasts_url", "http://g2.trac.bx.psu.edu/wiki/ScreenCasts" )
- return trans.fill_template( "masthead.mako", brand=brand, wiki_url=wiki_url, blog_url=blog_url,bugs_email=bugs_email, screencasts_url=screencasts_url )
-
+ screencasts_url = trans.app.config.get( "screencasts_url", "http://galaxycast.org" )
+ return trans.fill_template( "masthead.mako",
+ brand=brand,
+ wiki_url=wiki_url,
+ bugs_email=bugs_email,
+ screencasts_url=screencasts_url )
diff -r feff604427ee -r 193e5f4e2444 templates/user/index.mako
--- a/templates/user/index.mako Tue Mar 30 17:03:29 2010 -0400
+++ b/templates/user/index.mako Wed Mar 31 09:42:50 2010 -0400
@@ -7,8 +7,10 @@
%if user:
<p>You are currently logged in as ${user.email}.</p>
<ul>
- <li><a href="${h.url_for( action='show_info' )}">${_('Manage your information')}</a></li>
- <li><a href="${h.url_for( action='set_default_permissions' )}">${_('Change default permissions')}</a> for new histories</li>
+ %if webapp == 'galaxy':
+ <li><a href="${h.url_for( action='show_info' )}">${_('Manage your information')}</a></li>
+ <li><a href="${h.url_for( action='set_default_permissions' )}">${_('Change default permissions')}</a> for new histories</li>
+ %endif
<li><a href="${h.url_for( action='logout' )}">${_('Logout')}</a></li>
</ul>
%else:
diff -r feff604427ee -r 193e5f4e2444 templates/user/info.mako
--- a/templates/user/info.mako Tue Mar 30 17:03:29 2010 -0400
+++ b/templates/user/info.mako Wed Mar 31 09:42:50 2010 -0400
@@ -1,7 +1,6 @@
<%inherit file="/base.mako"/>
<%namespace file="/message.mako" import="render_msg" />
-
%if msg:
${render_msg( msg, messagetype )}
%endif
@@ -45,15 +44,20 @@
<form name="login_info" id="login_info" action="${h.url_for( controller='user', action='edit_info', user_id=user.id, admin_view=admin_view )}" method="post" >
<div class="toolFormTitle">Login Information</div>
<div class="form-row">
- <label>Email</label>
- ${login_info[ 'Email' ].get_html()}
+ <label>Email address:</label>
+ <input type="text" name="email" value="${email}" size="40"/>
</div>
<div class="form-row">
- <label>Public Username</label>
- ${login_info[ 'Public Username' ].get_html()}
+ <label>Public user name:</label>
+ <input type="text" name="username" size="40" value="${username}"/>
+ <div class="toolParamHelp" style="clear: both;">
+ Your user name is an optional identifier that will be used to generate addresses for information
+ you share publicly. User names must be at least four characters in length and contain only lower-case
+ letters, numbers, and the '-' character.
+ </div>
</div>
<div class="form-row">
- <input type="submit" name="login_info_button" value="Save">
+ <input type="submit" name="login_info_button" value="Save"/>
</div>
</form>
</div>
@@ -63,54 +67,54 @@
<div class="toolFormTitle">Change Password</div>
%if not admin_view:
<div class="form-row">
- <label>Current Password</label>
- ${login_info[ 'Current Password' ].get_html()}
+ <label>Current Password:</label>
+ <input type="password" name="current" value="${current}" size="40"/>
</div>
%endif
<div class="form-row">
- <label>New Password</label>
- ${login_info[ 'New Password' ].get_html()}
+ <label>New Password:</label>
+ <input type="password" name="password" value="${password}" size="40"/>
</div>
<div class="form-row">
- <label>Confirm</label>
- ${login_info[ 'Confirm' ].get_html()}
+ <label>Confirm:</label>
+ <input type="password" name="confirm" value="${confirm}" size="40"/>
</div>
<div class="form-row">
- <input type="submit" name="change_password_button" value="Save">
+ <input type="submit" name="change_password_button" value="Save"/>
</div>
</form>
</div>
%if user.values or user_info_forms:
-<p></p>
-<div class="toolForm">
- <form name="user_info" id="user_info" action="${h.url_for( controller='user', action='edit_info', user_id=user.id, admin_view=admin_view )}" method="post" >
- <div class="toolFormTitle">User information</div>
- %if user_info_select:
+ <p></p>
+ <div class="toolForm">
+ <form name="user_info" id="user_info" action="${h.url_for( controller='user', action='edit_info', user_id=user.id, admin_view=admin_view )}" method="post" >
+ <div class="toolFormTitle">User information</div>
+ %if user_info_select:
+ <div class="form-row">
+ <label>User type:</label>
+ ${user_info_select.get_html()}
+ </div>
+ %endif
+
+ %for field in widgets:
+ <div class="form-row">
+ <label>${field['label']}:</label>
+ ${field['widget'].get_html()}
+ <div class="toolParamHelp" style="clear: both;">
+ ${field['helptext']}
+ </div>
+ <div style="clear: both"></div>
+ </div>
+ %endfor
+ %if not user_info_select:
+ <input type="hidden" name="user_info_select" value="${user_info_form.id}"/>
+ %endif
+
<div class="form-row">
- <label>User type</label>
- ${user_info_select.get_html()}
+ <input type="submit" name="edit_user_info_button" value="Save"/>
</div>
- %endif
-
- %for field in widgets:
- <div class="form-row">
- <label>${field['label']}</label>
- ${field['widget'].get_html()}
- <div class="toolParamHelp" style="clear: both;">
- ${field['helptext']}
- </div>
- <div style="clear: both"></div>
- </div>
- %endfor
- %if not user_info_select:
- <input type="hidden" name="user_info_select" value="${user_info_form.id}"/>
- %endif
-
- <div class="form-row">
- <input type="submit" name="edit_user_info_button" value="Save">
- </div>
- </form>
-</div>
+ </form>
+ </div>
%endif
<p></p>
<div class="toolForm">
@@ -139,7 +143,7 @@
<tr class="libraryRow libraryOrFolderRow" id="libraryRow">
<td>
<div class="form-row">
- <label>${address.desc}</label>
+ <label>${address.desc}:</label>
${address.get_html()}
</div>
<div class="form-row">
@@ -167,10 +171,6 @@
<div class="form-row">
<input type="submit" value="Add a new address">
</div>
- </div>
- </form>
-
-
-
-
-</div>
\ No newline at end of file
+ </div>
+ </form>
+</div>
diff -r feff604427ee -r 193e5f4e2444 templates/user/login.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/user/login.mako Wed Mar 31 09:42:50 2010 -0400
@@ -0,0 +1,30 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+<div class="toolForm">
+ <div class="toolFormTitle">Login</div>
+ %if header:
+ ${header}
+ %endif
+ <form name="login" id="login" action="${h.url_for( controller='user', action='login' )}" method="post" >
+ <div class="form-row">
+ <label>Email address:</label>
+ <input type="text" name="email" value="" size="40"/>
+ <input type="hidden" name="webapp" value="${webapp}" size="40"/>
+ <input type="hidden" name="referer" value="${trans.request.referer}" size="40"/>
+ </div>
+ <div class="form-row">
+ <label>Password:</label>
+ <input type="password" name="password" value="" size="40"/>
+ <div class="toolParamHelp" style="clear: both;">
+ <a href="${h.url_for( controller='user', action='reset_password', webapp=webapp, use_panels=use_panels )}">Forgot password? Reset here</a>
+ </div>
+ </div>
+ <div class="form-row">
+ <input type="submit" name="login_button" value="Login"/>
+ </div>
+ </form>
+</div>
diff -r feff604427ee -r 193e5f4e2444 templates/user/register.mako
--- a/templates/user/register.mako Tue Mar 30 17:03:29 2010 -0400
+++ b/templates/user/register.mako Wed Mar 31 09:42:50 2010 -0400
@@ -1,15 +1,6 @@
-<%inherit file="/base_panels.mako"/>
+<%inherit file="/base.mako"/>
<%namespace file="/message.mako" import="render_msg" />
-<%def name="init()">
-<%
- self.has_left_panel=False
- self.has_right_panel=False
- self.active_view="user"
- self.message_box_visible=False
-%>
-</%def>
-
<%def name="javascripts()">
${parent.javascripts()}
<script type="text/javascript">
@@ -36,64 +27,68 @@
});
});
</script>
-
</%def>
-<%def name="center_panel()">
- %if msg:
- ${render_msg( msg, messagetype )}
- %endif
-
- <div class="toolForm" style="margin: 1em">
- <form name="registration" id="registration" action="${h.url_for( controller='user', action='create', admin_view=admin_view )}" method="post" >
- <div class="toolFormTitle">Create account</div>
+<%
+ from galaxy.web.form_builder import CheckboxField
+ subscribe_check_box = CheckboxField( 'subscribe' )
+%>
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+<div class="toolForm">
+ <form name="registration" id="registration" action="${h.url_for( controller='user', action='create', admin_view=admin_view )}" method="post" >
+ <div class="toolFormTitle">Create account</div>
+ <div class="form-row">
+ <label>Email address:</label>
+ <input type="text" name="email" value="${email}" size="40"/>
+ <input type="hidden" name="webapp" value="${webapp}" size="40"/>
+ </div>
+ <div class="form-row">
+ <label>Password:</label>
+ <input type="password" name="password" value="${password}" size="40"/>
+ </div>
+ <div class="form-row">
+ <label>Confirm password:</label>
+ <input type="password" name="confirm" value="${confirm}" size="40"/>
+ </div>
+ <div class="form-row">
+ <label>Public user name:</label>
+ <input type="text" name="username" size="40" value="${username}"/>
+ <div class="toolParamHelp" style="clear: both;">
+ When you share or publish items, this name is shown as the author.
+ </div>
+ </div>
+ <div class="form-row">
+ <label>Subscribe to mailing list:</label>
+ %if subscribe_checked:
+ <% subscribe_check_box.checked = True %>
+ %endif
+ ${subscribe_check_box.get_html()}
+ </div>
+ %if user_info_select:
<div class="form-row">
- <label>Email</label>
- ${login_info[ 'Email' ].get_html()}
+ <label>User type</label>
+ ${user_info_select.get_html()}
</div>
- <div class="form-row">
- <label>Password</label>
- ${login_info[ 'Password' ].get_html()}
- </div>
- <div class="form-row">
- <label>Confirm Password</label>
- ${login_info[ 'Confirm' ].get_html()}
- </div>
- <div class="form-row">
- <label>Public Username</label>
- ${login_info[ 'Public Username' ].get_html()}
- <div class="toolParamHelp" style="clear: both;">
- When you share or publish items, this name is shown as the author.
+ %endif
+ %if user_info_form:
+ %for field in widgets:
+ <div class="form-row">
+ <label>${field['label']}</label>
+ ${field['widget'].get_html()}
+ <div class="toolParamHelp" style="clear: both;">
+ ${field['helptext']}
+ </div>
+ <div style="clear: both"></div>
</div>
- </div>
- <div class="form-row">
- <label>Subscribe To Mailing List</label>
- ${login_info[ 'Subscribe To Mailing List' ].get_html()}
- </div>
- %if user_info_select:
- <div class="form-row">
- <label>User type</label>
- ${user_info_select.get_html()}
- </div>
- %endif
- %if user_info_form:
- %for field in widgets:
- <div class="form-row">
- <label>${field['label']}</label>
- ${field['widget'].get_html()}
- <div class="toolParamHelp" style="clear: both;">
- ${field['helptext']}
- </div>
- <div style="clear: both"></div>
- </div>
- %endfor
- %if not user_info_select:
- <input type="hidden" name="user_info_select" value="${user_info_form.id}"/>
- %endif
- %endif
- <div class="form-row">
- <input type="submit" name="create_user_button" value="Submit">
- </div>
- </form>
- </div>
-</%def>
\ No newline at end of file
+ %endfor
+ %if not user_info_select:
+ <input type="hidden" name="user_info_select" value="${user_info_form.id}"/>
+ %endif
+ %endif
+ <div class="form-row">
+ <input type="submit" name="create_user_button" value="Submit"/>
+ </div>
+ </form>
+</div>
diff -r feff604427ee -r 193e5f4e2444 templates/user/reset_password.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/user/reset_password.mako Wed Mar 31 09:42:50 2010 -0400
@@ -0,0 +1,21 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+%if msg:
+ ${render_msg( msg, messagetype )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">Login</div>
+ <form name="reset_password" id="reset_password" action="${h.url_for( controller='user', action='reset_password' )}" method="post" >
+ <div class="form-row">
+ <label>Email:</label>
+ <input type="text" name="email" value="" size="40"/>
+ <input type="hidden" name="webapp" value="${webapp}" size="40"/>
+ </div>
+ <div style="clear: both"></div>
+ <div class="form-row">
+ <input type="submit" name="reset_password_button" value="Submit"/>
+ </div>
+ </form>
+</div>
diff -r feff604427ee -r 193e5f4e2444 test/base/test_db_util.py
--- a/test/base/test_db_util.py Tue Mar 30 17:03:29 2010 -0400
+++ b/test/base/test_db_util.py Wed Mar 31 09:42:50 2010 -0400
@@ -4,6 +4,13 @@
from base.twilltestcase import *
import sys
+def delete_obj( obj ):
+ sa_session.delete( obj )
+ sa_session.flush()
+def delete_user_roles( user ):
+ for ura in user.roles:
+ sa_session.delete( ura )
+ sa_session.flush()
def flush( obj ):
sa_session.add( obj )
sa_session.flush()
@@ -106,9 +113,15 @@
return sa_session.query( galaxy.model.UserGroupAssociation ) \
.filter( galaxy.model.UserGroupAssociation.table.c.group_id == group.id ) \
.all()
+def get_user_info_form_definition():
+ return galaxy.model.FormDefinition.types.USER_INFO
def get_user_role_associations_by_role( role ):
return sa_session.query( galaxy.model.UserRoleAssociation ) \
.filter( galaxy.model.UserRoleAssociation.table.c.role_id == role.id ) \
.all()
+def mark_form_deleted( form ):
+ form.current.deleted = True
+ sa_session.add( form )
+ sa_session.flush()
def refresh( obj ):
sa_session.refresh( obj )
diff -r feff604427ee -r 193e5f4e2444 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py Tue Mar 30 17:03:29 2010 -0400
+++ b/test/base/twilltestcase.py Wed Mar 31 09:42:50 2010 -0400
@@ -280,7 +280,7 @@
num_deleted = len( id.split( ',' ) )
self.home()
self.visit_page( "history/list?operation=delete&id=%s" % ( id ) )
- check_str = 'Deleted %d %s' % ( num_deleted, iff( num_deleted != 1, "histories","history") )
+ check_str = 'Deleted %d %s' % ( num_deleted, iff( num_deleted != 1, "histories", "history" ) )
self.check_page_for_string( check_str )
self.home()
def delete_current_history( self, check_str='' ):
@@ -793,41 +793,41 @@
self.assertTrue( genome_build == dbkey )
# Functions associated with user accounts
- def create( self, email='test(a)bx.psu.edu', password='testuser' ):
- self.home()
- # Create user, setting username to email.
- self.visit_page( "user/create?email=%s&username=%s&password=%s&confirm=%s&create_user_button=Submit" % ( email, email, password, password ) )
- self.check_page_for_string( "now logged in as %s" %email )
- self.home()
+ def create( self, email='test(a)bx.psu.edu', password='testuser', username='admin-user', webapp='galaxy' ):
+ # HACK: don't use panels because late_javascripts() messes up the twill browser and it
+ # can't find form fields (and hence user can't be logged in).
+ self.visit_url( "%s/user/create?use_panels=False&webapp=%s" % ( self.url, webapp ) )
+ tc.fv( '1', 'email', email )
+ tc.fv( '1', 'password', password )
+ tc.fv( '1', 'confirm', password )
+ tc.fv( '1', 'username', username )
+ tc.submit( 'create_user_button' )
+ self.check_page_for_string( "now logged in as %s" % email )
# Make sure a new private role was created for the user
- self.visit_page( "user/set_default_permissions" )
+ self.visit_url( "%s/user/set_default_permissions" % self.url )
self.check_page_for_string( email )
self.home()
def create_user_with_info( self, email, password, username, user_info_forms, user_info_form_id, user_info_values ):
'''
This method registers a new user and also provides use info
'''
- self.home()
if user_info_forms == 'multiple':
- self.visit_page( "user/create?user_info_select=%i&admin_view=False" % user_info_form_id )
+ self.visit_url( "%s/user/create?user_info_select=%i&admin_view=False&use_panels=False" % ( self.url, user_info_form_id ) )
else:
- self.visit_page( "user/create?admin_view=False" )
- print self.write_temp_file( self.last_page() )
+ self.visit_url( "%s/user/create?admin_view=False&use_panels=False" % self.url )
+ ##print self.write_temp_file( self.last_page() )
self.check_page_for_string( "Create account" )
- tc.fv( "2", "email", email )
- tc.fv( "2", "password", password )
- tc.fv( "2", "confirm", password )
- tc.fv( "2", "username", username )
+ tc.fv( "1", "email", email )
+ tc.fv( "1", "password", password )
+ tc.fv( "1", "confirm", password )
+ tc.fv( "1", "username", username )
if user_info_forms == 'multiple':
self.check_page_for_string( "User type" )
for index, info_value in enumerate(user_info_values):
- tc.fv( "2", "field_%i" % index, info_value )
+ tc.fv( "1", "field_%i" % index, info_value )
tc.submit( "create_user_button" )
- self.check_page_for_string( "ogged in as %s" % email )
def create_user_with_info_as_admin( self, email, password, username, user_info_forms, user_info_form_id, user_info_values ):
- '''
- This method registers a new user and also provides use info as an admin
- '''
+ # This method creates a new user with associated info
self.home()
if user_info_forms == 'multiple':
self.visit_page( "admin/users?operation=create?user_info_select=%i&admin_view=False" % user_info_form_id )
@@ -844,16 +844,15 @@
tc.fv( "2", "field_%i" % index, info_value )
tc.submit( "create_user_button" )
self.check_page_for_string( "Created new user account (%s)" % email )
- def edit_login_info( self, new_email, new_username ):
+ def edit_login_info( self, new_email, new_username, check_str1='' ):
self.home()
- self.visit_page( "user/show_info" )
+ self.visit_url( "%s/user/show_info" % self.url )
self.check_page_for_string( "Manage User Information" )
tc.fv( "1", "email", new_email )
tc.fv( "1", "username", new_username )
tc.submit( "login_info_button" )
- self.check_page_for_string( 'The login information has been updated with the changes' )
- self.check_page_for_string( new_email )
- self.check_page_for_string( new_username )
+ if check_str1:
+ self.check_page_for_string( check_str1 )
def change_password( self, password, new_password ):
self.home()
self.visit_page( "user/show_info" )
@@ -907,13 +906,14 @@
self.visit_url( "%s/%s" % ( self.url, url ) )
self.check_page_for_string( 'Default history permissions have been changed.' )
self.home()
- def login( self, email='test(a)bx.psu.edu', password='testuser' ):
+ def login( self, email='test(a)bx.psu.edu', password='testuser', username='admin-user', webapp='galaxy' ):
# test(a)bx.psu.edu is configured as an admin user
try:
- self.create( email=email, password=password )
+ self.create( email=email, password=password, username=username, webapp=webapp )
except:
self.home()
- # HACK: don't use panels because late_javascripts() messes up the twill browser and it can't find form fields (and hence user can't be logged in).
+ # HACK: don't use panels because late_javascripts() messes up the twill browser and it
+ # can't find form fields (and hence user can't be logged in).
self.visit_url( "%s/user/login?use_panels=False" % self.url )
tc.fv( '1', 'email', email )
tc.fv( '1', 'password', password )
@@ -1161,12 +1161,14 @@
# Dataset Security stuff
# Tests associated with users
- def create_new_account_as_admin( self, email='test4(a)bx.psu.edu', password='testuser' ):
+ def create_new_account_as_admin( self, email='test4(a)bx.psu.edu', password='testuser', username='regular-user4' ):
"""Create a new account for another user"""
- # TODO: fix this so that it uses the form rather than the following URL.
- self.home()
- self.visit_url( "%s/user/create?admin_view=True&email=%s&password=%s&confirm=%s&create_user_button=Submit&subscribe=False" \
- % ( self.url, email, password, password ) )
+ self.visit_url( "%s/user/create?admin_view=True" % self.url )
+ tc.fv( '1', 'email', email )
+ tc.fv( '1', 'password', password )
+ tc.fv( '1', 'confirm', password )
+ tc.fv( '1', 'username', username )
+ tc.submit( 'create_user_button' )
try:
self.check_page_for_string( "Created new user account" )
previously_created = False
diff -r feff604427ee -r 193e5f4e2444 test/functional/test_admin_features.py
--- a/test/functional/test_admin_features.py Tue Mar 30 17:03:29 2010 -0400
+++ b/test/functional/test_admin_features.py Wed Mar 31 09:42:50 2010 -0400
@@ -5,17 +5,17 @@
def test_000_initiate_users( self ):
"""Ensuring all required user accounts exist"""
self.logout()
- self.login( email='test1(a)bx.psu.edu' )
+ self.login( email='test1(a)bx.psu.edu', username='regular-user1' )
global regular_user1
regular_user1 = get_user( 'test1(a)bx.psu.edu' )
assert regular_user1 is not None, 'Problem retrieving user with email "test1(a)bx.psu.edu" from the database'
self.logout()
- self.login( email='test2(a)bx.psu.edu' )
+ self.login( email='test2(a)bx.psu.edu', username='regular-user2' )
global regular_user2
regular_user2 = get_user( 'test2(a)bx.psu.edu' )
assert regular_user2 is not None, 'Problem retrieving user with email "test2(a)bx.psu.edu" from the database'
self.logout()
- self.login( email='test(a)bx.psu.edu' )
+ self.login( email='test(a)bx.psu.edu', username='admin-user' )
global admin_user
admin_user = get_user( 'test(a)bx.psu.edu' )
assert admin_user is not None, 'Problem retrieving user with email "test(a)bx.psu.edu" from the database'
@@ -24,7 +24,7 @@
# Logged in as admin_user
email = 'test3(a)bx.psu.edu'
password = 'testuser'
- previously_created = self.create_new_account_as_admin( email=email, password=password )
+ previously_created = self.create_new_account_as_admin( email=email, password=password, username='regular-user3' )
# Get the user object for later tests
global regular_user3
regular_user3 = get_user( email )
diff -r feff604427ee -r 193e5f4e2444 test/functional/test_data_security.py
--- a/test/functional/test_data_security.py Tue Mar 30 17:03:29 2010 -0400
+++ b/test/functional/test_data_security.py Wed Mar 31 09:42:50 2010 -0400
@@ -5,28 +5,28 @@
def test_000_initiate_users( self ):
"""Ensuring all required user accounts exist"""
self.logout()
- self.login( email='test1(a)bx.psu.edu' )
+ self.login( email='test1(a)bx.psu.edu', username='regular-user1' )
global regular_user1
regular_user1 = get_user( 'test1(a)bx.psu.edu' )
assert regular_user1 is not None, 'Problem retrieving user with email "test1(a)bx.psu.edu" from the database'
global regular_user1_private_role
regular_user1_private_role = get_private_role( regular_user1 )
self.logout()
- self.login( email='test2(a)bx.psu.edu' )
+ self.login( email='test2(a)bx.psu.edu', username='regular-user2' )
global regular_user2
regular_user2 = get_user( 'test2(a)bx.psu.edu' )
assert regular_user2 is not None, 'Problem retrieving user with email "test2(a)bx.psu.edu" from the database'
global regular_user2_private_role
regular_user2_private_role = get_private_role( regular_user2 )
self.logout()
- self.login( email='test3(a)bx.psu.edu' )
+ self.login( email='test3(a)bx.psu.edu', username='regular-user3' )
global regular_user3
regular_user3 = get_user( 'test3(a)bx.psu.edu' )
assert regular_user3 is not None, 'Problem retrieving user with email "test3(a)bx.psu.edu" from the database'
global regular_user3_private_role
regular_user3_private_role = get_private_role( regular_user3 )
self.logout()
- self.login( email='test(a)bx.psu.edu' )
+ self.login( email='test(a)bx.psu.edu', username='admin-user' )
global admin_user
admin_user = get_user( 'test(a)bx.psu.edu' )
assert admin_user is not None, 'Problem retrieving user with email "test(a)bx.psu.edu" from the database'
diff -r feff604427ee -r 193e5f4e2444 test/functional/test_history_functions.py
--- a/test/functional/test_history_functions.py Tue Mar 30 17:03:29 2010 -0400
+++ b/test/functional/test_history_functions.py Wed Mar 31 09:42:50 2010 -0400
@@ -22,7 +22,7 @@
assert anonymous_history is not None, "Problem retrieving anonymous_history from database"
# Upload a dataset to anonymous_history so it will be set as the current history after login
self.upload_file( '1.bed', dbkey='hg18' )
- self.login( email='test1(a)bx.psu.edu' )
+ self.login( email='test1(a)bx.psu.edu', username='regular-user1' )
global regular_user1
regular_user1 = sa_session.query( galaxy.model.User ) \
.filter( galaxy.model.User.table.c.email=='test1(a)bx.psu.edu' ) \
@@ -35,21 +35,21 @@
self.login( email=regular_user1.email )
self.check_history_for_string( name )
self.logout()
- self.login( email='test2(a)bx.psu.edu' )
+ self.login( email='test2(a)bx.psu.edu', username='regular-user2' )
global regular_user2
regular_user2 = sa_session.query( galaxy.model.User ) \
.filter( galaxy.model.User.table.c.email=='test2(a)bx.psu.edu' ) \
.first()
assert regular_user2 is not None, 'Problem retrieving user with email "test2(a)bx.psu.edu" from the database'
self.logout()
- self.login( email='test3(a)bx.psu.edu' )
+ self.login( email='test3(a)bx.psu.edu', username='regular-user3' )
global regular_user3
regular_user3 = sa_session.query( galaxy.model.User ) \
.filter( galaxy.model.User.table.c.email=='test3(a)bx.psu.edu' ) \
.first()
assert regular_user3 is not None, 'Problem retrieving user with email "test3(a)bx.psu.edu" from the database'
self.logout()
- self.login( email='test(a)bx.psu.edu' )
+ self.login( email='test(a)bx.psu.edu', username='admin-user' )
global admin_user
admin_user = sa_session.query( galaxy.model.User ) \
.filter( galaxy.model.User.table.c.email=='test(a)bx.psu.edu' ) \
diff -r feff604427ee -r 193e5f4e2444 test/functional/test_library_features.py
--- a/test/functional/test_library_features.py Tue Mar 30 17:03:29 2010 -0400
+++ b/test/functional/test_library_features.py Wed Mar 31 09:42:50 2010 -0400
@@ -5,28 +5,28 @@
def test_000_initiate_users( self ):
"""Ensuring all required user accounts exist"""
self.logout()
- self.login( email='test1(a)bx.psu.edu' )
+ self.login( email='test1(a)bx.psu.edu', username='regular-user1' )
global regular_user1
regular_user1 = get_user( 'test1(a)bx.psu.edu' )
assert regular_user1 is not None, 'Problem retrieving user with email "test1(a)bx.psu.edu" from the database'
global regular_user1_private_role
regular_user1_private_role = get_private_role( regular_user1 )
self.logout()
- self.login( email='test2(a)bx.psu.edu' )
+ self.login( email='test2(a)bx.psu.edu', username='regular-user2' )
global regular_user2
regular_user2 = get_user( 'test2(a)bx.psu.edu' )
assert regular_user2 is not None, 'Problem retrieving user with email "test2(a)bx.psu.edu" from the database'
global regular_user2_private_role
regular_user2_private_role = get_private_role( regular_user2 )
self.logout()
- self.login( email='test3(a)bx.psu.edu' )
+ self.login( email='test3(a)bx.psu.edu', username='regular-user3' )
global regular_user3
regular_user3 = get_user( 'test3(a)bx.psu.edu' )
assert regular_user3 is not None, 'Problem retrieving user with email "test3(a)bx.psu.edu" from the database'
global regular_user3_private_role
regular_user3_private_role = get_private_role( regular_user3 )
self.logout()
- self.login( email='test(a)bx.psu.edu' )
+ self.login( email='test(a)bx.psu.edu', username='admin-user' )
global admin_user
admin_user = get_user( 'test(a)bx.psu.edu' )
assert admin_user is not None, 'Problem retrieving user with email "test(a)bx.psu.edu" from the database'
diff -r feff604427ee -r 193e5f4e2444 test/functional/test_library_security.py
--- a/test/functional/test_library_security.py Tue Mar 30 17:03:29 2010 -0400
+++ b/test/functional/test_library_security.py Wed Mar 31 09:42:50 2010 -0400
@@ -5,28 +5,28 @@
def test_000_initiate_users( self ):
"""Ensuring all required user accounts exist"""
self.logout()
- self.login( email='test1(a)bx.psu.edu' )
+ self.login( email='test1(a)bx.psu.edu', username='regular-user1' )
global regular_user1
regular_user1 = get_user( 'test1(a)bx.psu.edu' )
assert regular_user1 is not None, 'Problem retrieving user with email "test1(a)bx.psu.edu" from the database'
global regular_user1_private_role
regular_user1_private_role = get_private_role( regular_user1 )
self.logout()
- self.login( email='test2(a)bx.psu.edu' )
+ self.login( email='test2(a)bx.psu.edu', username='regular-user2' )
global regular_user2
regular_user2 = get_user( 'test2(a)bx.psu.edu' )
assert regular_user2 is not None, 'Problem retrieving user with email "test2(a)bx.psu.edu" from the database'
global regular_user2_private_role
regular_user2_private_role = get_private_role( regular_user2 )
self.logout()
- self.login( email='test3(a)bx.psu.edu' )
+ self.login( email='test3(a)bx.psu.edu', username='regular-user3' )
global regular_user3
regular_user3 = get_user( 'test3(a)bx.psu.edu' )
assert regular_user3 is not None, 'Problem retrieving user with email "test3(a)bx.psu.edu" from the database'
global regular_user3_private_role
regular_user3_private_role = get_private_role( regular_user3 )
self.logout()
- self.login( email='test(a)bx.psu.edu' )
+ self.login( email='test(a)bx.psu.edu', username='admin-user' )
global admin_user
admin_user = get_user( 'test(a)bx.psu.edu' )
assert admin_user is not None, 'Problem retrieving user with email "test(a)bx.psu.edu" from the database'
diff -r feff604427ee -r 193e5f4e2444 test/functional/test_metadata_editing.py
--- a/test/functional/test_metadata_editing.py Tue Mar 30 17:03:29 2010 -0400
+++ b/test/functional/test_metadata_editing.py Wed Mar 31 09:42:50 2010 -0400
@@ -8,7 +8,7 @@
def test_00_metadata_edit( self ):
"""test_metadata_edit: Testing metadata editing"""
self.logout()
- self.login( email='test(a)bx.psu.edu' )
+ self.login( email='test(a)bx.psu.edu', username='admin-user' )
admin_user = sa_session.query( galaxy.model.User ) \
.filter( galaxy.model.User.table.c.email=='test(a)bx.psu.edu' ) \
.one()
diff -r feff604427ee -r 193e5f4e2444 test/functional/test_user_info.py
--- a/test/functional/test_user_info.py Tue Mar 30 17:03:29 2010 -0400
+++ b/test/functional/test_user_info.py Wed Mar 31 09:42:50 2010 -0400
@@ -1,38 +1,55 @@
-import galaxy.model
-from galaxy.model.orm import *
-from galaxy.model.mapping import context as sa_session
from base.twilltestcase import *
+from base.test_db_util import *
not_logged_in_as_admin_security_msg = 'You must be logged in as an administrator to access this feature.'
logged_in_as_admin_security_msg = 'You must be an administrator to access this feature.'
not_logged_in_security_msg = 'You must be logged in to create/submit sequencing requests'
+global form_one_name
form_one_name = "Student"
+global form_two_name
form_two_name = "Researcher"
-def get_latest_form(form_name):
- fdc_list = sa_session.query( galaxy.model.FormDefinitionCurrent ) \
- .filter( galaxy.model.FormDefinitionCurrent.table.c.deleted==False ) \
- .order_by( galaxy.model.FormDefinitionCurrent.table.c.create_time.desc() )
- for fdc in fdc_list:
- sa_session.refresh( fdc )
- sa_session.refresh( fdc.latest_form )
- if form_name == fdc.latest_form.name:
- return fdc.latest_form
- return None
-
class TestUserInfo( TwillTestCase ):
- def test_000_create_user_info_forms( self ):
+ def test_000_initiate_users( self ):
+ """Ensuring all required user accounts exist"""
+ self.logout()
+ self.login( email='test1(a)bx.psu.edu', username='regular-user1' )
+ global regular_user1
+ regular_user1 = get_user( 'test1(a)bx.psu.edu' )
+ assert regular_user1 is not None, 'Problem retrieving user with email "test1(a)bx.psu.edu" from the database'
+ global regular_user1_private_role
+ regular_user1_private_role = get_private_role( regular_user1 )
+ self.logout()
+ self.login( email='test2(a)bx.psu.edu', username='regular-user2' )
+ global regular_user2
+ regular_user2 = get_user( 'test2(a)bx.psu.edu' )
+ assert regular_user2 is not None, 'Problem retrieving user with email "test2(a)bx.psu.edu" from the database'
+ global regular_user2_private_role
+ regular_user2_private_role = get_private_role( regular_user2 )
+ self.logout()
+ self.login( email='test3(a)bx.psu.edu', username='regular-user3' )
+ global regular_user3
+ regular_user3 = get_user( 'test3(a)bx.psu.edu' )
+ assert regular_user3 is not None, 'Problem retrieving user with email "test3(a)bx.psu.edu" from the database'
+ global regular_user3_private_role
+ regular_user3_private_role = get_private_role( regular_user3 )
+ self.logout()
+ self.login( email='test(a)bx.psu.edu', username='admin-user' )
+ global admin_user
+ admin_user = get_user( 'test(a)bx.psu.edu' )
+ assert admin_user is not None, 'Problem retrieving user with email "test(a)bx.psu.edu" from the database'
+ global admin_user_private_role
+ admin_user_private_role = get_private_role( admin_user )
+ def test_005_create_user_info_forms( self ):
"""Testing creating a new user info form and editing it"""
- self.logout()
- self.login( email='test(a)bx.psu.edu' )
- # create a the first form
- global form_one_name
+ # Logged in as admin_user
+ # Create a the first form
name = form_one_name
desc = "This is Student user info form's description"
- formtype = galaxy.model.FormDefinition.types.USER_INFO
+ formtype = get_user_info_form_definition()
self.create_form( name=name, desc=desc, formtype=formtype, num_fields=0 )
# Get the form_definition object for later tests
- form_one = get_latest_form(form_one_name)
+ form_one = get_form( form_one_name )
assert form_one is not None, 'Problem retrieving form named "%s" from the database' % name
# edit form & add few more fields
fields = [dict(name='Affiliation',
@@ -48,17 +65,20 @@
desc='',
type='CheckboxField',
required='optional')]
- form_one = get_latest_form(form_one_name)
- self.form_add_field(form_one.current.id, form_one.name, form_one.desc, form_one.type, field_index=len(form_one.fields), fields=fields)
- form_one_latest = get_latest_form(form_one_name)
- assert len(form_one_latest.fields) == len(form_one.fields)+len(fields)
+ self.form_add_field( form_one.current.id,
+ form_one.name,
+ form_one.desc,
+ form_one.type,
+ field_index=len( form_one.fields ),
+ fields=fields)
+ form_one_latest = get_form( form_one_name )
+ assert len( form_one_latest.fields ) == len( form_one.fields ) + len( fields )
# create the second form
- global form_two_name
name = form_two_name
desc = "This is Researcher user info form's description"
self.create_form( name=name, desc=desc, formtype=formtype, num_fields=0 )
# Get the form_definition object for later tests
- form_two = get_latest_form(form_two_name)
+ form_two = get_form( form_two_name )
assert form_two is not None, 'Problem retrieving form named "%s" from the database' % name
# edit form & add few more fields
fields = [dict(name='Affiliation',
@@ -74,94 +94,117 @@
desc='',
type='CheckboxField',
required='optional')]
- form_two = get_latest_form(form_two_name)
- self.form_add_field(form_two.current.id, form_two.name, form_two.desc, form_two.type, field_index=len(form_one.fields), fields=fields)
- form_two_latest = get_latest_form(form_two_name)
- assert len(form_two_latest.fields) == len(form_two.fields)+len(fields)
- def test_005_user_reqistration_multiple_user_info_forms( self ):
+ self.form_add_field( form_two.current.id,
+ form_two.name,
+ form_two.desc,
+ form_two.type,
+ field_index=len( form_one.fields ),
+ fields=fields )
+ form_two_latest = get_form( form_two_name )
+ assert len( form_two_latest.fields ) == len( form_two.fields ) + len( fields )
+ def test_010_user_reqistration_multiple_user_info_forms( self ):
''' Testing user registration with multiple user info forms '''
+ # Logged in as admin_user
self.logout()
- # user a new user with 'Student' user info form
- form_one = get_latest_form(form_one_name)
+ # Create a new user with 'Student' user info form
+ form_one = get_form(form_one_name)
user_info_values=['Educational', 'Penn State', True]
- self.create_user_with_info( 'test11(a)bx.psu.edu', 'testuser', 'test11',
+ self.create_user_with_info( 'test11(a)bx.psu.edu',
+ 'testuser',
+ 'test11',
user_info_forms='multiple',
user_info_form_id=form_one.id,
user_info_values=user_info_values )
- self.home()
- self.visit_page( "user/show_info" )
+ global regular_user11
+ regular_user11 = get_user( 'test11(a)bx.psu.edu' )
+ assert regular_user11 is not None, 'Problem retrieving user with email "test11(a)bx.psu.edu" from the database'
+ global regular_user11_private_role
+ regular_user11_private_role = get_private_role( regular_user11 )
+ self.logout()
+ self.login( email=regular_user11.email, username='regular-user11' )
+ self.visit_url( "%s/user/show_info" % self.url )
self.check_page_for_string( "Manage User Information" )
self.check_page_for_string( user_info_values[0] )
self.check_page_for_string( user_info_values[1] )
self.check_page_for_string( '<input type="checkbox" name="field_2" value="true" checked>' )
- def test_010_user_reqistration_single_user_info_forms( self ):
+ def test_015_user_reqistration_single_user_info_forms( self ):
''' Testing user registration with a single user info form '''
- # lets delete the 'Researcher' user info form
- self.login( 'test(a)bx.psu.edu' )
- form_two_latest = get_latest_form(form_two_name)
- form_two_latest.current.deleted = True
- sa_session.add( form_two_latest.current )
- sa_session.flush()
- self.home()
- self.visit_page('forms/manage?sort=create_time&f-deleted=True')
- self.check_page_for_string(form_two_latest.name)
+ # Logged in as regular_user_11
self.logout()
- # user a new user with 'Student' user info form
- form_one = get_latest_form(form_one_name)
+ self.login( email=admin_user.email )
+ # Delete the 'Researcher' user info form
+ form_two_latest = get_form( form_two_name )
+ mark_form_deleted( form_two_latest )
+ self.visit_url( '%s/forms/manage?sort=create_time&f-deleted=True' % self.url )
+ self.check_page_for_string( form_two_latest.name )
+ # Create a new user with 'Student' user info form
+ form_one = get_form( form_one_name )
user_info_values=['Educational', 'Penn State', True]
self.create_user_with_info( 'test12(a)bx.psu.edu', 'testuser', 'test12',
user_info_forms='single',
user_info_form_id=form_one.id,
user_info_values=user_info_values )
- self.home()
- self.visit_page( "user/show_info" )
+ global regular_user12
+ regular_user12 = get_user( 'test12(a)bx.psu.edu' )
+ assert regular_user12 is not None, 'Problem retrieving user with email "test12(a)bx.psu.edu" from the database'
+ global regular_user12_private_role
+ regular_user12_private_role = get_private_role( regular_user12 )
+ self.logout()
+ self.login( email=regular_user12.email, username='regular-user12' )
+ self.visit_url( "%s/user/show_info" % self.url )
self.check_page_for_string( "Manage User Information" )
self.check_page_for_string( user_info_values[0] )
self.check_page_for_string( user_info_values[1] )
self.check_page_for_string( '<input type="checkbox" name="field_2" value="true" checked>' )
- def test_015_edit_user_info( self ):
+ def test_020_edit_user_info( self ):
"""Testing editing user info as a regular user"""
- self.logout()
- self.login( 'test11(a)bx.psu.edu' )
- user = sa_session.query( galaxy.model.User ) \
- .filter( and_( galaxy.model.User.table.c.email=='test11(a)bx.psu.edu' ) ).first()
- self.edit_login_info( new_email='test11_new(a)bx.psu.edu', new_username='test11_new' )
+ # Logged in as regular_user_12
+ # Test changing email and user name - first try an invalid user name
+ self.edit_login_info( new_email='test12_new(a)bx.psu.edu',
+ new_username='test12_new',
+ check_str1='User name must contain only letters, numbers and' )
+ # Now try a valid user name
+ self.edit_login_info( new_email='test12_new(a)bx.psu.edu',
+ new_username='test12-new',
+ check_str1='The login information has been updated with the changes' )
+ # Since we changed the user's account. make sure the user's private role was changed accordingly
+ if not get_private_role( regular_user12 ):
+ raise AssertionError, "The private role for %s was not correctly set when their account (email) was changed" % regular_user12.email
+ # Test changing password
self.change_password( 'testuser', 'testuser#' )
self.logout()
- self.login( email='test11_new(a)bx.psu.edu', password='testuser#' )
- self.edit_login_info( new_email='test11(a)bx.psu.edu', new_username='test11' )
- self.change_password( 'testuser#', 'testuser' )
+ refresh( regular_user12 )
+ # Test logging in with new email and password
+ self.login( email=regular_user12.email, password='testuser#' )
+ # Test editing the user info
self.edit_user_info( ['Research', 'PSU'] )
- def test_020_create_user_as_admin( self ):
- ''' Testing creating users as an admin '''
+ def test_999_reset_data_for_later_test_runs( self ):
+ # Logged in as regular_user_12
self.logout()
- self.login( 'test(a)bx.psu.edu' )
- form_one = get_latest_form(form_one_name)
- user_info_values=['Educational', 'Penn State', True]
- self.create_user_with_info( 'test13(a)bx.psu.edu', 'testuser', 'test13',
- user_info_forms='single',
- user_info_form_id=form_one.id,
- user_info_values=user_info_values )
- self.logout()
- self.login( 'test(a)bx.psu.edu' )
- user = sa_session.query( galaxy.model.User ) \
- .filter( and_( galaxy.model.User.table.c.email=='test13(a)bx.psu.edu' ) ).first()
- self.home()
- page = "admin/users?id=%s&operation=information&f-deleted=False" % self.security.encode_id( user.id )
- self.visit_page( page )
- self.check_page_for_string( 'Manage User Information' )
- self.check_page_for_string( 'test13(a)bx.psu.edu' )
- self.check_page_for_string( user_info_values[0] )
- self.check_page_for_string( user_info_values[1] )
- self.check_page_for_string( '<input type="checkbox" name="field_2" value="true" checked>' )
- # lets delete the 'Student' user info form
- self.login( 'test(a)bx.psu.edu' )
- form_one_latest = get_latest_form(form_one_name)
- form_one_latest.current.deleted = True
- sa_session.add( form_one_latest.current )
- sa_session.flush()
- self.home()
- self.visit_page('forms/manage?sort=create_time&f-deleted=True')
- self.check_page_for_string(form_one_latest.name)
- self.logout()
-
+ self.login( email=admin_user.email )
+ ###############
+ # Mark form_one as deleted ( form_two was marked deleted earlier )
+ ###############
+ form_latest = get_form( form_one_name )
+ mark_form_deleted( form_latest )
+ ###############
+ # Manually delete the test_user11
+ ###############
+ self.mark_user_deleted( user_id=self.security.encode_id( regular_user11.id ), email=regular_user11.email )
+ refresh( regular_user11 )
+ self.purge_user( self.security.encode_id( regular_user11.id ), regular_user11.email )
+ refresh( regular_user11 )
+ # We should now only the the user and his private role
+ delete_user_roles( regular_user11 )
+ delete_obj( regular_user11 )
+ ###############
+ # Manually delete the test_user12
+ ###############
+ refresh( regular_user12 )
+ self.mark_user_deleted( user_id=self.security.encode_id( regular_user12.id ), email=regular_user12.email )
+ refresh( regular_user12 )
+ self.purge_user( self.security.encode_id( regular_user12.id ), regular_user12.email )
+ refresh( regular_user12 )
+ # We should now only the the user and his private role
+ delete_user_roles( regular_user12 )
+ delete_obj( regular_user12 )
1
0