Added main.py that now contains the One & Only Singleton instance of these classes:

- Navigator
 - Aplication
 - Workflow
 - Project
 - Options
Corresponding changes have been added in lots of other files to account for this, but
the access to these objects should now be a lot easier.
This commit is contained in:
Einar Ryeng 2007-07-26 12:35:59 +00:00
parent 91abf12f51
commit a45743c31e
12 changed files with 196 additions and 78 deletions

View File

@ -3,7 +3,7 @@
from getopt import getopt
import os
import sys
from fluents import fluents, project, workflow
from fluents import fluents, project, workflow, main
import workflows
import cfgparse, optparse
@ -68,11 +68,16 @@ if __name__ == '__main__':
if wf.ident == options.workflow:
selected_wf = wf
app = fluents.FluentApp(selected_wf)
app.options = options
fluents.app = app
app.set_project(project.Project())
main.set_workflow(selected_wf())
main.set_options(options)
app = fluents.FluentApp()
main.set_application(app)
main.set_project(project.Project())
app.set_project(main.project)
app.show()
gtk.main()

View File

@ -0,0 +1,3 @@
import main

View File

@ -17,9 +17,8 @@ class CreateProjectDruid(gtk.Window):
Workflow, and asks the user to select one of these. A new project of
the selected class is added to the application."""
def __init__(self, app):
def __init__(self):
gtk.Window.__init__(self)
self.app = app
self.widget_tree = gtk.glade.XML(GLADEFILENAME, 'new_project_druid')
self.workflows = self.make_workflow_list()
self.selected = None
@ -63,10 +62,12 @@ class CreateProjectDruid(gtk.Window):
def finish(self, *rest):
tree, it = self['workflow_list'].get_selection().get_selected()
wf = self.workflows.get_value(it, 1)
wf_class = self.workflows.get_value(it, 1)
proj = project.Project()
self.app.set_workflow(wf(self.app))
self.app.set_project(proj)
main.set_workflow(wf_class())
# self.app.set_workflow(wf(self.app))
# self.app.set_project(proj)
main.set_project(proj)
self.hide()
self.destroy()

View File

@ -13,7 +13,7 @@ import gnome
import gnome.ui
import scipy
import pango
import project, workflow, dataset, logger, view, navigator, dialogs, selections
import project, workflow, dataset, logger, view, navigator, dialogs, selections, main
PROGRAM_NAME = 'fluents'
@ -142,8 +142,8 @@ class ViewFrameToolButton (gtk.ToolItem):
class FluentApp:
def __init__(self, wf): # Application variables
self.project = None
def __init__(self): # Application variables
# self.project = None
self.current_data = None
self._last_view = None
self._plot_toolbar = None
@ -151,7 +151,7 @@ class FluentApp:
gtk.glade.set_custom_handler(self.custom_object_factory)
self.widget_tree = gtk.glade.XML(GLADEFILENAME, 'appwindow')
self.workflow = wf(self)
# self.workflow = wf
self.idlist_crt = selections.IdListController(self['identifier_list'])
self.sellist_crt = selections.SelectionListController(self['selection_tree'],
@ -164,11 +164,11 @@ class FluentApp:
self['appwindow'].set_size_request(800, 600)
# Set up workflow
self.wf_view = workflow.WorkflowView(self.workflow)
self.wf_view = workflow.WorkflowView(main.workflow)
self.wf_view.show()
self['workflow_vbox'].pack_end(self.wf_view)
self._wf_menu = workflow.WorkflowMenu(self.workflow)
self._wf_menu = workflow.WorkflowMenu(main.workflow)
self._wf_menu.show()
wf_menuitem = gtk.MenuItem('Fu_nctions')
wf_menuitem.set_submenu(self._wf_menu)
@ -208,16 +208,16 @@ class FluentApp:
def set_project(self, proj):
logger.log('notice', 'Creating a new project')
self.project = proj
project.project = proj
self.workflow.add_project(proj)
# self.project = proj
# project.project = proj
# main.workflow.add_project(proj)
self.navigator_view.add_project(proj)
self.dimlist_crt.set_project(proj)
self.sellist_crt.set_project(proj)
def set_workflow(self, workflow):
self.workflow = workflow
self.wf_view.set_workflow(self.workflow)
main.workflow = workflow
self.wf_view.set_workflow(main.workflow)
def show(self):
self.init_gui()
@ -226,7 +226,7 @@ class FluentApp:
"""Sets the plot in the currently active ViewFrame. If the plot is
already shown in another ViewFrame it will be moved from there."""
# Set current selection in the plot before showing it.
plot.selection_changed(None, self.project.get_selection())
plot.selection_changed(None, main.project.get_selection())
self['main_view'].insert_view(plot)
self._update_toolbar(plot)
@ -287,7 +287,7 @@ class FluentApp:
return self.main_view
def create_navigator_view(self, str1, str2, int1, int2):
self.navigator_view = navigator.NavigatorView(None, self)
self.navigator_view = navigator.NavigatorView()
self.navigator_view.show()
return self.navigator_view
@ -336,7 +336,7 @@ class FluentApp:
def on_workflow_refresh_clicked(self, *ignored):
try:
reload(sys.modules[self.workflow.__class__.__module__])
reload(sys.modules[main.workflow.__class__.__module__])
except Exception, e:
logger.log('warning', 'Cannot reload workflow')
logger.log('warning', e)

90
fluents/main.py Normal file
View File

@ -0,0 +1,90 @@
import sys
#: Dictionary of observers
_observers = {}
#: The current Navigator object.
navigator = None
#: The current application
application = None
#: The current project
project = None
#: The current workflow
workflow = None
#: A cfgparse/optparse options object.
options = None
def notify_observers(name):
call = "%s_changed" % name
for s in _observers.get(name, []):
getattr(s, call)(getattr(sys.modules[__name__], name))
def _add_observer(name, observer):
"""Adds observer as an observer of the named object."""
if not _observers.has_key(name):
_observers[name] = []
_observers[name].append(observer)
def _remove_observer(name, observer):
"""Removes observer as an observer of the named object."""
if not _observers.has_key(name):
return
_observers.remove(observer)
def add_navigator_observer(observer):
_add_observer('navigator', observer)
def add_project_observer(observer):
_add_observer('project', observer)
def add_workflow_observer(observer):
_add_observer('workflow', observer)
def add_application_observer(observer):
_add_observer('application', observer)
def remove_navigator_observer(observer):
_remove_observer('navigator', observer)
def remove_project_observer(observer):
_remove_observer('project', observer)
def remove_workflow_observer(observer):
_remove_observer('workflow', observer)
def remove_application_observer(observer):
_remove_observer('application', observer)
def remove_options_observer(observer):
_remove_observer('options', observer)
def set_navigator(nav):
global navigator
navigator = nav
notify_observers('navigator')
def set_application(app):
global application
application = app
notify_observers('application')
def set_project(p):
global project
project = p
notify_observers('project')
def set_workflow(wf):
global workflow
workflow = wf
notify_observers('workflow')
def set_options(opt):
global options
options = opt
notify_observers('options')

View File

@ -4,14 +4,14 @@ import gobject
import plots
import time
import fluents
import dataset, logger, plots, project, workflow
import dataset, logger, plots, project, workflow, main
class NavigatorView (gtk.TreeView):
def __init__(self, project, app):
self.project = project
self.app = app
if project:
self.data_tree = project.data_tree
def __init__(self):
# self.project = project
# self.app = app
if main.project:
self.data_tree = main.project.data_tree
else:
self.data_tree = None
@ -65,7 +65,7 @@ class NavigatorView (gtk.TreeView):
self.data_tree.drag_data_get(paths[0], selection)
def add_project(self, project):
self.project = project
# self.project = project
self.data_tree = project.data_tree
self.set_model(project.data_tree)
self.data_tree.connect('row-changed',self.row_changed_handler)
@ -101,10 +101,10 @@ class NavigatorView (gtk.TreeView):
if objs and isinstance(objs[0], dataset.Dataset):
logger.log('debug', 'Selecting dataset')
self.project.set_current_data(objs)
main.project.set_current_data(objs)
else:
logger.log('debug', 'Deselecting dataset')
self.project.set_current_data([])
main.project.set_current_data([])
# TreeView changed. Set correct focus and colours
@ -142,7 +142,7 @@ class NavigatorView (gtk.TreeView):
if isinstance(obj, plots.Plot):
logger.log('debug', 'Activating plot')
self.app.change_plot(obj)
main.application.change_plot(obj)
elif isinstance(obj, dataset.Dataset):
self.display_data_info(obj)
elif obj == None:
@ -153,7 +153,7 @@ class NavigatorView (gtk.TreeView):
if isinstance(child, plots.Plot):
children.append(child)
i = self.data_tree.iter_next(i)
self.app.change_plots(children)
main.application.change_plots(children)
else:
t = type(obj)
logger.log('debug', 'Activated datatype was %s. Don\'t know what to do.' % t)
@ -248,9 +248,8 @@ class NavigatorMenu(gtk.Menu):
else:
icon = fluents.icon_factory.get("dataset")
project = navigator.project
project.add_dataset(ds)
project.data_tree_insert(None, ds.get_name(), ds, None, "black", icon)
main.project.add_dataset(ds)
main.project.data_tree_insert(None, ds.get_name(), ds, None, "black", icon)
else:
print "unknown; ", retval
dialog.destroy()
@ -273,10 +272,9 @@ class NavigatorMenu(gtk.Menu):
dialog.destroy()
def on_plot_image(self, item, navigator):
project = navigator.project
plot = plots.ImagePlot(self.dataset, name='Image Plot')
icon = fluents.icon_factory.get("line_plot")
project.data_tree_insert(self.tree_iter, 'Image Plot', plot, None, "black", icon)
main.project.data_tree_insert(self.tree_iter, 'Image Plot', plot, None, "black", icon)
# fixme: image plot selections are not well defined
#plot.set_selection_listener(project.set_selection)
#project._selection_observers.append(plot)

View File

@ -136,7 +136,3 @@ class Project:
self.current_data = obj
## Singleton project.
## This is the current and only project in the application.
project = None

View File

@ -6,7 +6,7 @@ import gnome
import gnome.ui
import gobject
import logger, dataset
import logger, dataset, main
import annotations
from lib import hypergeom
@ -243,8 +243,7 @@ class SelectionListController:
def set_project(self, project):
"""Dependency injection."""
self.project = project
project.add_selection_observer(self)
main.project.add_selection_observer(self)
def set_dimlist_controller(self, dimlist_controller):
"""Dependency injection of the dimension list controller."""
@ -292,7 +291,7 @@ class SelectionListController:
di = self._get_dataset_iter(dataset)
if not di:
n_tot = dataset.shape[0]
selection = self.project.get_selection().get(dim_name)
selection = main.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)
@ -363,7 +362,7 @@ class SelectionListController:
"""
dim_name = dataset.get_dim_name(0)
sel_store = self._sel_stores[dim_name]
selection_obj = self.project.get_selection()
selection_obj = main.project.get_selection()
current_selection = selection_obj.get(dim_name)
if current_selection==None: return
@ -427,7 +426,7 @@ class SelectionListController:
else:
seltree.expand_row(path, True)
elif isinstance(obj, dataset.Selection):
self.project.set_selection(self._dimension,
main.project.set_selection(self._dimension,
obj[self._dimension])
def _on_button_pressed(self, widget, event):
@ -486,7 +485,7 @@ class DimListController:
##
def set_project(self, project):
"""Dependency injection."""
self.project = project
# self.project = project
self.dim_names = project.dim_names
self.update_dims()
project.add_dataset_observer(self)

View File

@ -4,6 +4,7 @@ import os
import inspect
import logger
import fluents
import main
def _workflow_classes(modname):
"""Returns a list of all subclasses of Workflow in a given module"""
@ -58,20 +59,20 @@ class Workflow:
ident = None
description = "Workflow Description"
def __init__(self, app):
def __init__(self):
print "Setting stages"
self.stages = []
self.stages_by_id = {}
self.app = app
def get_data_file_name(self, filename):
"""Checks if a file with the given name exists in the data directory.
Returns the file name if the file exists in the data directory, which
is defined as datadir/workflowname. If the file does not exist, or the
workflow does not have an identificator, this method returns None."""
print os.path.join(self.app.options.datadir, self.ident, filename)
print os.path.join(main.options.datadir, self.ident, filename)
if self.ident == None:
return None
fn = os.path.join(self.app.options.datadir, self.ident, filename)
fn = os.path.join(main.options.datadir, self.ident, filename)
if os.path.isfile(fn):
return fn
return None
@ -87,18 +88,19 @@ class Workflow:
for fun in stage.functions:
print ' %s' % fun.name
def add_project(self,project):
if project == None:
logger.log('notice','Proejct is empty')
logger.log('notice','Project added in : %s' %self.name)
self.project = project
# def add_project(self,project):
# if project == None:
# logger.log('notice','Proejct is empty')
# logger.log('notice','Project added in : %s' %self.name)
# self.project = project
class EmptyWorkflow(Workflow):
name = 'Empty Workflow'
def __init__(self, app):
Workflow.__init__(self, None)
def __init__(self):
print "initing empty workflow"
Workflow.__init__(self)
class Stage:
@ -188,8 +190,7 @@ class WorkflowView (gtk.VBox):
def run_function(self, function):
logger.log('debug', 'Starting function: %s' % function.name)
project = self.workflow.app.project
parent_data = project.current_data
parent_data = main.project.current_data
validation = function.validate_input()
@ -226,12 +227,12 @@ class WorkflowView (gtk.VBox):
if pass_selection:
# if the function has a 'selection' argument, we pass in
# the selection
new_data = function.run(selection=project.get_selection(), *data)
new_data = function.run(selection=main.project.get_selection(), *data)
else:
new_data = function.run(*data)
if new_data != None:
project.add_data(parent_data, new_data, function.name)
main.project.add_data(parent_data, new_data, function.name)
logger.log('debug', 'Function ended: %s' % function.name)

View File

@ -164,17 +164,12 @@ def read_gene_ontology(fd):
section = s
if s == 'Term':
term = GOTerm()
# print "[Term]"
else:
term = None
#print "ignoring: %s" %s
print "ignoring: %s" %s
else:
if term:
_add_term_attribute(term, k, v, c)
# print " %s: %s" % (k, v)
# else:
# print "no term: ignoring: %s" %line
# print '.',
line = fd.readline()
if term:
@ -182,6 +177,18 @@ def read_gene_ontology(fd):
return go
def pickle_gene_ontology(go, fn):
fd = open(fn, 'wb')
pickle.dump(go, fd)
fd.close()
def load_pickled_ontology(fn):
fd = open(fn, 'rb')
go = pickle.load(fd)
fd.close()
return go
def read_default_go():
f = open("/usr/share/gene-ontology/gene_ontology.obo")
go = read_gene_ontology(f)

View File

@ -37,7 +37,7 @@ class GoTermView (gtk.Frame):
def __init__(self):
gtk.Frame.__init__(self)
tab = gtk.Table(2, 2, False)
tab = gtk.Table(2, 3, False)
self._table = tab
self._name = gtk.Label('')
@ -48,6 +48,11 @@ class GoTermView (gtk.Frame):
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._isa_parents = gtk.HBox()
isa_parents_label = gtk.Label('Is a:')
tab.attach(isa_parents_label, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
tab.attach(self._isa_parents, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
self._def = gtk.TextBuffer()
textview = gtk.TextView(self._def)
textview.set_wrap_mode(gtk.WRAP_WORD)
@ -55,9 +60,10 @@ class GoTermView (gtk.Frame):
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)
tab.attach(def_label, 0, 1, 2, 3, gtk.FILL, gtk.FILL, 5, 5)
tab.attach(scrolled_window, 1, 2, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 5, 5)
self._tab = tab
self.add(tab)
self.set_go_term(None)
@ -66,16 +72,28 @@ class GoTermView (gtk.Frame):
self.set_label(term['id'])
self._name.set_text(term['name'])
self._def.set_text(term['def'])
self._tab.remove(self._isa_parents)
self._isa_parents = gtk.HBox()
for p in term['is_a']:
btn = gtk.Button(p)
btn.show()
self._isa_parents.add(btn)
self._isa_parents.show()
self._tab.attach(self._isa_parents, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
else:
self.set_label('GO Term')
self._name.set_text('')
self._def.set_text('')
self._tab.remove(self._isa_parents)
self._isa_parents = gtk.HBox()
self._tab.attach(self._isa_parents, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5)
class GeneOntologyTree (gtk.HPaned):
def __init__(self, network):
gtk.HPaned.__init__(self)
self.set_position(400)
treemodel = geneontology.get_go_treestore(network)
self._treemodel = treemodel

View File

@ -13,8 +13,8 @@ class SmallTestWorkflow(workflow.Workflow):
ident = 'smokers'
description = 'A small test workflow for gene expression analysis.'
def __init__(self, app):
workflow.Workflow.__init__(self, app)
def __init__(self):
workflow.Workflow.__init__(self)
# DATA IMPORT
load = workflow.Stage('load', 'Data')