Updated the selection controller with sorting ++
This commit is contained in:
parent
f0b2660813
commit
48165d1aed
|
@ -1,7 +1,3 @@
|
|||
|
||||
import logger, dataset
|
||||
import annotations
|
||||
|
||||
import pygtk
|
||||
import gtk
|
||||
import gtk.gdk
|
||||
|
@ -10,6 +6,11 @@ import gnome
|
|||
import gnome.ui
|
||||
import gobject
|
||||
|
||||
import logger, dataset
|
||||
import annotations
|
||||
from lib import hypergeom
|
||||
|
||||
|
||||
class SimpleMenu(gtk.Menu):
|
||||
def __init__(self):
|
||||
gtk.Menu.__init__(self)
|
||||
|
@ -166,22 +167,43 @@ class SelectionListController:
|
|||
self._dimension = None
|
||||
self._idlist_controller = idlist_controller
|
||||
|
||||
# Selection renderers
|
||||
renderer = gtk.CellRendererText()
|
||||
sel_column = gtk.TreeViewColumn('Selection', renderer, text=0)
|
||||
seltree.insert_column(sel_column, 0)
|
||||
|
||||
intersect_cs_col = gtk.TreeViewColumn('In curr.sel.', renderer, text=3)
|
||||
seltree.insert_column(intersect_cs_col, 1)
|
||||
|
||||
n_all_col = gtk.TreeViewColumn('# All', renderer, text=4)
|
||||
seltree.insert_column(n_all_col, 2)
|
||||
|
||||
rank_col = gtk.TreeViewColumn('Rank', renderer, text=5)
|
||||
seltree.insert_column(rank_col, 3)
|
||||
|
||||
# Signals
|
||||
seltree.connect('row-activated', self._on_row_activated)
|
||||
seltree.connect('cursor-changed', self._on_cursor_changed)
|
||||
|
||||
seltree.connect('button-press-event', self._on_button_pressed)
|
||||
seltree.drag_dest_set(gtk.DEST_DEFAULT_ALL,
|
||||
[("GTK_TREE_MODEL_ROW", gtk.TARGET_SAME_APP, 7)],
|
||||
gtk.gdk.ACTION_LINK)
|
||||
|
||||
seltree.connect('drag-data-received', self._drag_data_received)
|
||||
|
||||
##
|
||||
## Public interface
|
||||
##
|
||||
# Selections context menu
|
||||
self._seltree_menu = SimpleMenu()
|
||||
self._seltree_menu.add_simple_item('Sort by selection', self._on_seltree_sort)
|
||||
# self._seltree_menu.add_simple_item('Copy selection', self._on_seltree_copy_selection)
|
||||
#
|
||||
# Public interface
|
||||
#
|
||||
|
||||
def set_project(self, project):
|
||||
"""Dependency injection."""
|
||||
self.project = project
|
||||
project.add_selection_observer(self)
|
||||
|
||||
def set_dimlist_controller(self, dimlist_controller):
|
||||
self._dimlist_controller = dimlist_controller
|
||||
|
||||
|
@ -199,19 +221,26 @@ class SelectionListController:
|
|||
store = self._sel_stores[dim]
|
||||
|
||||
if not self._get_current_selection_iter(selection, dim):
|
||||
values = (selection.title, selection, dim)
|
||||
n = len(selection[dim])
|
||||
values = (selection.title, selection, dim, n, n, 2)
|
||||
store.insert_after(None, None, values)
|
||||
|
||||
def add_dataset(self, dataset):
|
||||
self._ensure_selection_store(dataset.get_dim_name(0))
|
||||
store = self._sel_stores[dataset.get_dim_name(0)]
|
||||
dim_name = dataset.get_dim_name(0)
|
||||
self._ensure_selection_store(dim_name)
|
||||
store = self._sel_stores[dim_name]
|
||||
di = self._get_dataset_iter(dataset)
|
||||
if not di:
|
||||
values = (dataset.get_name(), dataset, dataset.get_dim_name(0))
|
||||
n_tot = dataset.shape[0]
|
||||
selection = self.project.get_selection().get(dim_name)
|
||||
ds_idents = dataset.get_identifiers(dim_name)
|
||||
n_cs = len(selection.intersection(ds_idents))
|
||||
values = (dataset.get_name(), dataset, dim_name, n_cs, n_tot, 2)
|
||||
|
||||
i = store.insert_after(None, None, values)
|
||||
for selection in dataset.as_selections():
|
||||
values = (selection.title, selection, dataset.get_dim_name(0))
|
||||
n_sel = len(selection[dim_name])
|
||||
values = (selection.title, selection, dim_name, 0, n_sel, 0)
|
||||
store.insert_after(i, None, values)
|
||||
|
||||
|
||||
|
@ -221,12 +250,16 @@ class SelectionListController:
|
|||
def _add_selection_store(self, dim):
|
||||
"""Add a new gtk.TreeStore for the selections on a dimension."""
|
||||
# Create new store
|
||||
## Two types of lines, one for CategoryDatasets and one for
|
||||
## Selections. The elements are title, link to dataset or selection
|
||||
## and the name of the dimension.
|
||||
# Two types of lines, one for CategoryDatasets and one for
|
||||
# Selections. The elements are title, link to dataset or selection,
|
||||
# name of dimension, num. members in selection, num. in
|
||||
# intersection with current selection and the rank of selection.
|
||||
store = gtk.TreeStore(gobject.TYPE_STRING,
|
||||
gobject.TYPE_PYOBJECT,
|
||||
gobject.TYPE_STRING)
|
||||
gobject.TYPE_STRING,
|
||||
gobject.TYPE_INT,
|
||||
gobject.TYPE_INT,
|
||||
gobject.TYPE_FLOAT)
|
||||
|
||||
# Set selection store for this dimension
|
||||
self._sel_stores[dim] = store
|
||||
|
@ -265,9 +298,32 @@ class SelectionListController:
|
|||
i = store.iter_next(i)
|
||||
return None
|
||||
|
||||
##
|
||||
## GTK callbacks
|
||||
##
|
||||
def _sort_selections(self, dataset):
|
||||
"""Ranks selections by intersection with current selection.
|
||||
Ranks determined by the hypergeometric distribution.
|
||||
"""
|
||||
dim_name = dataset.get_dim_name(0)
|
||||
sel_store = self._sel_stores[dim_name]
|
||||
selection_obj = self.project.get_selection()
|
||||
current_selection = selection_obj.get(dim_name)
|
||||
if current_selection==None: return
|
||||
|
||||
pvals = hypergeom.gene_hypergeo_test(current_selection, dataset)
|
||||
|
||||
for row in sel_store:
|
||||
if row[1]==dataset:
|
||||
for child in row.iterchildren():
|
||||
name = child[0]
|
||||
child[3] = pvals[name][0]
|
||||
child[4] = pvals[name][1]
|
||||
child[5] = pvals[name][2]
|
||||
|
||||
sel_store.set_sort_column_id(5, gtk.SORT_ASCENDING)
|
||||
|
||||
#
|
||||
# GTK callbacks
|
||||
#
|
||||
|
||||
def _drag_data_received(self, widget, drag_context, x, y,
|
||||
selection, info, timestamp):
|
||||
|
||||
|
@ -306,6 +362,19 @@ class SelectionListController:
|
|||
self.project.set_selection(self._dimension,
|
||||
obj[self._dimension])
|
||||
|
||||
def _on_button_pressed(self, widget, event):
|
||||
"""Button press callbak."""
|
||||
if event.button == 3:
|
||||
self._seltree_menu.popup(None, None, None, event.button, event.time)
|
||||
|
||||
def _on_seltree_sort(self, menuitem):
|
||||
"""Sort selection tree if row is category dataset."""
|
||||
store = self._sel_stores[self._dimension]
|
||||
p = self._seltree.get_cursor()[0]
|
||||
i = store.get_iter(p)
|
||||
obj = store.get_value(i, 1)
|
||||
if isinstance(obj, dataset.CategoryDataset):
|
||||
self._sort_selections(obj)
|
||||
|
||||
class DimListController:
|
||||
def __init__(self, dimlist, seltree_controller):
|
||||
|
@ -337,7 +406,6 @@ class DimListController:
|
|||
self.project = project
|
||||
self.dim_names = project.dim_names
|
||||
self.update_dims()
|
||||
project.add_selection_observer(self._seltree_controller)
|
||||
project.add_dataset_observer(self)
|
||||
|
||||
def get_dimension(self, dim):
|
||||
|
|
Reference in New Issue