diff --git a/workflows/gobrowser.py b/workflows/gobrowser.py new file mode 100644 index 0000000..5768ac4 --- /dev/null +++ b/workflows/gobrowser.py @@ -0,0 +1,221 @@ + +import gtk +from fluents import dataset, logger, plots, workflow, fluents, project +import geneontology +from scipy import array, randn, log, ones, zeros +import networkx +import re + +EVIDENCE_CODES=[('IMP', 'Inferred from mutant phenotype'), + ('IGI', 'Inferred from genetic interaction'), + ('IPI', 'Inferred from physical interaction'), + ('ISS', 'Inferred from sequence or structure similarity'), + ('IDA', 'Inferred from direct assay'), + ('IEP', 'Inferred on expression pattern'), + ('IEA', 'Inferred from electronic annotation'), + ('TAS', 'Traceable author statement'), + ('NAS', 'Non-traceable author statement'), + ('ND', 'No biological data available'), + ('RCA', 'Inferred from reviewed computational analysis'), + ('IC', 'Inferred by curator')] + +DISTANCE_METRICS = [('resnik', 'Resnik'), + ('jiang', 'Jiang & Conrath'), + ('fussimeg', 'FuSSiMeG')] + +GO_DATA_DIR = '/home/einarr/data' + +evidence = None +go = None + +class GoTermView (gtk.Frame): + + def __init__(self): + gtk.Frame.__init__(self) + tab = gtk.Table(2, 2, False) + self._table = tab + + self._name = gtk.Label('') + self._name.set_line_wrap(True) + self._name.set_alignment(0, 0) + name_label = gtk.Label('Name:') + name_label.set_alignment(0, 0) + tab.attach(name_label, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 5, 5) + tab.attach(self._name, 1, 2, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL, 5, 5) + + self._def = gtk.TextBuffer() + textview = gtk.TextView(self._def) + textview.set_wrap_mode(gtk.WRAP_WORD) + scrolled_window = gtk.ScrolledWindow() + scrolled_window.add(textview) + def_label = gtk.Label('Def:') + def_label.set_alignment(0.0, 0.0) + tab.attach(def_label, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 5, 5) + tab.attach(scrolled_window, 1, 2, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 5, 5) + + self.add(tab) + self.set_go_term(None) + + def set_go_term(self, term): + if term: + self.set_label(term['id']) + self._name.set_text(term['name']) + self._def.set_text(term['def']) + else: + self.set_label('GO Term') + self._name.set_text('') + self._def.set_text('') + + +class GeneOntologyTree (gtk.HPaned): + + def __init__(self, network): + gtk.HPaned.__init__(self) + + treemodel = geneontology.get_go_treestore(network) + self._treemodel = treemodel + self._tree_view = gtk.TreeView(treemodel) + + self._selected_terms = set() + + self._tree_view.set_fixed_height_mode(True) + + # Set up context menu + self._context_menu = GoTermContextMenu(treemodel, self._tree_view) + self._tree_view.connect('popup_menu', self._popup_menu) + self._tree_view.connect('button_press_event', self._on_button_press) + + renderer = gtk.CellRendererText() + go_column = gtk.TreeViewColumn('GO ID', renderer, text=0) + go_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + go_column.set_fixed_width(200) + go_column.set_resizable(True) + self._tree_view.insert_column(go_column, 0) + + renderer = gtk.CellRendererToggle() + renderer.set_property('activatable', True) + renderer.connect('toggled', self._toggle_selected) + renderer.set_active(True) + renderer.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE) + go_column = gtk.TreeViewColumn('T', renderer, active=2) + go_column.set_fixed_width(20) + go_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + go_column.set_resizable(True) + self._tree_view.insert_column(go_column, 1) + + renderer = gtk.CellRendererText() + go_column = gtk.TreeViewColumn('Name', renderer, text=1) + go_column.set_fixed_width(200) + go_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + go_column.set_resizable(True) + self._tree_view.insert_column(go_column, 2) + + self._desc_view = GoTermView() + + self._tree_view.connect('cursor-changed', self._on_cursor_changed) + + scrolled_window = gtk.ScrolledWindow() + scrolled_window.add(self._tree_view) + self.add1(scrolled_window) + self.add2(self._desc_view) + self.show_all() + + def _on_cursor_changed(self, tree): + path, col = self._tree_view.get_cursor() + current = self._treemodel.get_iter(path) + term = self._treemodel.get_value(current, 3) + self._desc_view.set_go_term(term) + + + ## + ## GTK Callback functions + ## + def _popup_menu(self, *rest): + self.menu.popup(None, None, None, 0, 0) + + def _on_button_press(self, widget, event): + path = widget.get_path_at_pos(int(event.x), int(event.y)) + iter = None + + if path: + iter = self._treemodel.get_iter(path[0]) + obj = self._treemodel.get_value(iter, 3) + else: + obj = None + + self._context_menu.set_current_term(obj, iter) + + if event.button == 3: + self._context_menu.popup(None, None, None, event.button, event.time) + + def _toggle_selected(self, renderer, path): + iter = self._treemodel.get_iter(path) + + selected = self._treemodel.get_value(iter, 2) + id = self._treemodel.get_value(iter, 0) + + self._treemodel.set_value(iter, 2, not selected) + + if selected: + self._selected_terms.remove(id) + else: + self._selected_terms.add(id) + + +class GoTermContextMenu (gtk.Menu): + """Context menu for GO terms in the gene ontology browser""" + + def __init__(self, treemodel, treeview): + self._treemodel = treemodel + self._treeview = treeview + self._current_term = None + self._current_iter = None + + gtk.Menu.__init__(self) + + # Popuplate tree + self._expand_item = i = gtk.MenuItem('Expand') + i.connect('activate', self._on_expand_subtree, treemodel, treeview) + self.append(i) + i.show() + + self._collapse_item = i = gtk.MenuItem('Collapse') + i.connect('activate', self._on_collapse_subtree, treemodel, treeview) + self.append(i) + i.show() + + self._select_subtree_item = i = gtk.MenuItem('Select subtree') + i.connect('activate', self._on_select_subtree, treemodel, treeview) + self.append(i) + i.show() + + def set_current_term(self, term, it): + self._current_term = term + self._current_iter = it + + def _on_expand_subtree(self, item, treemodel, treeview): + path = treemodel.get_path(self._current_iter) + treeview.expand_row(path, True) + + def _on_collapse_subtree(self, item, treemodel, treeview): + treeview.collapse_row(treemodel.get_path(self._current_iter)) + + def _on_select_subtree(self, item, treemodel, treeview): + logger.log('notice', 'Selecting subtree from GO id: %s (%s)' % + (self._current_term['id'], self._current_term['name'])) + ids = [x['id'] for x in networkx.bfs(go, self._current_term)] + project.project.set_selection('go-terms', set(ids)) + + +class LoadGOFunction(workflow.Function): + def __init__(self): + workflow.Function.__init__(self, 'load-go', 'Load Gene Ontology') + + def run(self): + global go + go = geneontology.read_default_go() + browser = GeneOntologyTree(go) + label = gtk.Label('_Gene Ontology') + label.set_use_underline(True) + fluents.app['bottom_notebook'].append_page(browser, label) + diff --git a/workflows/smalltest.py b/workflows/smalltest.py index f572406..59771e5 100644 --- a/workflows/smalltest.py +++ b/workflows/smalltest.py @@ -3,6 +3,7 @@ import webbrowser from fluents import logger, plots,workflow,dataset from fluents.lib import blmfuncs,nx_utils,validation,engines,cx_stats,cx_utils +import gobrowser, geneontology import scipy @@ -40,6 +41,10 @@ class SmallTestWorkflow(workflow.Workflow): query.add_function(KEGGQuery()) self.add_stage(query) + go = workflow.Stage('go', 'Gene Ontology') + go.add_function(gobrowser.LoadGOFunction()) + self.add_stage(go) + # EXTRA PLOTS #plt = workflow.Stage('net', 'Network') #plt.add_function(nx_analyser.KeggNetworkAnalyser())