Projects/laydi
Projects
/
laydi
Archived
7
0
Fork 0
This repository has been archived on 2024-07-04. You can view files and clone it, but cannot push or open issues or pull requests.
laydi/fluents/navigator.py

422 lines
16 KiB
Python
Raw Normal View History

import gtk
import gobject
import plots
import time
import fluents
from logger import logger
import dataset, plots, project, workflow, main
import scipy
class NavigatorView (gtk.TreeView):
2007-12-11 01:13:26 +01:00
"""The NavigatorView is a tree view of the project.
There is always one NavigatorView, that shows the functions, plots and
datasets in the current project.
"""
def __init__(self):
if main.project:
self.data_tree = main.project.data_tree
else:
self.data_tree = None
2006-04-21 11:23:05 +02:00
gtk.TreeView.__init__(self)
2007-12-11 01:13:26 +01:00
# Various properties
self.set_enable_tree_lines(True)
self.set_headers_visible(False)
2006-08-30 12:27:45 +02:00
self.get_hadjustment().set_value(0)
# Selection Mode
self.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
2007-12-11 01:13:26 +01:00
self.get_selection().connect('changed',self.on_selection_changed)
self._previous_selection = []
# Setting up TextRenderers etc
self.connect('row_activated', self.on_row_activated)
self.connect('cursor_changed', self.on_cursor_changed)
# Activate context menu
self.menu = NavigatorMenu(self)
self.connect('popup_menu', self.popup_menu)
self.connect('button_press_event', self.on_mouse_event)
2006-08-28 14:06:05 +02:00
self.textrenderer = textrenderer = gtk.CellRendererText()
2006-08-30 12:27:45 +02:00
pixbufrenderer = gtk.CellRendererPixbuf()
self.object_col = gtk.TreeViewColumn('Object')
2006-08-30 12:27:45 +02:00
self.object_col.pack_start(pixbufrenderer,expand=False)
2006-08-28 14:06:05 +02:00
self.object_col.pack_start(textrenderer,expand=False)
2007-12-11 01:13:26 +01:00
self.object_col.set_attributes(textrenderer, cell_background=3,
foreground=4, text=0)
2006-08-30 12:27:45 +02:00
self.object_col.set_attributes(pixbufrenderer, pixbuf=5)
self.append_column(self.object_col)
# send events to plots / itself
self.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
[("GTK_TREE_MODEL_ROW", gtk.TARGET_SAME_APP, 7)],
gtk.gdk.ACTION_LINK | gtk.gdk.ACTION_MOVE)
2006-05-02 13:09:55 +02:00
self.connect("drag-data-get",self.slot_drag_data)
logger.debug('Initializing navigator window.')
def slot_drag_data(self, treeview, context, selection, target_id, etime):
2007-12-11 01:13:26 +01:00
"""Sets the data for a drag event."""
2006-08-28 14:06:05 +02:00
treeselection = treeview.get_selection()
model, paths = treeselection.get_selected_rows()
if paths:
self.data_tree.drag_data_get(paths[0], selection)
2006-05-02 13:09:55 +02:00
def add_project(self, project):
2007-12-11 01:13:26 +01:00
"""Dependency injection."""
self.data_tree = project.data_tree
self.set_model(project.data_tree)
self.data_tree.connect('row-changed',self.on_row_changed)
2007-12-11 01:13:26 +01:00
def on_selection_changed(self, selection):
"""Update the list of currently selected datasets."""
# update prev selection right away in case of multiple events
model, paths = selection.get_selected_rows()
2006-08-28 14:06:05 +02:00
if not paths: # a plot is marked: do nothing
return
tmp = self._previous_selection
self._previous_selection = paths
2007-12-11 01:13:26 +01:00
tree = self.data_tree
# set timestamp on newly selected objects
2007-12-11 01:13:26 +01:00
[tree.set_value(tree.get_iter(path), 6, time.time())
for path in paths if path not in tmp]
2007-12-11 01:13:26 +01:00
objs = [tree.get_iter(path) for path in paths]
objs = [(tree[iter][6], tree[iter][2]) for iter in objs]
objs.sort()
objs = [obj for timestamp, obj in objs]
if objs and isinstance(objs[0], dataset.Dataset):
logger.debug('Selecting dataset')
main.project.current_data = objs
2006-05-03 13:52:54 +02:00
else:
logger.debug('Deselecting dataset')
main.project.current_data = []
def on_row_changed(self, treestore, pos, iter):
2007-12-11 01:13:26 +01:00
"""Set correct focus and colours when rows have changed."""
obj = treestore[iter][2]
obj_type = treestore[iter][1]
2007-12-11 01:13:26 +01:00
if not (obj or obj_type):
2006-04-27 16:15:13 +02:00
return
self.expand_to_path(pos)
2007-12-11 01:13:26 +01:00
if isinstance(obj, dataset.Dataset):
2006-04-27 16:15:13 +02:00
self.set_cursor(pos)
self.grab_focus()
def on_row_activated(self, widget, path, column):
tree_iter = self.data_tree.get_iter(path)
obj = self.data_tree.get_value(tree_iter, 2)
2006-04-21 11:23:05 +02:00
if isinstance(obj, plots.Plot):
logger.debug('Activating plot')
main.application.change_plot(obj)
2006-04-21 11:23:05 +02:00
elif isinstance(obj, dataset.Dataset):
pass
elif obj == None:
children = []
i = self.data_tree.iter_children(tree_iter)
while i:
child = self.data_tree.get(i, 2)[0]
if isinstance(child, plots.Plot):
children.append(child)
i = self.data_tree.iter_next(i)
main.application.change_plots(children)
2006-04-21 11:23:05 +02:00
else:
t = type(obj)
logger.notice('Activated datatype was %s. Don\'t know what to do.' % t)
def popup_menu(self, *rest):
self.menu.popup(None, None, None, 0, 0)
def on_mouse_event(self, widget, event):
path = widget.get_path_at_pos(int(event.x), int(event.y))
if path:
iter = self.data_tree.get_iter(path[0])
obj = self.data_tree.get_value(iter, 2)
else:
2007-12-11 01:13:26 +01:00
iter = None
obj = None
if isinstance(obj, dataset.Dataset):
self.menu.set_dataset(obj, iter)
else:
self.menu.set_dataset(None, iter)
if event.button == 3:
self.menu.popup(None, None, None, event.button, event.time)
def on_cursor_changed(self, widget):
2007-12-11 01:13:26 +01:00
"""Update statusbar to contain dataset information.
Lists the dimensions of a dataset in the statusbar of the program
if a dataset is focused in the navigator.
"""
path = widget.get_cursor()[0]
tree_iter = self.data_tree.get_iter(path)
obj = self.data_tree.get_value(tree_iter, 2)
2007-12-11 01:13:26 +01:00
if isinstance(obj, dataset.Dataset):
dims = zip(obj.get_dim_name(), obj.shape)
dim_text = ", ".join(["%s (%d)" % dim for dim in dims])
else:
dim_text = ""
main.application['appbar1'].push(dim_text)
class NavigatorMenu(gtk.Menu):
def __init__(self, navigator):
gtk.Menu.__init__(self)
self.navigator = navigator
self.dataset = None
self.tree_iter = None
# Populate main menu
self.load_item = gtk.MenuItem('Load dataset')
self.load_item.connect('activate', self.on_load_dataset, navigator)
self.append(self.load_item)
self.load_item.show()
self.save_item = gtk.MenuItem('Save dataset')
self.save_item.connect('activate', self.on_save_dataset, navigator)
self.append(self.save_item)
self.save_item.show()
self.delete_item = gtk.MenuItem('Delete')
self.delete_item.connect('activate', self.on_delete, navigator)
self.append(self.delete_item)
self.delete_item.show()
# Build transform sub menu
self.trans_menu = gtk.Menu()
self.trans_tr_item = gtk.MenuItem('Transpose')
self.trans_tr_item.connect('activate', self.on_transpose, navigator)
self.trans_menu.append(self.trans_tr_item)
self.trans_tr_item.show()
self.trans_stdr_item = gtk.MenuItem('Std. rows')
self.trans_stdr_item.connect('activate', self.on_standardise_rows, navigator)
self.trans_menu.append(self.trans_stdr_item)
self.trans_stdr_item.show()
self.trans_stdc_item = gtk.MenuItem('Std. cols')
self.trans_stdc_item.connect('activate', self.on_standardise_cols, navigator)
self.trans_menu.append(self.trans_stdc_item)
self.trans_stdc_item.show()
self.trans_log_item = gtk.MenuItem('Log')
self.trans_log_item.connect('activate', self.on_log, navigator)
self.trans_menu.append(self.trans_log_item)
self.trans_log_item.show()
self.trans_item = gtk.MenuItem("Transformation")
2007-08-03 11:44:31 +02:00
self.append(self.trans_item)
self.trans_item.set_submenu(self.trans_menu)
2007-08-03 11:44:31 +02:00
self.trans_item.show()
# Build plot sub menu
self.plot_menu = gtk.Menu()
self.plot_image_item = gtk.MenuItem('Image Plot')
self.plot_image_item.connect('activate', self.on_plot_image, navigator)
self.plot_menu.append(self.plot_image_item)
self.plot_image_item.show()
2007-01-17 16:40:54 +01:00
self.plot_hist_item = gtk.MenuItem('Histogram')
self.plot_hist_item.connect('activate', self.on_plot_hist, navigator)
self.plot_menu.append(self.plot_hist_item)
self.plot_hist_item.show()
self.plot_scatter_item = gtk.MenuItem('Scatter')
self.plot_scatter_item.connect('activate', self.on_plot_scatter, navigator)
self.plot_menu.append(self.plot_scatter_item)
self.plot_scatter_item.show()
2007-11-08 12:47:36 +01:00
self.plot_line_item = gtk.MenuItem('Line view')
self.plot_line_item.connect('activate', self.on_plot_line, navigator)
self.plot_menu.append(self.plot_line_item)
self.plot_line_item.show()
self.plot_item = gtk.MenuItem('Plot')
self.append(self.plot_item)
self.plot_item.set_submenu(self.plot_menu)
self.plot_item.show()
def set_dataset(self, ds, it):
self.dataset = ds
self.tree_iter = it
if ds == None:
self.save_item.set_property('sensitive', False)
self.plot_item.set_property('sensitive', False)
self.trans_item.set_property('sensitive', False)
else:
self.save_item.set_property('sensitive', True)
self.plot_item.set_property('sensitive', True)
self.trans_item.set_property('sensitive', True)
2007-12-11 01:13:26 +01:00
def load_dataset(self, filename):
"""Load the dataset from the given file and add it to the project."""
ds = dataset.read_ftsv(filename)
if isinstance(ds, dataset.GraphDataset):
icon = fluents.icon_factory.get("graph_dataset")
elif isinstance(ds, dataset.CategoryDataset):
icon = fluents.icon_factory.get("category_dataset")
else:
icon = fluents.icon_factory.get("dataset")
main.project.add_dataset(ds)
main.project.data_tree_insert(None, ds.get_name(), ds, None, "black", icon)
def on_load_dataset(self, item, navigator):
2007-12-11 01:13:26 +01:00
# Set up file chooser.
dialog = gtk.FileChooserDialog('Load dataset')
dialog.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
2007-12-11 01:13:26 +01:00
dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN, gtk.RESPONSE_OK)
dialog.set_select_multiple(True)
2007-08-22 16:05:51 +02:00
dialog.set_current_folder(main.options.datadir)
2007-12-11 01:13:26 +01:00
retval = dialog.run()
if retval in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
pass
elif retval == gtk.RESPONSE_OK:
for filename in dialog.get_filenames():
2007-12-11 01:13:26 +01:00
self.load_dataset(filename)
else:
print "unknown; ", retval
dialog.destroy()
def on_save_dataset(self, item, navigator):
dialog = gtk.FileChooserDialog('Save dataset')
dialog.set_action(gtk.FILE_CHOOSER_ACTION_SAVE)
dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)
dialog.set_current_name("%s.ftsv" % self.dataset.get_name())
retval = dialog.run()
if retval in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
logger.debug("Cancelled save dataset")
elif retval == gtk.RESPONSE_OK:
logger.debug("Saving dataset as: %s" % dialog.get_filename())
fd = open(dialog.get_filename(), 'w')
dataset.write_ftsv(fd, self.dataset)
fd.close()
else:
print "unknown; ", retval
dialog.destroy()
def on_delete(self, item, navigator):
tm, rows = navigator.get_selection().get_selected_rows()
iters = [tm.get_iter(r) for r in rows]
iters.reverse()
for i in iters:
main.project.delete_data(i)
# tm.remove(i)
def on_plot_image(self, item, navigator):
plot = plots.ImagePlot(self.dataset, name='Image Plot')
icon = fluents.icon_factory.get("line_plot")
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)
2007-01-17 16:40:54 +01:00
def on_plot_hist(self, item, navigator):
2007-08-02 12:19:16 +02:00
project = main.project
2007-01-17 16:40:54 +01:00
plot = plots.HistogramPlot(self.dataset, name='Histogram')
icon = fluents.icon_factory.get("line_plot")
project.data_tree_insert(self.tree_iter, 'Histogram', plot, None, "black", icon)
plot.set_selection_listener(project.set_selection)
project._selection_observers.append(plot)
2007-08-03 11:44:31 +02:00
def on_plot_scatter(self, item, navigator):
project = main.project
datasets = main.project.current_data
ds_major = datasets[0]
dims_major = ds_major.get_dim_name()
ids_major = ds_major.get_identifiers(dims_major[1])
if len(datasets)>1:
# If there is more than one active dataset -> try to use the two first
ds_minor = datasets[1]
dims_minor = ds_minor.get_dim_name()
if dims_minor != dims_major or ds_minor.shape[0] != ds_major.shape[0]:
# the selected datasets are not matched -> use initial selected
ds_minor = ds_major
else:
#Only one dataset selected
ds_minor = ds_major
plot = plots.ScatterPlot(ds_major, ds_minor,
dims_major[0], dims_major[1],
ids_major[0], ids_major[1],
name='Scatter (%s)' % ds_major.get_name())
plot.add_axes_spin_buttons(len(ids_major), 0, 1)
icon = fluents.icon_factory.get("line_plot")
project.data_tree_insert(self.tree_iter, 'Scatter', plot, None, "black", icon)
plot.set_selection_listener(project.set_selection)
project._selection_observers.append(plot)
2007-11-08 12:47:36 +01:00
def on_plot_line(self, item, navigator):
project = main.project
ds = self.dataset
dims = ds.get_dim_name()
ids = ds.get_identifiers(dims[1])
plot = plots.LineViewPlot(ds, name='Line (%s)' % ds.get_name())
icon = fluents.icon_factory.get("line_plot")
project.data_tree_insert(self.tree_iter, 'Line view', plot, None, "black", icon)
plot.set_selection_listener(project.set_selection)
project._selection_observers.append(plot)
2007-08-03 11:44:31 +02:00
def on_transpose(self, item, navigator):
project = main.project
ds = self.dataset.transpose()
ds._name = ds._name + ".T"
icon = fluents.icon_factory.get(ds)
project.data_tree_insert(self.tree_iter, ds.get_name(), ds, None, "black", icon)
def on_standardise_rows(self, item, navigator):
project = main.project
ds = self.dataset.copy()
ds._name = self.dataset._name + ".rsc"
axis = 1
ds._array = ds.asarray()/scipy.expand_dims(ds.asarray().std(axis), axis)
icon = fluents.icon_factory.get(ds)
project.data_tree_insert(self.tree_iter, ds.get_name(), ds, None, "black", icon)
def on_standardise_cols(self, item, navigator):
project = main.project
ds = self.dataset.copy()
ds._name = self.dataset._name + ".csc"
axis = 0
ds._array = ds.asarray()/scipy.expand_dims(ds.asarray().std(axis), axis)
icon = fluents.icon_factory.get(ds)
project.data_tree_insert(self.tree_iter, ds.get_name(), ds, None, "black", icon)
def on_log(self, item, navigator):
project = main.project
try:
if not scipy.all(self.dataset.asarray()>0):
raise ValueError
except:
logger.log('warning', 'Datasets needs to be strictly positive for a log transform')
return
ds = self.dataset.copy()
ds._array = scipy.log(ds.asarray())
icon = fluents.icon_factory.get(ds)
ds._name = ds._name + ".log"
project.data_tree_insert(self.tree_iter, ds.get_name(), ds, None, "black", icon)