2 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/bc56358a5c51/ changeset: bc56358a5c51 user: jgoecks date: 2012-09-14 20:40:53 summary: Visualization framework: (a) put summary tree back in tracks module because pickling requires it not move modules and (b) move grids from tracks controller to visualization controller. affected #: 14 files diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/datatypes/converters/interval_to_interval_index_converter.py --- a/lib/galaxy/datatypes/converters/interval_to_interval_index_converter.py +++ b/lib/galaxy/datatypes/converters/interval_to_interval_index_converter.py @@ -14,7 +14,7 @@ import sys, fileinput, optparse from galaxy import eggs import pkg_resources; pkg_resources.require( "bx-python" ) -from galaxy.visualization.genome.summary import * +from galaxy.visualization.tracks.summary import * from galaxy.datatypes.util.gff_util import convert_gff_coords_to_bed from bx.interval_index_file import Indexes diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py --- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py +++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py @@ -15,7 +15,7 @@ import sys, fileinput, optparse from galaxy import eggs import pkg_resources; pkg_resources.require( "bx-python" ) -from galaxy.visualization.genome.summary import * +from galaxy.visualization.tracks.summary import * from bx.intervals.io import * from galaxy.datatypes.util.gff_util import * diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/datatypes/converters/sam_or_bam_to_summary_tree_converter.py --- a/lib/galaxy/datatypes/converters/sam_or_bam_to_summary_tree_converter.py +++ b/lib/galaxy/datatypes/converters/sam_or_bam_to_summary_tree_converter.py @@ -14,7 +14,7 @@ pkg_resources.require( "pysam" ) from pysam import csamtools -from galaxy.visualization.genome.summary import * +from galaxy.visualization.tracks.summary import * def main(): parser = optparse.OptionParser() diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/datatypes/converters/vcf_to_summary_tree_converter.py --- a/lib/galaxy/datatypes/converters/vcf_to_summary_tree_converter.py +++ b/lib/galaxy/datatypes/converters/vcf_to_summary_tree_converter.py @@ -9,7 +9,7 @@ import optparse import galaxy_utils.sequence.vcf -from galaxy.visualization.genome.summary import SummaryTree +from galaxy.visualization.tracks.summary import SummaryTree def main(): # Read options, args. diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/visualization/genome/data_providers.py --- a/lib/galaxy/visualization/genome/data_providers.py +++ b/lib/galaxy/visualization/genome/data_providers.py @@ -16,7 +16,7 @@ from bx.interval_index_file import Indexes from bx.bbi.bigwig_file import BigWigFile from galaxy.util.lrucache import LRUCache -from galaxy.visualization.genome.summary import * +from galaxy.visualization.tracks.summary import * from galaxy.visualization.data_providers import BaseDataProvider import galaxy_utils.sequence.vcf from galaxy.datatypes.tabular import Tabular, Vcf diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/visualization/genome/summary.py --- a/lib/galaxy/visualization/genome/summary.py +++ /dev/null @@ -1,111 +0,0 @@ -''' -Summary tree data structure for feature aggregation across large genomic regions. -''' - -import sys, os -import cPickle - -# TODO: What are the performance implications of setting min level to 1? Data -# structure size and/or query speed? It would be nice to have level 1 data -# so that client does not have to compute it. -MIN_LEVEL = 2 - -class SummaryTree: - def __init__( self, block_size=25, levels=6, draw_cutoff=150, detail_cutoff=30 ): - self.chrom_blocks = {} - self.levels = levels - self.draw_cutoff = draw_cutoff - self.detail_cutoff = detail_cutoff - self.block_size = block_size - self.chrom_stats = {} - - def find_block( self, num, level ): - """ Returns block that num is in for level. """ - return ( num / self.block_size ** level ) - - def insert_range( self, chrom, start, end ): - """ Inserts a feature at chrom:start-end into the tree. """ - - # Get or set up chrom blocks. - if chrom in self.chrom_blocks: - blocks = self.chrom_blocks[ chrom ] - else: - blocks = self.chrom_blocks[ chrom ] = {} - self.chrom_stats[ chrom ] = {} - for level in range( MIN_LEVEL, self.levels + 1 ): - blocks[ level ] = {} - - # Insert feature into all matching blocks at all levels. - for level in range( MIN_LEVEL, self.levels + 1 ): - block_level = blocks[ level ] - starting_block = self.find_block( start, level ) - ending_block = self.find_block( end, level ) - for block in range( starting_block, ending_block + 1 ): - if block in block_level: - block_level[ block ] += 1 - else: - block_level[ block ] = 1 - - def finish( self ): - """ Compute stats for levels. """ - - for chrom, blocks in self.chrom_blocks.iteritems(): - for level in range( self.levels, MIN_LEVEL - 1, -1 ): - # Set level's stats. - max_val = max( blocks[ level ].values() ) - self.chrom_stats[ chrom ][ level ] = {} - self.chrom_stats[ chrom ][ level ][ "delta" ] = self.block_size ** level - self.chrom_stats[ chrom ][ level ][ "max" ] = max_val - self.chrom_stats[ chrom ][ level ][ "avg" ] = float( max_val ) / len( blocks[ level ] ) - - self.chrom_blocks[ chrom ] = dict( [ ( key, value ) for key, value in blocks.iteritems() ] ) - - def query( self, chrom, start, end, level, draw_cutoff=None, detail_cutoff=None ): - """ Queries tree for data. """ - - # Set cutoffs to self's attributes if not defined. - if draw_cutoff != 0: - draw_cutoff = self.draw_cutoff - if detail_cutoff != 0: - detail_cutoff = self.detail_cutoff - - # Get data. - if chrom in self.chrom_blocks: - stats = self.chrom_stats[ chrom ] - - # For backwards compatibility: - if "detail_level" in stats and level <= stats[ "detail_level" ]: - return "detail" - elif "draw_level" in stats and level <= stats[ "draw_level" ]: - return "draw" - - # If below draw, detail level, return string to denote this. - max = stats[ level ][ "max" ] - if max < detail_cutoff: - return "detail" - if max < draw_cutoff: - return "draw" - - # Return block data. - blocks = self.chrom_blocks[ chrom ] - results = [] - multiplier = self.block_size ** level - starting_block = self.find_block( start, level ) - ending_block = self.find_block( end, level ) - for block in range( starting_block, ending_block + 1 ): - val = 0 - if block in blocks[ level ]: - val = blocks[ level ][ block ] - results.append( ( block * multiplier, val ) ) - return results - - return None - - def write( self, filename ): - """ Writes tree to file. """ - self.finish() - cPickle.dump( self, open( filename, 'wb' ), 2 ) - -def summary_tree_from_file( filename ): - return cPickle.load( open( filename, "rb" ) ) - diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/visualization/tracks/__init__.py --- /dev/null +++ b/lib/galaxy/visualization/tracks/__init__.py @@ -0,0 +1,1 @@ +""" Summary.py required to be in this module due to pickling. """ \ No newline at end of file diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/visualization/tracks/summary.py --- /dev/null +++ b/lib/galaxy/visualization/tracks/summary.py @@ -0,0 +1,111 @@ +''' +Summary tree data structure for feature aggregation across large genomic regions. +''' + +import sys, os +import cPickle + +# TODO: What are the performance implications of setting min level to 1? Data +# structure size and/or query speed? It would be nice to have level 1 data +# so that client does not have to compute it. +MIN_LEVEL = 2 + +class SummaryTree: + def __init__( self, block_size=25, levels=6, draw_cutoff=150, detail_cutoff=30 ): + self.chrom_blocks = {} + self.levels = levels + self.draw_cutoff = draw_cutoff + self.detail_cutoff = detail_cutoff + self.block_size = block_size + self.chrom_stats = {} + + def find_block( self, num, level ): + """ Returns block that num is in for level. """ + return ( num / self.block_size ** level ) + + def insert_range( self, chrom, start, end ): + """ Inserts a feature at chrom:start-end into the tree. """ + + # Get or set up chrom blocks. + if chrom in self.chrom_blocks: + blocks = self.chrom_blocks[ chrom ] + else: + blocks = self.chrom_blocks[ chrom ] = {} + self.chrom_stats[ chrom ] = {} + for level in range( MIN_LEVEL, self.levels + 1 ): + blocks[ level ] = {} + + # Insert feature into all matching blocks at all levels. + for level in range( MIN_LEVEL, self.levels + 1 ): + block_level = blocks[ level ] + starting_block = self.find_block( start, level ) + ending_block = self.find_block( end, level ) + for block in range( starting_block, ending_block + 1 ): + if block in block_level: + block_level[ block ] += 1 + else: + block_level[ block ] = 1 + + def finish( self ): + """ Compute stats for levels. """ + + for chrom, blocks in self.chrom_blocks.iteritems(): + for level in range( self.levels, MIN_LEVEL - 1, -1 ): + # Set level's stats. + max_val = max( blocks[ level ].values() ) + self.chrom_stats[ chrom ][ level ] = {} + self.chrom_stats[ chrom ][ level ][ "delta" ] = self.block_size ** level + self.chrom_stats[ chrom ][ level ][ "max" ] = max_val + self.chrom_stats[ chrom ][ level ][ "avg" ] = float( max_val ) / len( blocks[ level ] ) + + self.chrom_blocks[ chrom ] = dict( [ ( key, value ) for key, value in blocks.iteritems() ] ) + + def query( self, chrom, start, end, level, draw_cutoff=None, detail_cutoff=None ): + """ Queries tree for data. """ + + # Set cutoffs to self's attributes if not defined. + if draw_cutoff != 0: + draw_cutoff = self.draw_cutoff + if detail_cutoff != 0: + detail_cutoff = self.detail_cutoff + + # Get data. + if chrom in self.chrom_blocks: + stats = self.chrom_stats[ chrom ] + + # For backwards compatibility: + if "detail_level" in stats and level <= stats[ "detail_level" ]: + return "detail" + elif "draw_level" in stats and level <= stats[ "draw_level" ]: + return "draw" + + # If below draw, detail level, return string to denote this. + max = stats[ level ][ "max" ] + if max < detail_cutoff: + return "detail" + if max < draw_cutoff: + return "draw" + + # Return block data. + blocks = self.chrom_blocks[ chrom ] + results = [] + multiplier = self.block_size ** level + starting_block = self.find_block( start, level ) + ending_block = self.find_block( end, level ) + for block in range( starting_block, ending_block + 1 ): + val = 0 + if block in blocks[ level ]: + val = blocks[ level ][ block ] + results.append( ( block * multiplier, val ) ) + return results + + return None + + def write( self, filename ): + """ Writes tree to file. """ + self.finish() + cPickle.dump( self, open( filename, 'wb' ), 2 ) + +def summary_tree_from_file( filename ): + return cPickle.load( open( filename, "rb" ) ) + diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/web/controllers/tracks.py --- a/lib/galaxy/web/controllers/tracks.py +++ b/lib/galaxy/web/controllers/tracks.py @@ -8,7 +8,6 @@ from galaxy import model from galaxy.util.json import to_json_string, from_json_string from galaxy.web.base.controller import * -from galaxy.web.controllers.library import LibraryListGrid from galaxy.web.framework import simplejson from galaxy.web.framework.helpers import time_ago, grids from galaxy.util.bunch import Bunch @@ -16,152 +15,13 @@ from galaxy.model import NoConverterException, ConverterDependencyException from galaxy.visualization.genome.data_providers import * from galaxy.visualization.genomes import decode_dbkey, Genomes -from galaxy.visualization.genome.visual_analytics import get_dataset_job - - -class NameColumn( grids.TextColumn ): - def get_value( self, trans, grid, history ): - return history.get_display_name() - def get_link( self, trans, grid, history ): - # Provide link to list all datasets in history that have a given dbkey. - # Right now, only dbkey needs to be passed through, but pass through - # all for now since it's cleaner. - d = dict( action=grid.datasets_action, show_item_checkboxes=True ) - d[ grid.datasets_param ] = trans.security.encode_id( history.id ) - for filter, value in grid.cur_filter_dict.iteritems(): - d[ "f-" + filter ] = value - return d - -class DbKeyPlaceholderColumn( grids.GridColumn ): - """ Placeholder to keep track of dbkey. """ - def filter( self, trans, user, query, dbkey ): - return query - -class HistorySelectionGrid( grids.Grid ): - """ - Grid enables user to select a history, which is then used to display - datasets from the history. - """ - title = "Add Track: Select History" - model_class = model.History - template='/tracks/history_select_grid.mako' - default_sort_key = "-update_time" - datasets_action = 'list_history_datasets' - datasets_param = "f-history" - columns = [ - NameColumn( "History Name", key="name", filterable="standard" ), - grids.GridColumn( "Last Updated", key="update_time", format=time_ago, visible=False ), - DbKeyPlaceholderColumn( "Dbkey", key="dbkey", model_class=model.HistoryDatasetAssociation, visible=False ) - ] - num_rows_per_page = 10 - use_async = True - use_paging = True - def apply_query_filter( self, trans, query, **kwargs ): - return query.filter_by( user=trans.user, purged=False, deleted=False, importing=False ) - -class LibrarySelectionGrid( LibraryListGrid ): - """ - Grid enables user to select a Library, which is then used to display - datasets from the history. - """ - title = "Add Track: Select Library" - template='/tracks/history_select_grid.mako' - model_class = model.Library - datasets_action = 'list_library_datasets' - datasets_param = "f-library" - columns = [ - NameColumn( "Library Name", key="name", filterable="standard" ) - ] - num_rows_per_page = 10 - use_async = True - use_paging = True - -class DbKeyColumn( grids.GridColumn ): - """ Column for filtering by and displaying dataset dbkey. """ - def filter( self, trans, user, query, dbkey ): - """ Filter by dbkey; datasets without a dbkey are returned as well. """ - # use raw SQL b/c metadata is a BLOB - dbkey_user, dbkey = decode_dbkey( dbkey ) - dbkey = dbkey.replace("'", "\\'") - return query.filter( or_( \ - or_( "metadata like '%%\"dbkey\": [\"%s\"]%%'" % dbkey, "metadata like '%%\"dbkey\": \"%s\"%%'" % dbkey ), \ - or_( "metadata like '%%\"dbkey\": [\"?\"]%%'", "metadata like '%%\"dbkey\": \"?\"%%'" ) \ - ) - ) - -class HistoryColumn( grids.GridColumn ): - """ Column for filtering by history id. """ - def filter( self, trans, user, query, history_id ): - return query.filter( model.History.id==trans.security.decode_id(history_id) ) - -class HistoryDatasetsSelectionGrid( grids.Grid ): - # Grid definition. - available_tracks = None - title = "Add Datasets" - template = "tracks/history_datasets_select_grid.mako" - model_class = model.HistoryDatasetAssociation - default_filter = { "deleted" : "False" , "shared" : "All" } - default_sort_key = "-hid" - use_async = True - use_paging = False - columns = [ - grids.GridColumn( "Id", key="hid" ), - grids.TextColumn( "Name", key="name", model_class=model.HistoryDatasetAssociation ), - grids.TextColumn( "Filetype", key="extension", model_class=model.HistoryDatasetAssociation ), - HistoryColumn( "History", key="history", visible=False ), - DbKeyColumn( "Dbkey", key="dbkey", model_class=model.HistoryDatasetAssociation, visible=True, sortable=False ) - ] - columns.append( - grids.MulticolFilterColumn( "Search name and filetype", cols_to_filter=[ columns[1], columns[2] ], - key="free-text-search", visible=False, filterable="standard" ) - ) - - def get_current_item( self, trans, **kwargs ): - """ - Current item for grid is the history being queried. This is a bit - of hack since current_item typically means the current item in the grid. - """ - return model.History.get( trans.security.decode_id( kwargs[ 'f-history' ] ) ) - def build_initial_query( self, trans, **kwargs ): - return trans.sa_session.query( self.model_class ).join( model.History.table ).join( model.Dataset.table ) - def apply_query_filter( self, trans, query, **kwargs ): - if self.available_tracks is None: - self.available_tracks = trans.app.datatypes_registry.get_available_tracks() - return query.filter( model.HistoryDatasetAssociation.extension.in_(self.available_tracks) ) \ - .filter( model.Dataset.state == model.Dataset.states.OK ) \ - .filter( model.HistoryDatasetAssociation.deleted == False ) \ - .filter( model.HistoryDatasetAssociation.visible == True ) - -class TracksterSelectionGrid( grids.Grid ): - # Grid definition. - title = "Insert into visualization" - template = "/tracks/add_to_viz.mako" - async_template = "/page/select_items_grid_async.mako" - model_class = model.Visualization - default_sort_key = "-update_time" - use_async = True - use_paging = False - columns = [ - grids.TextColumn( "Title", key="title", model_class=model.Visualization, filterable="standard" ), - grids.TextColumn( "Dbkey", key="dbkey", model_class=model.Visualization ), - grids.GridColumn( "Last Updated", key="update_time", format=time_ago ) - ] - - def build_initial_query( self, trans, **kwargs ): - return trans.sa_session.query( self.model_class ).filter( self.model_class.deleted == False ) - def apply_query_filter( self, trans, query, **kwargs ): - return query.filter( self.model_class.user_id == trans.user.id ) +from galaxy.visualization.genome.visual_analytics import get_dataset_job class TracksController( BaseUIController, UsesVisualizationMixin, UsesHistoryDatasetAssociationMixin, SharableMixin ): """ Controller for track browser interface. Handles building a new browser from datasets in the current history, and display of the resulting browser. """ - - libraries_grid = LibrarySelectionGrid() - histories_grid = HistorySelectionGrid() - history_datasets_grid = HistoryDatasetsSelectionGrid() - tracks_grid = TracksterSelectionGrid() @web.expose @web.require_login() @@ -441,70 +301,7 @@ result = data_provider.get_data( chrom, int( low ), int( high ), int( start_val ), int( max_vals ), **kwargs ) result.update( { 'dataset_type': tracks_dataset_type, 'extra_info': extra_info } ) return result - - @web.expose - @web.require_login( "see all available libraries" ) - def list_libraries( self, trans, **kwargs ): - """List all libraries that can be used for selecting datasets.""" - - # Render the list view - return self.libraries_grid( trans, **kwargs ) - - @web.expose - @web.require_login( "see a library's datasets that can added to this visualization" ) - def list_library_datasets( self, trans, **kwargs ): - """List a library's datasets that can be added to a visualization.""" - - library = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( kwargs.get('f-library') ) ) - return trans.fill_template( '/tracks/library_datasets_select_grid.mako', - cntrller="library", - use_panels=False, - library=library, - created_ldda_ids='', - hidden_folder_ids='', - show_deleted=False, - comptypes=[], - current_user_roles=trans.get_current_user_roles(), - message='', - status="done" ) - - @web.expose - @web.require_login( "see all available histories" ) - def list_histories( self, trans, **kwargs ): - """List all histories that can be used for selecting datasets.""" - - # Render the list view - return self.histories_grid( trans, **kwargs ) - - @web.expose - @web.require_login( "see current history's datasets that can added to this visualization" ) - def list_current_history_datasets( self, trans, **kwargs ): - """ List a history's datasets that can be added to a visualization. """ - - kwargs[ 'f-history' ] = trans.security.encode_id( trans.get_history().id ) - kwargs[ 'show_item_checkboxes' ] = 'True' - return self.list_history_datasets( trans, **kwargs ) - - @web.expose - @web.require_login( "see a history's datasets that can added to this visualization" ) - def list_history_datasets( self, trans, **kwargs ): - """List a history's datasets that can be added to a visualization.""" - - # Render the list view - return self.history_datasets_grid( trans, **kwargs ) - - @web.expose - @web.require_login( "see all available datasets" ) - def list_datasets( self, trans, **kwargs ): - """List all datasets that can be added as tracks""" - - # Render the list view - return self.data_grid( trans, **kwargs ) - - @web.expose - def list_tracks( self, trans, **kwargs ): - return self.tracks_grid( trans, **kwargs ) - + @web.expose def sweepster( self, trans, id=None, hda_ldda=None, dataset_id=None, regions=None ): """ diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 lib/galaxy/web/controllers/visualization.py --- a/lib/galaxy/web/controllers/visualization.py +++ b/lib/galaxy/web/controllers/visualization.py @@ -3,6 +3,145 @@ from galaxy.web.base.controller import * from galaxy.web.framework.helpers import time_ago, grids, iff from galaxy.util.sanitize_html import sanitize_html +from galaxy.web.controllers.library import LibraryListGrid +from galaxy.visualization.genomes import decode_dbkey + +# +# -- Grids -- +# + +class NameColumn( grids.TextColumn ): + def get_value( self, trans, grid, history ): + return history.get_display_name() + def get_link( self, trans, grid, history ): + # Provide link to list all datasets in history that have a given dbkey. + # Right now, only dbkey needs to be passed through, but pass through + # all for now since it's cleaner. + d = dict( action=grid.datasets_action, show_item_checkboxes=True ) + d[ grid.datasets_param ] = trans.security.encode_id( history.id ) + for filter, value in grid.cur_filter_dict.iteritems(): + d[ "f-" + filter ] = value + return d + +class DbKeyPlaceholderColumn( grids.GridColumn ): + """ Placeholder to keep track of dbkey. """ + def filter( self, trans, user, query, dbkey ): + return query + +class HistorySelectionGrid( grids.Grid ): + """ + Grid enables user to select a history, which is then used to display + datasets from the history. + """ + title = "Add Track: Select History" + model_class = model.History + template='/tracks/history_select_grid.mako' + default_sort_key = "-update_time" + datasets_action = 'list_history_datasets' + datasets_param = "f-history" + columns = [ + NameColumn( "History Name", key="name", filterable="standard" ), + grids.GridColumn( "Last Updated", key="update_time", format=time_ago, visible=False ), + DbKeyPlaceholderColumn( "Dbkey", key="dbkey", model_class=model.HistoryDatasetAssociation, visible=False ) + ] + num_rows_per_page = 10 + use_async = True + use_paging = True + def apply_query_filter( self, trans, query, **kwargs ): + return query.filter_by( user=trans.user, purged=False, deleted=False, importing=False ) + +class LibrarySelectionGrid( LibraryListGrid ): + """ + Grid enables user to select a Library, which is then used to display + datasets from the history. + """ + title = "Add Track: Select Library" + template='/tracks/history_select_grid.mako' + model_class = model.Library + datasets_action = 'list_library_datasets' + datasets_param = "f-library" + columns = [ + NameColumn( "Library Name", key="name", filterable="standard" ) + ] + num_rows_per_page = 10 + use_async = True + use_paging = True + +class DbKeyColumn( grids.GridColumn ): + """ Column for filtering by and displaying dataset dbkey. """ + def filter( self, trans, user, query, dbkey ): + """ Filter by dbkey; datasets without a dbkey are returned as well. """ + # use raw SQL b/c metadata is a BLOB + dbkey_user, dbkey = decode_dbkey( dbkey ) + dbkey = dbkey.replace("'", "\\'") + return query.filter( or_( \ + or_( "metadata like '%%\"dbkey\": [\"%s\"]%%'" % dbkey, "metadata like '%%\"dbkey\": \"%s\"%%'" % dbkey ), \ + or_( "metadata like '%%\"dbkey\": [\"?\"]%%'", "metadata like '%%\"dbkey\": \"?\"%%'" ) \ + ) + ) + +class HistoryColumn( grids.GridColumn ): + """ Column for filtering by history id. """ + def filter( self, trans, user, query, history_id ): + return query.filter( model.History.id==trans.security.decode_id(history_id) ) + +class HistoryDatasetsSelectionGrid( grids.Grid ): + # Grid definition. + available_tracks = None + title = "Add Datasets" + template = "tracks/history_datasets_select_grid.mako" + model_class = model.HistoryDatasetAssociation + default_filter = { "deleted" : "False" , "shared" : "All" } + default_sort_key = "-hid" + use_async = True + use_paging = False + columns = [ + grids.GridColumn( "Id", key="hid" ), + grids.TextColumn( "Name", key="name", model_class=model.HistoryDatasetAssociation ), + grids.TextColumn( "Filetype", key="extension", model_class=model.HistoryDatasetAssociation ), + HistoryColumn( "History", key="history", visible=False ), + DbKeyColumn( "Dbkey", key="dbkey", model_class=model.HistoryDatasetAssociation, visible=True, sortable=False ) + ] + columns.append( + grids.MulticolFilterColumn( "Search name and filetype", cols_to_filter=[ columns[1], columns[2] ], + key="free-text-search", visible=False, filterable="standard" ) + ) + + def get_current_item( self, trans, **kwargs ): + """ + Current item for grid is the history being queried. This is a bit + of hack since current_item typically means the current item in the grid. + """ + return model.History.get( trans.security.decode_id( kwargs[ 'f-history' ] ) ) + def build_initial_query( self, trans, **kwargs ): + return trans.sa_session.query( self.model_class ).join( model.History.table ).join( model.Dataset.table ) + def apply_query_filter( self, trans, query, **kwargs ): + if self.available_tracks is None: + self.available_tracks = trans.app.datatypes_registry.get_available_tracks() + return query.filter( model.HistoryDatasetAssociation.extension.in_(self.available_tracks) ) \ + .filter( model.Dataset.state == model.Dataset.states.OK ) \ + .filter( model.HistoryDatasetAssociation.deleted == False ) \ + .filter( model.HistoryDatasetAssociation.visible == True ) + +class TracksterSelectionGrid( grids.Grid ): + # Grid definition. + title = "Insert into visualization" + template = "/tracks/add_to_viz.mako" + async_template = "/page/select_items_grid_async.mako" + model_class = model.Visualization + default_sort_key = "-update_time" + use_async = True + use_paging = False + columns = [ + grids.TextColumn( "Title", key="title", model_class=model.Visualization, filterable="standard" ), + grids.TextColumn( "Dbkey", key="dbkey", model_class=model.Visualization ), + grids.GridColumn( "Last Updated", key="update_time", format=time_ago ) + ] + + def build_initial_query( self, trans, **kwargs ): + return trans.sa_session.query( self.model_class ).filter( self.model_class.deleted == False ) + def apply_query_filter( self, trans, query, **kwargs ): + return query.filter( self.model_class.user_id == trans.user.id ) class VisualizationListGrid( grids.Grid ): def get_url_args( item ): @@ -89,6 +228,10 @@ UsesItemRatings ): _user_list_grid = VisualizationListGrid() _published_list_grid = VisualizationAllPublishedGrid() + _libraries_grid = LibrarySelectionGrid() + _histories_grid = HistorySelectionGrid() + _history_datasets_grid = HistoryDatasetsSelectionGrid() + _tracks_grid = TracksterSelectionGrid() @web.expose def list_published( self, trans, *args, **kwargs ): @@ -464,6 +607,69 @@ help="A description of the visualization; annotation is shown alongside published visualizations."), template="visualization/create.mako" ) + @web.expose + @web.require_login( "see all available libraries" ) + def list_libraries( self, trans, **kwargs ): + """List all libraries that can be used for selecting datasets.""" + + # Render the list view + return self._libraries_grid( trans, **kwargs ) + + @web.expose + @web.require_login( "see a library's datasets that can added to this visualization" ) + def list_library_datasets( self, trans, **kwargs ): + """List a library's datasets that can be added to a visualization.""" + + library = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( kwargs.get('f-library') ) ) + return trans.fill_template( '/tracks/library_datasets_select_grid.mako', + cntrller="library", + use_panels=False, + library=library, + created_ldda_ids='', + hidden_folder_ids='', + show_deleted=False, + comptypes=[], + current_user_roles=trans.get_current_user_roles(), + message='', + status="done" ) + + @web.expose + @web.require_login( "see all available histories" ) + def list_histories( self, trans, **kwargs ): + """List all histories that can be used for selecting datasets.""" + + # Render the list view + return self._histories_grid( trans, **kwargs ) + + @web.expose + @web.require_login( "see current history's datasets that can added to this visualization" ) + def list_current_history_datasets( self, trans, **kwargs ): + """ List a history's datasets that can be added to a visualization. """ + + kwargs[ 'f-history' ] = trans.security.encode_id( trans.get_history().id ) + kwargs[ 'show_item_checkboxes' ] = 'True' + return self.list_history_datasets( trans, **kwargs ) + + @web.expose + @web.require_login( "see a history's datasets that can added to this visualization" ) + def list_history_datasets( self, trans, **kwargs ): + """List a history's datasets that can be added to a visualization.""" + + # Render the list view + return self._history_datasets_grid( trans, **kwargs ) + + @web.expose + @web.require_login( "see all available datasets" ) + def list_datasets( self, trans, **kwargs ): + """List all datasets that can be added as tracks""" + + # Render the list view + return self._data_grid( trans, **kwargs ) + + @web.expose + def list_tracks( self, trans, **kwargs ): + return self._tracks_grid( trans, **kwargs ) + def get_item( self, trans, id ): return self.get_visualization( trans, id ) diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 templates/root/alternate_history.mako --- a/templates/root/alternate_history.mako +++ b/templates/root/alternate_history.mako @@ -131,10 +131,10 @@ # do these need _localized_ dbkeys? trackster_urls = {} if hda.dbkey != '?': - data_url = h.url_for( controller='tracks', action='list_tracks', dbkey=hda.dbkey ) + data_url = h.url_for( controller='visualization', action='list_tracks', dbkey=hda.dbkey ) data_url = hda.replace( 'dbkey', 'f-dbkey' ) else: - data_url = h.url_for( controller='tracks', action='list_tracks' ) + data_url = h.url_for( controller='visualization', action='list_tracks' ) trackster_urls[ 'hda-url' ] = data_url trackster_urls[ 'action-url' ] = h.url_for( controller='tracks', action='browser', dataset_id=encoded_data_id ) trackster_urls[ 'new-url' ] = h.url_for( controller='tracks', action='index', dataset_id=encoded_data_id, default_dbkey=hda.dbkey ) diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 templates/root/history_common.mako --- a/templates/root/history_common.mako +++ b/templates/root/history_common.mako @@ -229,10 +229,10 @@ %if data.ext in app.datatypes_registry.get_available_tracks(): <% if data.dbkey != '?': - data_url = h.url_for( controller='tracks', action='list_tracks', dbkey=data.dbkey ) + data_url = h.url_for( controller='visualization', action='list_tracks', dbkey=data.dbkey ) data_url = data_url.replace( 'dbkey', 'f-dbkey' ) else: - data_url = h.url_for( controller='tracks', action='list_tracks' ) + data_url = h.url_for( controller='visualization', action='list_tracks' ) %><a href="javascript:void(0)" data-url="${data_url}" class="icon-button chart_curve tooltip trackster-add" action-url="${h.url_for( controller='tracks', action='browser', dataset_id=dataset_id)}" diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 templates/tracks/browser.mako --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -51,7 +51,7 @@ var add_bookmarks = function() { show_modal( "Select dataset for new bookmarks", "progress" ); $.ajax({ - url: "${h.url_for( action='list_histories' )}", + url: "${h.url_for( controller='visualization', action='list_histories' )}", data: { "f-dbkey": view.dbkey }, error: function() { alert( "Grid failed" ); }, success: function(table_html) { diff -r 40f6d9738623ee2b2c7ff1f5a82fe09c7628d766 -r bc56358a5c51512f98c09a88c31a7b445e8160e0 templates/visualization/trackster_common.mako --- a/templates/visualization/trackster_common.mako +++ b/templates/visualization/trackster_common.mako @@ -17,7 +17,7 @@ ## Render a block of JavaScript that contains all necessary variables for Trackster. <%def name="render_trackster_js_vars()"> var add_track_async_url = "${h.url_for( controller='/tracks', action='add_track_async' )}", - add_datasets_url = "${h.url_for( controller='/tracks', action='list_current_history_datasets' )}", + add_datasets_url = "${h.url_for( controller='/visualization', action='list_current_history_datasets' )}", default_data_url = "${h.url_for( controller='/tracks', action='data' )}", raw_data_url = "${h.url_for( controller='/tracks', action='raw_data' )}", reference_url = "${h.url_for( controller='/tracks', action='reference' )}", https://bitbucket.org/galaxy/galaxy-central/changeset/f8ea04e7bbff/ changeset: f8ea04e7bbff user: jgoecks date: 2012-09-14 20:42:11 summary: Summary tree documentation update. affected #: 1 file diff -r bc56358a5c51512f98c09a88c31a7b445e8160e0 -r f8ea04e7bbff4acbc14f95e14fd6f955c307f906 lib/galaxy/visualization/tracks/summary.py --- a/lib/galaxy/visualization/tracks/summary.py +++ b/lib/galaxy/visualization/tracks/summary.py @@ -1,5 +1,5 @@ ''' -Summary tree data structure for feature aggregation across large genomic regions. +This module cannot be moved due to the use of pickling. ''' import sys, os @@ -11,6 +11,9 @@ MIN_LEVEL = 2 class SummaryTree: + ''' + Summary tree data structure for feature aggregation across large genomic regions. + ''' def __init__( self, block_size=25, levels=6, draw_cutoff=150, detail_cutoff=30 ): self.chrom_blocks = {} self.levels = levels Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.