Example #1
0
  def __init__(self, x, y, title="Graph", parent=None):
    gtk.Window.__init__(self)
    try:
      self.set_screen(parent.get_screen())
    except:
      self.connect('destroy', lambda *w: self.destroy())

    self.set_title(title)
    self.set_default_size(800, 600)
    self.set_border_width(2)
    self.set_position(gtk.WIN_POS_CENTER)

    box = gtk.VBox()
    self.add(box)

    fig = Fig(figsize=(5,4), dpi=100)
    ax = fig.add_subplot(111)
    ax.plot(x, y)

    canvas = FigCan(fig)
    canvas.mpl_connect('key_press_event', self.on_key_event)
    box.pack_start(canvas)

    toolbar = NavBar(canvas, self)
    box.pack_start(toolbar, False, False)

    self.show_all()

    del box, fig, ax, canvas, toolbar
Example #2
0
class PowerGraph(gtk.Window):
  def __init__(self, powers, step=0.5, title="Power Graph", parent=None):
    x = []
    y = []

    for power, next_power in itertools.izip(powers, powers[1:]):
      u = float(power[0])
      u1 = float(next_power[0])

      while u < u1:
        x.append(u)
        y.append(float(eval(power[1])))
        u += step*(u1-u)

    x.append(float(powers[-1][0]))
    y.append(float(eval(powers[-1][1])))

    gtk.Window.__init__(self)
 
    try:
      self.set_screen(parent.get_screen())
    except AttributeError:
      self.connect('destroy', lambda *w: self.destroy())

    if parent is not None:
      self.set_parent(parent)
    self.set_title(title)
    self.set_destroy_with_parent(True)
    self.set_default_size(600, 400)

    vbox = gtk.VBox()
    self.add(vbox)

    figure = Figure(figsize=(5,4), dpi=100)
    subplot = figure.add_subplot(111)
    subplot.plot(x, y)
    subplot.set_title("Power Graph")
    subplot.set_xlabel("Speed (u) [m/s]")
    subplot.set_ylabel("Power [kW]")
    subplot.grid(True)

    self.canvas = FigureCanvas(figure)
    self.canvas.mpl_connect('key_press_event', self.on_key_event)
    vbox.pack_start(self.canvas)

    self.toolbar = NavigationToolbar(self.canvas, self)
    vbox.pack_start(self.toolbar, False, False)

    self.show_all()

  def on_key_event(self, event):
    key_press_handler(event, self.canvas, self.toolbar)
    def __init__(self, toolBoxWidgets=None, title="GTK Gui Plot", scaling=True, *args, **kwargs):
        if not toolBoxWidgets:
            toolBoxWidgets = []
        super(GuiWithCanvasAndToolbar, self).__init__(*args, **kwargs)
        self.connect("destroy", lambda x: gtk.main_quit())
        self.set_default_size(1100, 600)
        self.set_title(title)

        table = gtk.Table(1, 2, False)

        self.figures = []
        self.y_max = float("-inf")
        self.x_max = float("-inf")
        self.y_min = float("inf")
        self.x_min = float("inf")
        self.fig = Figure(figsize=(8, 6), dpi=100)
        self.ax = self.fig.add_subplot(111)
        canvas = FigureCanvas(self.fig)
        canvas.set_size_request(800, 600)
        canvas.mpl_connect('button_press_event', self.handle_click)

        table.attach(canvas, 0, 1, 0, 1)

        toolbox = gtk.Table(len(toolBoxWidgets) + 1, 1, False)
        i = 0
        for widget in toolBoxWidgets:
            toolbox.attach(widget, 0, 1, i, i + 1)
            i += 1

        label = gtk.Label("SimGUI")
        toolbox.attach(label, 0, 1, i, i + 1)

        table.attach(toolbox, 1, 2, 0, 1)

        self.canvas = canvas
        canvas.draw()
        self.update_figures()

        self.add(table)
        self.scaling = scaling
Example #4
0
 def __init__(self, wTree, widget):
     figure = Figure(figsize=(6,4), dpi=72)
     axes = figure.add_subplot(1,1,1)
     canvas = FigureCanvasGTKAgg(figure)
     canvas.show()
     canvas.mpl_connect('pick_event', self.pick_handler)
     canvas.mpl_connect('motion_notify_event', self.motion_handler)
     canvas.mpl_connect('button_release_event', self.release_handler)
     canvas.mpl_connect('button_press_event', self.press_handler)
     graphview = wTree.get_widget(widget)
     graphview.add_with_viewport(canvas)
     self.figure = figure
     self.canvas = canvas
     self.axes = axes
     self.plot_line = self.axes.plot([], [], 'b-', animated=True)[0]
     self.cursors = []
     self.picked = None
     self.data = []
Example #5
0
class GenomeBrowser(object):
	def __init__(self):
		"""
		2008-01-30
		"""
		program_path = os.path.dirname(sys.argv[0])
		xml = gtk.glade.XML(os.path.join(program_path, 'GenomeBrowser.glade'))
		xml.signal_autoconnect(self)
		self.xml = xml
		
		self.app1 = xml.get_widget("app1")
		self.app1.connect("delete_event", gtk.main_quit)
		#self.app1.set_default_size(1200, 800)
		
		self.vbox_matplotlib = xml.get_widget('vbox_matplotlib')
		
		# matplotlib canvas
		fig = Figure(figsize=(8,8))
		self.canvas_matplotlib = FigureCanvas(fig)  # a gtk.DrawingArea
		self.canvas_matplotlib.set_size_request(600,400)
		self.canvas_matplotlib.mpl_connect('pick_event', self.on_canvas_pick)
		self.vbox_matplotlib.pack_start(self.canvas_matplotlib)
		
		#matplotlib axes
		#self.ax = fig.add_subplot(111)
		axe_y_offset1 = 0.05	#y_offset for axe_LD, axe_strain_pca, axe_phenotype, axe_map
		axe_height1 = 0.15	#height of axe_LD or axe_snp_matrix
		axe_y_offset2 = axe_y_offset1+axe_height1
		axe_height2 = 0.75	#height of axe_gene_model
		axe_y_offset3 = axe_y_offset2+axe_height2
		
		
		axe_x_offset1 = 0.1	#
		axe_width1 = 0.85
		axe_x_offset2 = axe_x_offset1 + axe_width1
		
		self.ax = fig.add_axes([axe_x_offset1, axe_y_offset2, axe_width1, axe_height2], frameon=False)
		self.ax.grid(True, alpha=0.3)
		#self.ax.set_xticklabels([])	#remove xtick labels on ax1 because axe_LD's xtick labels cover this.
		
		self.axe_gene_model = fig.add_axes([axe_x_offset1, axe_y_offset1, axe_width1, axe_height1], frameon=False, sharex=self.ax)
		#axe_gene_model.set_xticks([])	#this will set ax1's xticks off as well because the x-axis is shared.
		self.axe_gene_model.set_yticks([])
		
		
		# matplotlib toolbar
		self.toolbar = NavigationToolbar(self.canvas_matplotlib, self.app1)
		self.vbox_matplotlib.pack_start(self.toolbar, False, False)
		
		self.textview_output = xml.get_widget('textview_output')
		
		self.textbuffer_output = self.textview_output.get_buffer()
		
		#redirect stdout/stderr to textbuffer_output
		t_table=self.textbuffer_output.get_tag_table()
		tag_err=gtk.TextTag("error")
		tag_err.set_property("foreground","red")
		#tag_err.set_property("font","monospace 10")
		t_table.add(tag_err)
		tag_out=gtk.TextTag("output")
		tag_out.set_property("foreground","blue")
		#tag_out.set_property("font","monospace 10")
		t_table.add(tag_out)
		
		self.dummy_out = yh_gnome.Dummy_File(self.textbuffer_output, tag_out)
		self.dummy_err = yh_gnome.Dummy_File(self.textbuffer_output, tag_err)
		sys.stdout = self.dummy_out
		sys.stderr = self.dummy_err
		
		self.app1.show_all()
		
		self.filechooserdialog1 = xml.get_widget("filechooserdialog1")
		self.entry_min_value_cutoff = xml.get_widget('entry_min_value_cutoff')
		self.entry_max_value_cutoff = xml.get_widget('entry_max_value_cutoff')
		self.filechooserdialog1.connect("delete_event", yh_gnome.subwindow_hide)
		
		
		self.dialog_db_connect = xml.get_widget("dialog_db_connect")
		self.dialog_db_connect.connect("delete_event", yh_gnome.subwindow_hide)
		self.entry_mysql_hostname = xml.get_widget("entry_mysql_hostname")
		self.entry_mysql_dbname = xml.get_widget("entry_mysql_dbname")
		self.entry_postgres_hostname = xml.get_widget("entry_postgres_hostname")
		self.entry_postgres_dbname = xml.get_widget("entry_postgres_dbname")
		self.entry_postgres_schema = xml.get_widget("entry_postgres_schema")
		self.entry_gene_annotation_picklef = xml.get_widget("entry_gene_annotation_picklef")
		self.filechooserbutton_gene_annot = xml.get_widget("filechooserbutton_gene_annot")
		
		self.dialog_preferences = xml.get_widget("dialog_preferences")
		self.dialog_preferences.connect("delete_event", yh_gnome.subwindow_hide)
		self.checkbutton_debug = xml.get_widget("checkbutton_debug")
		self.checkbutton_stdout = xml.get_widget("checkbutton_stdout")
		self.checkbutton_stderr = xml.get_widget("checkbutton_stderr")
		self.entry_gene_width = xml.get_widget("entry_gene_width")
		self.checkbutton_draw_gene_symbol = xml.get_widget("checkbutton_draw_gene_symbol")
		
		self.aboutdialog1 = xml.get_widget("aboutdialog1")
		self.aboutdialog1.connect("delete_event", yh_gnome.subwindow_hide)
		
		self.dialog_cnvqc_db = xml.get_widget("dialog_cnvqc_db")
		self.filechooserdialog_cnv_gada = xml.get_widget("filechooserdialog_cnv_gada")		
		
		self.mysql_conn = self.mysql_curs = self.postgres_conn = self.postgres_curs = self.db = None
		self.gene_annotation = None
		self.candidate_gene_set = None
		
		self.chr_id2size = None
		self.chr_id2cumu_size = None
		self.chr_gap = None
		self.chr_id_ls = []
		
		self.genome_wide_results = GenomeWideResults(gap=1.0)
		self.genome_wide_results.genome_wide_result_ls = []
		self.genome_wide_results.genome_wide_result_obj_id2index = {}
		self.artist_obj_id2data_obj_key = {}
		self.yticks = []
		self.yticklabels = []
		
		self.gene_id2artist_object_id = {}
		self.chr_id2gene_id_ls = {}	#chr_id here is str type (db is varchar type)
		self.gene_id2model = {}
		self.artist_obj_id2artist_gene_id_ls = {}
		
		self.gene_id2vspan_obj_id = {}	#for the axvspan()'s drawn on the canvas
		
		self.gene_width = 1.0
		
		self.draw_gene_symbol_when_clicked = 0
		
		self.debug = 0
	
	def load_data(self, mysql_curs, postgres_curs):
		"""
		2008-02-04 update the info related to chromosome , position in toolbar
		2008-02-01
			read the input data
			
			chr_id2cumu_size has an extra fake chromosome (0) compared to chr_id2size
			
			chr_id is all changed into str type
		"""		
		from variation.src.common import get_chr_id2size, get_chr_id2cumu_size
		chr_id_int2size = get_chr_id2size(mysql_curs)
		self.chr_id2size = {}	#change the type of chr_id into string type
		for chr_id_int, size in chr_id_int2size.iteritems():
			self.chr_id2size[str(chr_id_int)] = size
		#chr_id2cumu_size has an extra fake chromosome (0) compared to chr_id2size
		data_ls = get_chr_id2cumu_size(self.chr_id2size)
		self.chr_id2cumu_size, self.chr_gap, self.chr_id_ls = data_ls[:3]
		#2008-02-04 update the info related to chromosome , position in toolbar
		if self.debug:
			print 'self.chr_id2size', self.chr_id2size
			for chr_id in self.chr_id2size:
				print type(chr_id)
			print 'self.chr_id2cumu_size', self.chr_id2cumu_size
			for chr_id in self.chr_id2cumu_size:
				print type(chr_id)
			print 'self.chr_id_ls', self.chr_id_ls
			for chr_id in self.chr_id_ls:
				print type(chr_id)
		self.toolbar.update_chr_info(self.chr_id2size, self.chr_id2cumu_size, self.chr_gap, self.chr_id_ls)
	
	def getXposition(self, chr, pos):
		chr = str(chr)
		if getattr(self, 'chr_id2cumu_size', None) is None:
			self.load_data(self.mysql_curs, self.postgres_curs)
		this_chr_starting_pos_on_plot = self.chr_id2cumu_size[chr]-self.chr_id2size[chr]-self.chr_gap
		x = this_chr_starting_pos_on_plot + pos
		return x
	
	def plot(self, ax, canvas, genome_wide_result, draw_line_as_point=True, draw_cnv_block=True):
		"""
		2008-05-28
			input is genome_wide_result
			chr_id2cumu_size, chr_id2size, chr_gap hidden from arguments
		2008-02-04
			chromosome is converted to str type
		2008-02-01
			draw the p-value, snp position, and chromosome boundary
		"""
		sys.stderr.write("Plotting %s ..."%genome_wide_result.name)
		#ax.clear()
		genome_wide_result_id = id(genome_wide_result)
		x_ls = []
		y_ls = []
		plot_together = True
		for data_obj in genome_wide_result.data_obj_ls:
			y_pos = genome_wide_result.base_value - genome_wide_result.min_value + data_obj.value
			x_pos = self.getXposition(data_obj.chromosome, data_obj.position)
			if data_obj.stop_position is not None and draw_cnv_block==True:
				x_stop_pos = self.getXposition(data_obj.chromosome, data_obj.stop_position)
				xs = [x_pos, x_stop_pos, x_stop_pos, x_pos]
				y_base_pos = genome_wide_result.base_value - genome_wide_result.min_value + 0
				ys = [y_pos, y_pos, y_base_pos, y_base_pos]
				artist_obj = Polygon(zip(xs,ys), facecolor='g', alpha=0.8, linewidth=0.5) 	#linewidth=0.7
				ax.add_patch(artist_obj)
				artist_obj_id = id(artist_obj)
				plot_together = False
			if data_obj.stop_position is not None and draw_line_as_point==False:	#bigger than 100k, then a line
				x_stop_pos = self.getXposition(data_obj.chromosome, data_obj.stop_position)
				x_ls.append([(x_pos, y_pos), (x_stop_pos, y_pos)])
				#artist_obj = Line2D([x_pos, y_pos], [x_stop_pos, y_pos], picker=True)
			else:
				if draw_line_as_point and data_obj.stop_position is not None:
					x_stop_pos = self.getXposition(data_obj.chromosome, data_obj.stop_position)
					x_pos = (x_pos+x_stop_pos)/2.0
				x_ls.append(x_pos)
				y_ls.append(y_pos)
					#artist_obj = Circle((x_pos, y_pos), picker=True)
		
		if plot_together:
			if len(y_ls)>0:
				artist_obj = ax.scatter(x_ls, y_ls, s=10, faceted=False, picker=True)
			else:
				artist_obj = LineCollection(x_ls, picker=True)
				ax.add_artist(artist_obj)
			artist_obj_id = id(artist_obj)
			self.artist_obj_id2data_obj_key[artist_obj_id] = [genome_wide_result_id, None]
		
		y_base_value = genome_wide_result.base_value
		y_top_value = genome_wide_result.base_value + genome_wide_result.max_value - genome_wide_result.min_value
		if self.debug:
			print "y_base_value", y_base_value
			print 'y_top_value', y_top_value
		self.yticks.append(y_base_value)
		self.yticks.append(y_top_value)
		ax.set_yticks(self.yticks)
		
		self.yticklabels.append('%s %.2f'%(genome_wide_result.name, genome_wide_result.min_value))
		self.yticklabels.append('%s %.2f'%(genome_wide_result.name, genome_wide_result.max_value))
		ax.set_yticklabels(self.yticklabels)
		
		"""
		ax.add_artist(g_artist)
		artist_obj_id = id(g_artist)
				self.artist_obj_id2artist_gene_id_ls[artist_obj_id] = [g_artist, gene_id]
				self.gene_id2artist_object_id[gene_id] = artist_obj_id
				
				x_ls = []
		y_ls = []
		max_pvalue = 0
		for i in range(len(snp_pos_ls)):
			chr, pos = snp_pos_ls[i]
			chr = str(chr)
			this_chr_starting_pos_on_plot = chr_id2cumu_size[chr]-chr_id2size[chr]-chr_gap
			x = this_chr_starting_pos_on_plot + pos
			x_ls.append(x)
			pvalue = pvalue_ls[i]
			if pvalue > max_pvalue:
				max_pvalue = pvalue
			y_ls.append(pvalue)
		ax.plot(x_ls, y_ls, '.', picker=3)	#3 points tolerance
		"""
		#draw the chromosome boundary
		for chr_id, cumu_size in self.chr_id2cumu_size.iteritems():
			ax.vlines(cumu_size, y_base_value, y_top_value, color='k')
		canvas.draw()
		sys.stderr.write("Done.\n")
	
	def respond2GeneObjPicker(self, event, artist_obj_id, artist_obj_id2artist_gene_id_ls, gene_annotation,\
							ax=None, draw_gene_symbol_when_clicked=False, canvas_matplotlib=None):
		"""
		2008-12-17
			a common function specifying how to respond to picker events of 
				both gene models in axe_gene_model and vertical gene spans in ax
			called by on_canvas_pick()
		"""
		gene_id = artist_obj_id2artist_gene_id_ls[artist_obj_id][1]
		gene_model = gene_annotation.gene_id2model[gene_id]
		
		if len(gene_model.gene_commentaries)==0:
			gene_commentary = gene_model	#fake one here
		else:
			gene_commentary = gene_model.gene_commentaries[0]
		
		protein_label = getattr(gene_commentary, 'protein_label', None)
		if not protein_label:
			protein_label = getattr(gene_commentary, 'label', '')
		
		protein_comment = getattr(gene_commentary, 'protein_comment', None)
		if not protein_comment:
			protein_comment = getattr(gene_commentary, 'comment', '')
		
		if getattr(gene_commentary, 'protein_label', None) is not None:	#true gene_commentary is available
			type_of_gene = getattr(gene_model, 'type_of_gene', '')
		else:	#it doesn't have protein, get gene_commentary_type
			type_of_gene = getattr(gene_commentary, 'gene_commentary_type', '')
		
		print '%s (gene id=%s) type_of_gene: %s. chromosome: %s. start: %s. stop: %s. strand: %s.'%\
				(gene_model.gene_symbol, gene_id, type_of_gene, gene_model.chromosome, \
				gene_model.start, gene_model.stop, gene_model.strand)
		print '\t protein_label: %s.'%protein_label
		print '\t protein_comment: %s.'%protein_comment
		
		if draw_gene_symbol_when_clicked:
			if ax:
				ax.text(event.mouseevent.xdata, event.mouseevent.ydata, gene_model.gene_symbol, size=8)
			if canvas_matplotlib:
				canvas_matplotlib.draw()
	
	def on_canvas_pick(self, event):
		"""
		2008-11-12
			display more information (maf, genotype_var_perc, comment) of data_obj (SNP) if they exist
		2008-05-28
			pick from collection
		2008-01-31 copied from examples/pick_event_demo.py from matplotlib source code
		"""
		if self.debug:
			print dir(event)
			print event.artist
			print dir(event.artist)
			print type(event.artist)
		"""
		if isinstance(event.artist, Line2D):
			thisline = event.artist
			xdata = thisline.get_xdata()
			ydata = thisline.get_ydata()
			ind = event.ind
			if self.debug:
				print "indices:", ind
				print 'onpick1 line:', zip(numpy.take(xdata, ind), numpy.take(ydata, ind))
			for i in ind:
				print "snp chromosome: %s, position: %s, pvalue: %s"%(self.snp_pos_ls[i][0], self.snp_pos_ls[i][1], self.pvalue_ls[i])
		"""
		if isinstance(event.artist, ExonIntronCollection):	#ExonIntronCollection is also a kind of Collection
			artist_obj_id = id(event.artist)
			if artist_obj_id in self.artist_obj_id2artist_gene_id_ls:
				self.respond2GeneObjPicker(event, artist_obj_id, self.artist_obj_id2artist_gene_id_ls, self.gene_annotation,\
							ax=self.axe_gene_model, draw_gene_symbol_when_clicked=self.draw_gene_symbol_when_clicked, \
							canvas_matplotlib=self.canvas_matplotlib)
			else:
				sys.stderr.write("%s not in artist_obj_id2artist_gene_id_ls.\n"%(artist_obj_id))
		elif isinstance(event.artist, Collection) or isinstance(event.artist, LineCollection):	#
			artist_obj_id = id(event.artist)
			if artist_obj_id in self.artist_obj_id2data_obj_key:
				genome_wide_result_id, data_obj_id = self.artist_obj_id2data_obj_key[artist_obj_id]
				genome_wide_result = self.genome_wide_results.get_genome_wide_result_by_obj_id(genome_wide_result_id)
				for obj_index in event.ind:
					if isinstance(obj_index, tuple) or isinstance(obj_index, list):
						obj_index = obj_index[0]
					data_obj = genome_wide_result.get_data_obj_by_obj_index(obj_index)
					output_str = "genome result: %s, chromosome: %s, position: %s, "%(genome_wide_result.name, data_obj.chromosome, data_obj.position)
					if data_obj.stop_position is not None:
						output_str += "stop position: %s, "%(data_obj.stop_position)
					output_str += '\n'
					output_str += "\tscore: %s\n"%(data_obj.value)
					if data_obj.maf:
						output_str += "\tmaf: %s\n"%(data_obj.maf)
					if data_obj.genotype_var_perc:
						output_str += "\tgenotype_var_perc: %s\n"%(data_obj.genotype_var_perc)
					if data_obj.comment:
						output_str += "\tcomment: %s\n"%(data_obj.comment)
					print output_str
			else:
				sys.stderr.write("%s not in artist_obj_id2data_obj_key.\n"%(artist_obj_id))
		elif isinstance(event.artist, Polygon):	#ExonIntronCollection is also a kind of Collection
			artist_obj_id = id(event.artist)
			
			print 'artist ID:', artist_obj_id 
			patch = event.artist
			
			print 'onpick1 patch:', patch.get_verts()
			if artist_obj_id in self.artist_obj_id2artist_gene_id_ls:
				self.respond2GeneObjPicker(event, artist_obj_id, self.artist_obj_id2artist_gene_id_ls, self.gene_annotation,\
										ax=self.ax, draw_gene_symbol_when_clicked=self.draw_gene_symbol_when_clicked, \
										canvas_matplotlib=self.canvas_matplotlib)
			else:
				sys.stderr.write("%s not in artist_obj_id2artist_gene_id_ls.\n"%(artist_obj_id))
		elif isinstance(event.artist, Rectangle):
			patch = event.artist
			print 'onpick1 patch:', patch.get_verts()
		elif isinstance(event.artist, Text):
			text = event.artist
			print 'onpick1 text:', text.get_text()
		
	
	def on_imagemenuitem_quit_activate(self, data=None):
		"""
		2008-02-01
			program quits
		"""
		gtk.main_quit()
	
	def on_imagemenuitem_open_activate(self, event, data=None):
		self.filechooserdialog1.show_all()
	
	def on_imagemenuitem_db_connect_activate(self, event, data=None):
		self.dialog_db_connect.show_all()
	
	def on_imagemenuitem_cnvqc_db_activate(self, event, data=None):
		"""
		2009-10-30
		"""
		self.dialog_cnvqc_db.show_all()
	
	def on_imagemenuitem_cnv_file_activate(self, event, data=None):
		"""
		2009-10-30
		"""
		self.filechooserdialog_cnv_gada.show_all()
	
	def on_button_filechooser_ok_clicked(self, widget, data=None):
		"""
		2008-12-16
			allow gwr name to be specified
			add function to get gwr from db based on call_method_id, analysis_method_id, phenotype_method_id
		2008-10-12
			add checkbutton_draw_line_as_point
			add checkbutton_4th_col_stop_pos
		2008-08-03
			restrict the data by (chromosome, start, stop)
		2008-05-31
			add check button to handle log10 transformation
		2008-05-28
			use GenomeWideResult and etc
		2008-02-14
			set the window title by the input filename
		"""
		input_fname = self.filechooserdialog1.get_filename()
		self.filechooserdialog1.hide()
		if not self.mysql_conn or not self.mysql_curs:
			self.db_connect()
		self.app1.set_title("Genome Browser: %s"%input_fname)
		
		checkbutton_log10_transformation = self.xml.get_widget("checkbutton_log10_transformation")
		if checkbutton_log10_transformation.get_active():
			do_log10_transformation = True
		else:
			do_log10_transformation = False
		
		if self.entry_min_value_cutoff.get_text():
			min_value_cutoff = float(self.entry_min_value_cutoff.get_text())
		else:
			min_value_cutoff = None
		
		#2008-08-03
		pdata = PassingData()
		entry_chromosome = self.xml.get_widget("entry_chromosome")
		if entry_chromosome.get_text():
			pdata.chromosome = int(entry_chromosome.get_text())
		entry_start = self.xml.get_widget("entry_start")
		if entry_start.get_text():
			pdata.start = int(entry_start.get_text())
		entry_stop = self.xml.get_widget("entry_stop")
		if entry_stop.get_text():
			pdata.stop = int(entry_stop.get_text())
		
		# 2009-10-27
		if self.entry_max_value_cutoff.get_text():
			pdata.max_value_cutoff = float(self.entry_max_value_cutoff.get_text())
		else:
			pdata.max_value_cutoff = None
		# 2009-10-27
		checkbutton_OR_min_max = self.xml.get_widget("checkbutton_OR_min_max")
		if checkbutton_OR_min_max.get_active():
			pdata.OR_min_max = True
		else:
			pdata.OR_min_max = False
		
		checkbutton_4th_col_stop_pos = self.xml.get_widget("checkbutton_4th_col_stop_pos")
		if checkbutton_4th_col_stop_pos.get_active():
			pdata.is_4th_col_stop_pos = True
		else:
			pdata.is_4th_col_stop_pos = False
		
		checkbutton_draw_line_as_point = self.xml.get_widget("checkbutton_draw_line_as_point")
		if checkbutton_draw_line_as_point.get_active():
			draw_line_as_point= True
		else:
			draw_line_as_point = False
		
		entry_gwr_name = self.xml.get_widget("entry_gwr_name")
		if entry_gwr_name.get_text():
			pdata.gwr_name = entry_gwr_name.get_text()
		else:
			pdata.gwr_name = None
		
		entry_call_method_id = self.xml.get_widget("entry_call_method_id")
		call_method_id = entry_call_method_id.get_text()
		entry_analysis_method_id = self.xml.get_widget("entry_analysis_method_id")
		analysis_method_id = entry_analysis_method_id.get_text()
		entry_phenotype_method_id = self.xml.get_widget("entry_phenotype_method_id")
		phenotype_method_id = entry_phenotype_method_id.get_text()
		
		if call_method_id and analysis_method_id and phenotype_method_id:
			call_method_id = int(call_method_id)
			analysis_method_id = int(analysis_method_id)
			phenotype_method_id = int(phenotype_method_id)
			rows = Stock_250kDB.ResultsMethod.query.filter_by(call_method_id=call_method_id).filter_by(analysis_method_id=analysis_method_id).\
					filter_by(phenotype_method_id=phenotype_method_id).filter_by(results_method_type_id=1)
			if rows.count()==1:
				rm = rows.first()
			elif rows.count()==0:
				sys.stderr.write("No result fetched from db based on call_method_id=%s, analysis_method_id=%s, phenotype_method_id=%s.\n"%\
								(call_method_id, analysis_method_id, phenotype_method_id))
				rm = None
			else:
				sys.stderr.write("First result out of %s results fetched from db based on call_method_id=%s, analysis_method_id=%s, phenotype_method_id=%s.\n"%\
								(rows.count(), call_method_id, analysis_method_id, phenotype_method_id))
				rm = rows.first()
			if rm:
				input_fname = rm.filename
				pdata.gwr_name = '%s_%s_%s'%(rm.analysis_method.short_name, rm.phenotype_method_id, rm.phenotype_method.short_name)
			
		
		genome_wide_result = getGenomeWideResultFromFile(input_fname, min_value_cutoff, do_log10_transformation, pdata)
		if len(genome_wide_result.data_obj_ls)>0:
			self.genome_wide_results.add_genome_wide_result(genome_wide_result)
			#self.load_data(input_fname, self.mysql_curs, self.postgres_curs)
			self.plot(self.ax, self.canvas_matplotlib, self.genome_wide_results.genome_wide_result_ls[-1], draw_line_as_point=draw_line_as_point)
		else:
			sys.stderr.write("No data in %s under min_value_cutoff=%s. Maybe min_value_cutoff is too high.\n"%(input_fname, min_value_cutoff))
	
	def on_button_filechooser_cancel_clicked(self, widget, data=None):
		self.filechooserdialog1.hide()
	
	def on_button_dialog_db_connect_cancel_clicked(self, widget, data=None):
		self.dialog_db_connect.hide()
	
	def on_button_dialog_db_connect_clicked(self, widget, data=None):
		self.dialog_db_connect.hide()
		self.db_connect()
	
	def on_button_cnvqc_ok_clicked(self, widget, data=None):
		"""
		2009-10-30
		"""
		self.dialog_cnvqc_db.hide()
		if not self.mysql_conn or not self.mysql_curs:
			self.db_connect()
		
		entry_cnv_qc_accession_id = self.xml.get_widget("entry_cnv_qc_accession_id")
		cnv_qc_accession_id = entry_cnv_qc_accession_id.get_text()
		if cnv_qc_accession_id:
			cnv_qc_accession_id = int(cnv_qc_accession_id)
		else:
			sys.stderr.write("Accession id is not given.\n")
			return
		entry_cnv_type_id = self.xml.get_widget("entry_cnv_type_id")
		cnv_type_id = entry_cnv_type_id.get_text()
		if cnv_type_id:
			cnv_type_id = int(cnv_type_id)
		else:
			cnv_type_id = None
		entry_cnv_qc_min_size = self.xml.get_widget("entry_cnv_qc_min_size")
		cnv_qc_min_size = entry_cnv_qc_min_size.get_text()
		if cnv_qc_min_size:
			cnv_qc_min_size = int(cnv_qc_min_size)
		else:
			cnv_qc_min_size = None
		entry_cnv_qc_min_no_of_probes = self.xml.get_widget("entry_cnv_qc_min_no_of_probes")
		cnv_qc_min_no_of_probes = entry_cnv_qc_min_no_of_probes.get_text()
		if cnv_qc_min_no_of_probes:
			cnv_qc_min_no_of_probes = int(cnv_qc_min_no_of_probes)
		else:
			cnv_qc_min_no_of_probes = None
		
		genome_wide_result = self.db.getCNVQCInGWA(cnv_qc_accession_id, cnv_type_id=cnv_type_id, min_size=cnv_qc_min_size,\
												min_no_of_probes=cnv_qc_min_no_of_probes)
		if len(genome_wide_result.data_obj_ls)>0:
			self.genome_wide_results.add_genome_wide_result(genome_wide_result)
			#self.load_data(input_fname, self.mysql_curs, self.postgres_curs)
			self.plot(self.ax, self.canvas_matplotlib, self.genome_wide_results.genome_wide_result_ls[-1], draw_cnv_block=True)
		else:
			sys.stderr.write("No CNV QC data for accession_id=%s, cnv_type=%s, min_size=%s, min_no_of_probes=%s.\n"%\
							(cnv_qc_accession_id, cnv_type_id, cnv_qc_min_size, cnv_qc_min_no_of_probes))
	
	
	def on_button_cnvqc_cancel_clicked(self, widget, data=None):
		"""
		2009-10-30
		"""
		self.dialog_cnvqc_db.hide()
		
		
	def on_button_cnv_gada_ok_clicked(self, widget, data=None):
		"""
		2009-10-30
			get CNVs from GADA output file
		"""
		input_fname = self.filechooserdialog_cnv_gada.get_filename()
		self.filechooserdialog_cnv_gada.hide()
		if not self.mysql_conn or not self.mysql_curs:
			self.db_connect()
		
		entry_cnv_array_id = self.xml.get_widget("entry_cnv_array_id")
		array_id = entry_cnv_array_id.get_text()
		if array_id:
			array_id = int(array_id)
		else:
			sys.stderr.write("Array id is not given.\n")
			return
		entry_cnv_max_amp = self.xml.get_widget("entry_cnv_max_amp")
		max_amp = entry_cnv_max_amp.get_text()
		if max_amp:
			max_amp = float(max_amp)
		else:
			max_amp = None
		entry_cnv_min_amp = self.xml.get_widget("entry_cnv_min_amp")
		min_amp = entry_cnv_min_amp.get_text()
		if min_amp:
			min_amp = float(min_amp)
		else:
			min_amp = None
		entry_cnv_min_size = self.xml.get_widget("entry_cnv_min_size")
		min_size = entry_cnv_min_size.get_text()
		if min_size:
			min_size = int(min_size)
		else:
			min_size = None
		
		entry_cnv_min_no_of_probes = self.xml.get_widget("entry_cnv_min_no_of_probes")
		min_no_of_probes = entry_cnv_min_no_of_probes.get_text()
		if min_no_of_probes:
			min_no_of_probes = int(min_no_of_probes)
		else:
			min_no_of_probes = None
		
		input_fname_ls = [input_fname]
		genome_wide_result = getCNVDataFromFileInGWA(input_fname_ls, array_id, max_amp=max_amp, min_amp=min_amp, min_size=min_size,\
							min_no_of_probes=min_no_of_probes)
		
		if len(genome_wide_result.data_obj_ls)>0:
			self.genome_wide_results.add_genome_wide_result(genome_wide_result)
			#self.load_data(input_fname, self.mysql_curs, self.postgres_curs)
			self.plot(self.ax, self.canvas_matplotlib, self.genome_wide_results.genome_wide_result_ls[-1], draw_cnv_block=True)
		else:
			sys.stderr.write("No CNV data for array_id=%s, max_amp=%s, min_amp=%s, min_size=%s, min_no_of_probes=%s.\n"%\
							(array_id, max_amp, min_amp, min_size, min_no_of_probes))
	
	
	def on_button_cnv_gada_cancel_clicked(self, widget, data=None):
		"""
		2009-10-30
		"""
		self.filechooserdialog_cnv_gada.hide()
	
	def db_connect(self):
		"""
		2010-1-15
			pass "cls_with_db_args=self" to DrawSNPRegion.dealWithGeneAnnotation()
		2009-12-09
			add db_user, db_passwd to MySQLdb.connect()
		2008-12-16
			add gene_annotation_picklef
		2008-02-01
			read the data in dialog_db_connect and establish the connections to two databases
		"""
		sys.stderr.write("Database Connecting ...")
		self.drivername = 'mysql'
		self.hostname = self.entry_mysql_hostname.get_text()
		self.dbname = self.entry_mysql_dbname.get_text()
		self.db_user = self.xml.get_widget("entry_db_user").get_text()
		self.db_passwd = self.xml.get_widget("entry_db_passwd").get_text()
		
		import MySQLdb
		try:
			self.mysql_conn = MySQLdb.connect(db=self.dbname, host=self.hostname, user=self.db_user, passwd=self.db_passwd)
			self.mysql_curs = self.mysql_conn.cursor()
			self.db = Stock_250kDB.Stock_250kDB(drivername=self.drivername, username=self.db_user,
					   password=self.db_passwd, hostname=self.hostname, database=self.dbname)
			self.db.setup(create_tables=False)
			self.session = self.db.session
		except:
			sys.stderr.write('DB connection error: %s\n'%repr(sys.exc_info()))
			traceback.print_exc()
		
		if not self.gene_annotation:
			gene_annotation_picklef = self.entry_gene_annotation_picklef.get_text()
			self.gene_annotation = DrawSNPRegion.dealWithGeneAnnotation(gene_annotation_picklef, cls_with_db_args=self)
		
		#2010-1-13 for postgresql. commented out
		#hostname = self.entry_postgres_hostname.get_text()
		#dbname = self.entry_postgres_dbname.get_text()
		#schema = self.entry_postgres_schema.get_text()
		
		#from annot.bin.codense.common import db_connect			#2008-12-16 don't need postgres conn anymore
		#self.postgres_conn, self.postgres_curs = db_connect(hostname, dbname, schema)
		
		sys.stderr.write("Done.\n")
	
	def get_gene_id2model(cls, curs, entrezgene_mapping_table='genome.entrezgene_mapping', \
						annot_assembly_table = 'genome.annot_assembly', gene_table='genome.gene', \
						gene2go_table='genome.gene2go', tax_id=3702):
		"""
		2008-09-24
			turn gene_id into integer
		2008-08-03
			schema where tables about genes are from is renamed from 'sequence' to 'genome'
		2008-02-02
			get all the necessary info for genes.
			watch, chromosome here is varchar type (because of chromosome X, Y etc)
		"""
		sys.stderr.write("Getting gene_id2model and chr_id2gene_id_ls...")
		from annot.bin.codense.common import pg_1d_array2python_ls
		gene_id2model = {}
		chr_id2gene_id_ls = {}
		curs.execute("DECLARE gene_crs CURSOR FOR select e.gene_id, a.chromosome, e.start, e.stop, e.mrna_start, e.mrna_stop, e.cds_start, e.cds_stop, e.strand, g.gene_symbol, g.description, g.type_of_gene \
					from %s e, %s a, %s g where e.gene_id=g.gene_id and e.genomic_gi=a.gi and e.tax_id=%s order by chromosome, start, stop"%\
					(entrezgene_mapping_table, annot_assembly_table, gene_table, tax_id))
		curs.execute("fetch 5000 from gene_crs")
		rows = curs.fetchall()
		while rows:
			for row in rows:
				#gene_id is integer. chromosome is varchar.
				gene_id, chromosome, start, stop, mrna_start, mrna_stop, cds_start, cds_stop, strand, symbol, description, type_of_gene = row
				gene_id = int(gene_id)	#2008-09-24
				if cds_start and cds_stop:
					if type(cds_start)!=list:
						cds_start = pg_1d_array2python_ls(cds_start, int)
						cds_stop = pg_1d_array2python_ls(cds_stop, int)
				else:
					cds_start = cds_stop = None
				
				if mrna_start and mrna_stop:
					if type(mrna_stop)!=list:
						mrna_start = pg_1d_array2python_ls(mrna_start, int)
						mrna_stop = pg_1d_array2python_ls(mrna_stop, int)
				else:
					mrna_start = mrna_stop = None
				
				if chromosome not in chr_id2gene_id_ls:
					chr_id2gene_id_ls[chromosome] = []
				chr_id2gene_id_ls[chromosome].append(gene_id)
				if gene_id not in gene_id2model:
					gene_id2model[gene_id] = GeneModel(gene_id, chromosome, symbol, description, type_of_gene, \
														start, stop, mrna_start, mrna_stop, cds_start, cds_stop, strand)
			curs.execute("fetch 5000 from gene_crs")
			rows = curs.fetchall()
		curs.execute("close gene_crs")
		sys.stderr.write("Done.\n")
		return gene_id2model, chr_id2gene_id_ls
	
	get_gene_id2model = classmethod(get_gene_id2model)
	
	def plot_one_gene(self, ax, gene_id, gene_id2model, chr_id2cumu_size, chr_id2size, chr_gap, y_value=1, gene_width=1.0):
		"""
		2008-12-16
			defunct. DrawSNPRegion.drawGeneModel() is used in on_button_draw_annotation_clicked()
		2008-02-02
			draw a single gene on the canvas, 
		"""
		gene_model = gene_id2model.get(gene_id)
		if gene_model:
			c_start_ls = None
			c_end_ls = None
			if gene_model.cds_start!=None and gene_model.cds_stop!=None:
				c_start_ls = gene_model.cds_start
				c_end_ls = gene_model.cds_stop
			elif gene_model.mrna_start!=None and gene_model.mrna_stop!=None:
				c_start_ls = gene_model.mrna_start
				c_end_ls = gene_model.mrna_stop
			elif gene_model.start!=None and gene_model.stop!=None:
				c_start_ls = [gene_model.start]
				c_end_ls = [gene_model.stop]
			if c_start_ls and c_end_ls:
				chromosome = gene_model.chromosome
				this_chr_starting_pos_on_plot = chr_id2cumu_size[chromosome]-chr_id2size[chromosome]-chr_gap
				if gene_model.strand=="1":
					g_artist = Gene(c_start_ls, c_end_ls, y=y_value, x_offset=this_chr_starting_pos_on_plot, width=gene_width, alpha=0.3, facecolor='r', picker=True)
				elif gene_model.strand=="-1":	#to draw opposite strand, 1st is to order c_start_ls and c_end_ls in descending order. 2nd is to swap c_start_ls and c_end_ls.
					#c_start_ls.reverse()	#2008-02-04 it's already in descending order in db.
					#c_end_ls.reverse()	#2008-02-04 it's already in descending order in db.
					g_artist = Gene(c_end_ls, c_start_ls, y=y_value, x_offset=this_chr_starting_pos_on_plot, width=gene_width, alpha=0.3, facecolor='r', picker=True)
				else:	#no arrow
					g_artist = Gene(c_start_ls, c_end_ls, y=y_value, is_arrow=False, x_offset=this_chr_starting_pos_on_plot, width=gene_width, alpha=0.3, facecolor='r', picker=True)
				ax.add_artist(g_artist)
				artist_obj_id = id(g_artist)
				self.artist_obj_id2artist_gene_id_ls[artist_obj_id] = [g_artist, gene_id]
				self.gene_id2artist_object_id[gene_id] = artist_obj_id
	
	def on_button_draw_annotation_clicked(self, widget, data=None):
		"""
		2008-12-16
			use DrawSNPRegion.drawGeneModel() to draw gene models
		2008-02-02
		"""
		if not self.chr_id2size:
			sys.stderr.write("No genome-wide pvalue plot has been drawn yet. Do it first!\n")
			return
		#if not self.gene_id2model:
		#	self.gene_id2model, self.chr_id2gene_id_ls = self.get_gene_id2model(self.postgres_curs, tax_id=3702)
		if not self.gene_annotation:
			self.db_connect()
		
		xlim = self.axe_gene_model.get_xlim()
		left_chr, left_pos = get_chr_pos_from_x_axis_pos(xlim[0], self.chr_gap, self.chr_id2cumu_size, self.chr_id_ls)
		right_chr, right_pos = get_chr_pos_from_x_axis_pos(xlim[1], self.chr_gap, self.chr_id2cumu_size, self.chr_id_ls)
		
		#fake a snps_within_this_region for drawGeneModel()
		snps_within_this_region = PassingData(chr_pos_ls=[[left_chr, left_pos],[right_chr, right_pos]])
		base_y_value = 1
		gene_width = 0.8
		gene_position_cycle = 5
		
		return_data = DrawSNPRegion.drawGeneModel(self.axe_gene_model, snps_within_this_region, self.gene_annotation, candidate_gene_set=None,\
								gene_width=gene_width, gene_position_cycle=gene_position_cycle, base_y_value=base_y_value, \
								gene_box_text_gap=20, label_gene=0, rotate_xy=False,\
								chr_id2cumu_size=self.chr_id2cumu_size, chr_id2size=self.chr_id2size, chr_gap=self.chr_gap,\
								artist_obj_id2artist_gene_id_ls=self.artist_obj_id2artist_gene_id_ls, \
								gene_id2artist_object_id=self.gene_id2artist_object_id, drawGeneOnTheBoundary=False)
					#set drawGeneOnTheBoundary to False because later adding text to these genes would corrupt the running program.
		self.axe_gene_model.set_ylim([base_y_value-gene_width, gene_position_cycle+gene_width*2])
		
		"""
		for gene_id in self.chr_id2gene_id_ls[left_chr]:
			gene_model = self.gene_id2model[gene_id]
			if gene_model.start!=None and gene_model.stop!=None and gene_model.stop>left_pos and gene_id not in self.gene_id2artist_object_id:
				if left_chr==right_chr:	#same chromosome
					if gene_model.start>right_pos:	#totally out of range, skip it
						continue
				y_value = len(self.gene_id2artist_object_id)%4	#cycling through the y position to avoid clogging
				self.plot_one_gene(self.ax, gene_id, self.gene_id2model, self.chr_id2cumu_size, self.chr_id2size, self.chr_gap, y_value=-1-y_value, gene_width=self.gene_width)
		if left_chr!=right_chr:
			for gene_id in self.chr_id2gene_id_ls[right_chr]:
				gene_model = self.gene_id2model[gene_id]
				if gene_model.start!=None and gene_model.stop!=None and gene_model.start<right_pos and gene_id not in self.gene_id2artist_object_id:
					y_value = len(self.gene_id2artist_object_id)%4	#cycling through the y position to avoid clogging
					self.plot_one_gene(self.ax, gene_id, self.gene_id2model, self.chr_id2cumu_size, self.chr_id2size, self.chr_gap, y_value=-1-y_value, gene_width=self.gene_width)
		"""
		self.canvas_matplotlib.draw()
	
	def on_imagemenuitem_preferences_activate(self, event, data=None):
		"""
		2008-02-04
		"""
		self.dialog_preferences.show_all()
	
	def on_button_dialog_preferences_ok_clicked(self, widget, data=None):
		"""
		2008-02-04
			change some preferences
		"""
		self.dialog_preferences.hide()
		if self.checkbutton_debug.get_active():
			self.debug = 1
		else:
			self.debug = 0
		if self.checkbutton_stderr.get_active():
			sys.stderr = self.dummy_err
		else:
			sys.stderr = sys.__stderr__
		if self.checkbutton_stdout.get_active():
			sys.stdout = self.dummy_out
		else:
			sys.stdout = sys.__stdout__
		if self.checkbutton_draw_gene_symbol.get_active():
			self.draw_gene_symbol_when_clicked = 1
		else:
			self.draw_gene_symbol_when_clicked = 0
		self.gene_width = float(self.entry_gene_width.get_text())
	
	def on_button_dialog_preferences_cancel_clicked(self, widget, data=None):
		"""
		2008-02-04
			don't change any preferences
		"""
		self.dialog_preferences.hide()
	
	def on_imagemenuitem_about_activate(self, widget):
		"""
		2008-02-04
		"""
		self.aboutdialog1.show_all()
	
	def on_imagemenuitem_cleanup_output_activate(self, widget):
		"""
		2008-02-04
			clean up output buffer
		"""
		self.textbuffer_output.set_text('')
	
	def on_checkbutton_debug_toggled(self, widget):
		"""
		2008-05-28
		"""
		if self.checkbutton_debug.get_active():
			self.debug = 1
		else:
			self.debug = 0
	
	def on_checkbutton_stdout_toggled(self, widget):
		"""
		2008-05-28
		"""
		if self.checkbutton_stdout.get_active():
			sys.stdout = self.dummy_out
		else:
			sys.stdout = sys.__stdout__
	
	def on_checkbutton_stderr_toggled(self, widget):
		"""
		2008-05-28
		"""
		if self.checkbutton_stderr.get_active():
			sys.stderr = self.dummy_err
		else:
			sys.stderr = sys.__stderr__
	
	def on_checkbutton_draw_gene_symbol_toggled(self, widget):
		"""
		2008-05-28
		"""
		if self.checkbutton_draw_gene_symbol.get_active():
			self.draw_gene_symbol_when_clicked = 1
		else:
			self.draw_gene_symbol_when_clicked = 0
	
	def on_entry_gene_width_changed(self, widget):
		"""
		2008-05-28
		"""
		self.gene_width = float(self.entry_gene_width.get_text())
	
	def on_filechooserbutton_gene_annot_file_set(self, widget):
		"""
		2008-12-16
		"""
		self.entry_gene_annotation_picklef.set_text(self.filechooserbutton_gene_annot.get_filename())
	
	def on_button_draw_gene_list_bars_clicked(self, widget):
		"""
		2008-12-16
			draw vertical spans to denote the locations of genes from a candidate list
		"""
		if self.db is None:
			self.db_connect()
		if not self.chr_id2size:
			sys.stderr.write("No genome-wide pvalue plot has been drawn yet. Do it first!\n")
			return
		entry_gene_list_id = self.xml.get_widget("entry_gene_list_id")
		list_type_id = entry_gene_list_id.get_text()
		comboboxentry_bar_color = self.xml.get_widget("comboboxentry_bar_color")
		bar_color = comboboxentry_bar_color.get_active_text()
		if not bar_color:	#default is black
			bar_color = 'k'
		if list_type_id:
			list_type_id = int(list_type_id)
			self.candidate_gene_set = GeneListRankTest.dealWithCandidateGeneList(list_type_id, return_set=True)
			for gene_id in self.candidate_gene_set:
				gene_model = self.gene_annotation.gene_id2model[gene_id]
				if gene_id in self.gene_id2vspan_obj_id:
					artist_obj_id = self.gene_id2vspan_obj_id[gene_id]
					artist = self.artist_obj_id2artist_gene_id_ls[artist_obj_id][0]
					if artist.get_edgecolor()!=bar_color:
						artist.set_edgecolor(bar_color)
					if artist.get_facecolor()!=bar_color:
						artist.set_facecolor(bar_color)
					#artist.remove()
				else:
					this_chr_starting_pos_on_plot = self.chr_id2cumu_size[gene_model.chromosome]-\
							self.chr_id2size[gene_model.chromosome]-self.chr_gap
					xmin = this_chr_starting_pos_on_plot + gene_model.start
					xmax = this_chr_starting_pos_on_plot + gene_model.stop
					artist = self.ax.axvspan(xmin, xmax, edgecolor=bar_color, facecolor=bar_color, alpha=0.3, picker=6)
					artist_obj_id = id(artist)
					self.artist_obj_id2artist_gene_id_ls[artist_obj_id] = [artist, gene_id]
					self.gene_id2vspan_obj_id[gene_id] = artist_obj_id
			self.canvas_matplotlib.draw()
	
	def on_button_adjust_gene_axis_clicked(self, widget):
		"""
		2008-12-19
			sometimes after zoom-in/out, axe_gene_model loses track of its y-range and the gene models in it float into ax.
			this function would bring the y-range of axe_gene_model into normal range.
		"""
		base_y_value = 1
		gene_width = 0.8
		gene_position_cycle = 5
		self.axe_gene_model.set_ylim([base_y_value-gene_width, gene_position_cycle+gene_width*2])
		self.canvas_matplotlib.draw()
Example #6
0
class SensorWindow(object):
    def __init__(self, mainThread, gladefile='sensor_window.glade'):
        self.builder = gtk.Builder()
        self.builder.add_from_file(gladefile)
        self.builder.connect_signals(self)

        self._stopped = False
        self.mainThread = mainThread

        self.fig = plt.figure()
        self.numLines = 1

        # lines plot
        self.ax = self.fig.add_subplot(111)
        self.ax.set_xlabel('Time')
        self.ax.set_ylabel('Power')
        self.ax.xaxis.set_animated(True)
        self.ax.yaxis.set_animated(True)
        self.ax.set_title('Light Intensity')
        self.ax.grid(True)

        self.start = time.time()
        self.background1 = None
        self.prev_time = self.start
        self.prev_pixel_offset = 0
        self.x0 = 0
        self.value = [0] * self.numLines

        self.ax.set_ylim(-1, 256)

        self.lines = []
        for i in range(self.numLines):
            line, = self.ax.plot([], [], animated=True, lw=2)
            self.lines.append(line)

        self.canvas = FigureCanvas(self.fig)

        self.graphview = self.builder.get_object("box2")
        self.graphview.pack_start(self.canvas)
        self.graphview.reorder_child(self.canvas, 0)

        self.img = self.builder.get_object("image1")
        self.img.set_from_file("off.svg")
        self.lamp = False

        self.canvas.show()

        gobject.idle_add(self.update_line)
        self.canvas.mpl_connect('draw_event', self.on_draw)

        self.barpath = []

    def close_window(self, obj):
        print "closing window"
        self.builder.get_object("window1").destroy()

    def destroy_callback(self, obj):
        print "destroying window"
        self.mainThread.stop()
        self._stopped = True

    def close_from_mainthread(self):
        print "close from mainthread"
        self.builder.get_object("window1").destroy()

    def toggle_lamp(self):
        print "toggle lamp!!"
        self.img = self.builder.get_object("image1")
        if (self.lamp):
            self.lamp = False
            self.img.set_from_file("off.svg")
        else:
            self.lamp = True
            self.img.set_from_file("on.svg")

    def update_line(self, *args):

        if self._stopped:
            self.destroy_callback(None)
            return False

        if self.background1 is None:
            return True

        cur_time = time.time()
        pixel_offset = int((cur_time - self.start) * 40.)
        dx_pixel = pixel_offset - self.prev_pixel_offset
        self.prev_pixel_offset = pixel_offset
        dx_data = self.get_dx_data(dx_pixel)  #cur_time - self.prev_time)

        x0 = self.x0
        self.x0 += dx_data
        self.prev_time = cur_time

        self.ax.set_xlim(self.x0 - 2, self.x0 + 0.1)

        # restore background which will plot lines from previous plots
        self.restore_background_shifted(dx_pixel)  #x0, self.x0)

        # now plot line segment within [x0, x0+dx_data],
        # Note that we're only plotting a line between [x0, x0+dx_data].
        xx = np.array([x0, self.x0])
        for i in range(len(self.lines)):
            line = self.lines[i]
            line.set_xdata(xx)

            # the for loop below could be improved by using collection.
            line.set_ydata(np.array([self.value[i], self.value[i]]))
            self.ax.draw_artist(line)

        self.background2 = self.canvas.copy_from_bbox(self.get_bg_bbox())

        self.ax.draw_artist(self.ax.xaxis)
        self.ax.draw_artist(self.ax.yaxis)

        self.canvas.blit(self.ax.get_figure().bbox)
        return True

    def get_dx_data(self, dx_pixel):
        tp = self.ax.transData.inverted().transform_point
        x0, y0 = tp((0, 0))
        x1, y1 = tp((dx_pixel, 0))
        return (x1 - x0)

    def get_bg_bbox(self):
        return self.ax.bbox.padded(-3)

    def save_bg(self):
        self.background1 = self.canvas.copy_from_bbox(
            self.ax.get_figure().bbox)
        self.background2 = self.canvas.copy_from_bbox(self.get_bg_bbox())

    def on_draw(self, *args):
        self.save_bg()
        return False

    def restore_background_shifted(self, dx_pixel):
        """
		restore bacground shifted by dx in data coordinate. This only
		works if the data coordinate system is linear.
		"""

        # restore the clean slate background
        self.canvas.restore_region(self.background1)

        # restore subregion (x1+dx, y1, x2, y2) of the second bg
        # in a offset position (x1-dx, y1)
        x1, y1, x2, y2 = self.background2.get_extents()
        self.canvas.restore_region(self.background2,
                                   bbox=(x1 + dx_pixel, y1, x2, y2),
                                   xy=(x1 - dx_pixel, y1))

        return dx_pixel

    def update(self, data):
        if type(data) == ListType:
            assert (len(self.lines) == len(data))
            self.value = data
        else:
            assert (len(self.lines) == 1)
            self.value = [data]
Example #7
0
class Figure(gtk.VBox):
    def __init__(self):
        print "Starting up SamFigure!"
        gtk.VBox.__init__(self)
        self.figure = MPLFigure()
        self.canvas = FigureCanvas(self.figure)
        self.canvas.mpl_connect("button_press_event", self.on_click)
        self.ax = self.figure.add_subplot(111)
        self.ax2 = None
        self.mode = TWODPLOT
        self.new_data()
        self.xlabel = ''
        self.y1label = ''
        self.y2label = ''
        self.xsize = 0
        self.ysize = 0
        self.packed = False
        self.count_since_replot=0

        self.set_colors()


    def on_click(self,event):
        # If left button, 
        if event.button==1:
                # screen coordinates of click
                xclick,yclick= event.x, event.y
                top_ax=event.inaxes
                if top_ax is None: return

                # display coordinates of nearest point in ax
                data1=self.ax.transData.transform(\
                    zip(self.listing.getX(),self.listing.getY(1)))
                distances1=\
                    [(x-xclick)**2+(y-yclick)**2 \
                    for (x,y) in data1]
                ind_sel1=numpy.argmin(distances1)
                dist1 = distances1[ind_sel1]
                xsel,ysel= data1[ind_sel1]
                label_ax=self.ax
                label_color='b'

                # if DUAL, then also check ax2 for nearer points
                if self.mode==DUALTWODPLOT:
                    data2=self.ax2.transData.transform(\
                        zip(self.listing.getX(),self.listing.getY(2)))
                    distances2=\
                        [(x-xclick)**2+(y-yclick)**2 \
                        for (x,y) in data2]
                    ind_sel2=numpy.argmin(distances2)
                    dist2 = distances2[ind_sel2]
                    if dist2<dist1:
                        xsel,ysel= data2[ind_sel2]
                        label_color='g'
                        label_ax=self.ax2

                # Clear off old labels
                if hasattr(self,"label_text"):
                    self.label_text.remove()
                    self.label_point.remove()
                    del(self.label_text)
                
                # Coordinates to show ( data coordinates of the selected axes)
                xlabel,ylabel=label_ax.transData.inverted().transform((xsel,ysel))

                # Coordinates to place label (on top set of axes)
                xloc,yloc=top_ax.transData.inverted().transform((xsel,ysel))

                # Label the point
                if (xloc > sum(self.ax.get_xlim())/2): h_align='right'
                else: h_align='left'
                self.label_text=\
                    top_ax.text(xloc,yloc,'({0:.3g},{1:.3g})'\
                        .format(xlabel,ylabel),\
                        backgroundcolor='white', color=label_color,\
                        verticalalignment='bottom', horizontalalignment=h_align,\
                        bbox={'facecolor': 'white', 'boxstyle':
                              'round'},zorder=100 )
                self.label_point,=\
                        top_ax.plot(xloc,yloc,'ro',\
                        zorder=self.label_text.get_zorder()+1)
                self.repaint()

        # Otherwise, just clear off old labels
        else:
            self.label_text.remove()
            self.label_point.remove()
            del(self.label_text)
            self.repaint()

    def replot(self):
        if self.mode == TWODPLOT:
                self.ax.clear()
                self.ax.plot(self.listing.getX(),self.listing.getY(1),self.color1+'.-')
                self.count_since_replot=0
        elif self.mode == DUALTWODPLOT:
                self.ax.clear()
                self.ax2.clear()
                self.ax.plot(self.listing.getX(),self.listing.getY(1),self.color1+'.-')
                self.ax2.plot(self.listing.getX(),self.listing.getY(2),self.color2+'.-')
                self.count_since_replot=0

    def show(self):
        try:
            if not self.packed:
                self.pack_start(self.canvas, expand=True)
                toolbar = NavigationToolbar(self.canvas, self.get_parent_window())

                next = 8
                button = gtk.Button('Lin y')
                button.show()
                button2 = gtk.Button('Lin x')
                button2.show()
                # linear/log
                def clicked(button):
                    self.adjust_axis_margins()
                    self.set_axis_labels()
                    self.color_labels()
                    self.canvas.draw_idle()
                    self.canvas.show()
                    if self.ax.get_yscale() == 'log':
                        button.set_label('Lin y')
                        self.ax.set_yscale('linear')
                    else:
                        button.set_label('Log y')
                        self.ax.set_yscale('log')
                    self.show()


                def clicked2(button):
                    self.adjust_axis_margins()
                    self.set_axis_labels()
                    self.color_labels()
                    self.canvas.draw_idle()
                    self.canvas.show()
                    if self.ax.get_xscale() == 'log':
                        button.set_label('Lin x')
                        self.ax.set_xscale('linear')
                    else:
                        button.set_label('Log x')
                        self.ax.set_xscale('log')
                    self.show()


                button.connect('clicked', clicked)
                button2.connect('clicked', clicked2)

                toolitem=gtk.ToolItem()
                toolitem.show()
                toolitem.add(button)
                toolbar.insert(toolitem, next)
                next +=1
                toolitem2=gtk.ToolItem()
                toolitem2.show()
                toolitem2.add(button2)
                toolbar.insert(toolitem2, next)


                self.pack_start(toolbar, expand=False)
                self.packed = True
            super(Figure, self).show()
        except Exception, e:
            print 'Exception: ', e
            raise
class DataMatrixGuiXYProbe(gtk.Window):
	"""
	2009-3-13
		migrated from QCVisualize.py. now become a standalone program and able to read data from a file and plot ...
		QCVisualize.py inherits from here
	2008-02-05
		embed it into a bigger gnome app, add more buttons, and change the __init__()
	2008-01-01
		class to visualize the results from QualityControl.py
	"""
	def __init__(self, plot_title='', id_is_strain=1, header=None, strain_acc_list=None, category_list=None, data_matrix=None):
		"""
		2008-01-10
			use a paned window to wrap the scrolledwindow and the canvas
			so that the relative size of canvas to the scrolledwindow could be adjusted by the user.
		"""
		prog = gnome.program_init('DataMatrixGuiXYProbe', '0.1')	#this must be called before any initialization for gnome app
		
		program_path = os.path.dirname(__init__.__file__)	#sys.argv[0])
		xml = gtk.glade.XML(os.path.join(program_path, 'DataMatrixGuiXYProbe.glade'))
		xml.signal_autoconnect(self)
		self.app1 = xml.get_widget("app1")
		self.app1.connect("delete_event", gtk.main_quit)
		self.app1.set_default_size(800, 1000)
		self.app1.set_title(plot_title)
		
		self.plot_title = plot_title
		self.id_is_strain = id_is_strain
		self.header = header
		self.strain_acc_list = strain_acc_list
		self.category_list = category_list
		self.data_matrix = data_matrix
		
		self.column_types = None
		self.column_header = None
		self.column_editable_flag_ls = None
		self.list_2d = None
		
		
		self.column_types = None
		self.list_2d = None
		self.column_header = None
		self.editable_flag_ls = None
		
		self.vbox1 = xml.get_widget("vbox1")
		self.treeview_matrix = xml.get_widget("treeview_matrix")
		
		# matplotlib stuff
		fig = Figure(figsize=(8,8))
		self.canvas = FigureCanvas(fig)  # a gtk.DrawingArea
		self._idClick = self.canvas.mpl_connect('button_press_event', self.onUserClickCanvas)
		self.vpaned1 = xml.get_widget("vpaned1")
		self.vpaned1.add2(self.canvas)
		
		#vbox.pack_start(self.canvas, True, True)
		self.ax = fig.add_subplot(111)
		self.treeview_matrix.connect('row-activated', self.plot_row)
		
		toolbar = NavigationToolbar(self.canvas, self.app1)
		self.vbox1.pack_start(toolbar, False, False)
		
		self.checkbutton_label_dot = xml.get_widget('checkbutton_label_dot')
		self.entry_dot_label_column = xml.get_widget('entry_dot_label_column')
		
		self.entry_x_na = xml.get_widget('entry_x_na')
		self.entry_y_na = xml.get_widget('entry_y_na')
		
		self.entry_multiply_x = xml.get_widget('entry_multiply_x')
		self.entry_multiply_y = xml.get_widget('entry_multiply_y')
		self.entry_add_x = xml.get_widget('entry_add_x')
		self.entry_add_y = xml.get_widget('entry_add_y')

		self.entry_x_error = xml.get_widget("entry_x_error")
		self.entry_y_error = xml.get_widget("entry_y_error")
		self.checkbutton_logX = xml.get_widget('checkbutton_logX')	#2014.06.09
		self.checkbutton_logY = xml.get_widget('checkbutton_logY')
		self.entry_x_column = xml.get_widget('entry_x_column')
		self.entry_y_column = xml.get_widget('entry_y_column')
		#self.checkbutton_histLogX = xml.get_widget('checkbutton_histLogX')	#2014.06.09
		#self.checkbutton_histLogY = xml.get_widget('checkbutton_histLogY')
		
		self.entry_hist_column = xml.get_widget('entry_hist_column')
		self.entry_no_of_bins = xml.get_widget('entry_no_of_bins')	#2009-5-20
		self.entry_plot_title = xml.get_widget('entry_plot_title')
		self.entry_plot_title.set_text(self.plot_title)
		
		self.filechooserdialog_save = xml.get_widget("filechooserdialog_save")
		self.filechooserdialog_save.connect("delete_event", yh_gnome.subwindow_hide)
		
		self.entry_sampling_probability = xml.get_widget("entry_sampling_probability")
		self.filechooserdialog_open = xml.get_widget("filechooserdialog_open")
		self.filechooserdialog_open.connect("delete_event", yh_gnome.subwindow_hide)
		
		self.app1_appbar1 = xml.get_widget('app1_appbar1')
		self.app1_appbar1.push('Status Message.')	#import gnome.ui has to be executed.
		
		self.treeview_matrix.connect('cursor-changed', self.update_no_of_selected, self.app1_appbar1)
		self.app1.show_all()
		
		self.xValuePreProcessor = None
		self.yValuePreProcessor = None
		
		self.x_error_column_index = None
		self.y_error_column_index = None
		
		#self.add_events(gdk.BUTTON_PRESS_MASK|gdk.KEY_PRESS_MASK|gdk.KEY_RELEASE_MASK)
	
	def onUserClickCanvas(self, event):
		"""
		2009-3-13
			use (x_lim[1]-x_lim[0])/200. as the resolution for a dot to be called identical to a data point.
			similar for the y_data
		2009-3-13
			deal with checkbutton_label_dot, entry_dot_label_column, entry_x_column, entry_y_column
		2008-01-01
			derived from on_click_row() of QualityControl.py
			reaction when user clicked in the plot
		"""
		# get the x and y coords, flip y from top to bottom
		x, y = event.x, event.y
		to_label_dot = self.checkbutton_label_dot.get_active()
		dot_label_column = int(self.entry_dot_label_column.get_text())
		x_column = int(self.entry_x_column.get_text())
		y_column = int(self.entry_y_column.get_text())
		x_lim = self.ax.get_xlim()
		x_grain_size = (x_lim[1]-x_lim[0])/200.
		y_lim = self.ax.get_ylim()
		y_grain_size = (y_lim[1]-y_lim[0])/200.
		if event.button==1:
			if event.inaxes is not None:
				print 'data coords', event.xdata, event.ydata
				if self.list_2d is None:
					return
				for row in self.list_2d:
					if row[x_column] and row[y_column]:	#not empty
						try:
							x_data = float(row[x_column])
							y_data = float(row[y_column])
							x = self.processDataValue(x_data, self.xValuePreProcessor)
							if x is None:
								continue
							y = self.processDataValue(y_data, self.yValuePreProcessor)
							if y is None:
								continue
							if abs(x-event.xdata)<x_grain_size and abs(y-event.ydata)<y_grain_size:
								info = row[dot_label_column]
								if to_label_dot:
									self.ax.text(event.xdata, event.ydata, info, size=8)
									self.canvas.draw()
								sys.stderr.write("%s: %s, %s: %s, raw xy=(%s, %s), scaled xy=(%s,%s), info: %s.\n"%\
												(self.column_header[0], row[0], self.column_header[1], row[1], row[x_column], row[y_column], x,y, info))
						except:
							sys.stderr.write("Column %s, %s of row (%s), could not be converted to float. skip.\n"%\
											(x_column, y_column, repr(row)))
	
	def setUserDataPreprocessingFlags(self):
		"""
		2014.07.25
		"""
		
		self.xValuePreProcessor = ValuePreProcessor(na = self.entry_x_na.get_text())
		self.yValuePreProcessor = ValuePreProcessor(na = self.entry_y_na.get_text())
		
		if self.entry_multiply_x.get_text():
			self.xValuePreProcessor.scalar = float(self.entry_multiply_x.get_text())
		if self.entry_multiply_y.get_text():
			self.yValuePreProcessor.scalar = float(self.entry_multiply_y.get_text())

		if self.entry_add_x.get_text():
			self.xValuePreProcessor.addition = float(self.entry_add_x.get_text())
		if self.entry_add_y.get_text():
			self.yValuePreProcessor.addition = float(self.entry_add_y.get_text())
		
		if self.entry_x_error.get_text():
			self.xValuePreProcessor.errorColumnIndex = int(self.entry_x_error.get_text())
		if self.entry_y_error.get_text():
			self.yValuePreProcessor.errorColumnIndex = int(self.entry_y_error.get_text())
		
		if self.checkbutton_logX.get_active():
			self.xValuePreProcessor.logScale = True
		if self.checkbutton_logY.get_active():
			self.yValuePreProcessor.logScale = True
	
	def processDataValue(self, value=None, valuePreProcessor=None):
		"""
		2014.07.31
		"""
		
		if valuePreProcessor.na is not None and (value==valuePreProcessor.na or float(value)==float(valuePreProcessor.na)):
			return None
		value = float(value)
		if valuePreProcessor.scalar is not None:
			value = value*valuePreProcessor.scalar
		if valuePreProcessor.addition is not None:
			value = value + valuePreProcessor.addition
		return value
	
	def decorateAxisLabel(self, label=None, valuePreProcessor=None):
		"""
		2014.07.31
		"""
		if valuePreProcessor.scalar is not None:
			label = "%s*%s"%(valuePreProcessor.scalar, label)
		if valuePreProcessor.addition:
			label = "%s+%s"%(label, valuePreProcessor.addition)
		return label
	
	def plotXY(self, ax, canvas, liststore, plot_title='', 
			chosen_index_ls=[]):
		"""
		2015.01.28 add summary stats to title
		2014.04.29 add error bars
		2009-3-13
			rename plot_NA_mismatch_rate to plotXY()
		2008-02-05
			chosen_index => chosen_index_ls
		2007-12-14
		"""
		x_column = int(self.entry_x_column.get_text())
		y_column = int(self.entry_y_column.get_text())
		self.setUserDataPreprocessingFlags()   
		
		plot_title = self.entry_plot_title.get_text()
		
		min_x = 1
		min_y = 1
		max_x = 0
		max_y = 0
		
		x_ls = []
		x_error_ls = []
		y_ls = []
		y_error_ls = []
		
		x_chosen_ls = []
		x_chosen_error_ls = []
		y_chosen_ls = []
		y_chosen_error_ls = []
		
		chosen_index_set = set(chosen_index_ls)
		for i in range(len(liststore)):
			row = liststore[i]
			x = row[x_column]
			y = row[y_column]
			if not x or not y:	#2013.07.12 skip if empty cells
				continue
			x = self.processDataValue(x, self.xValuePreProcessor)
			if x is None:
				continue
			y = self.processDataValue(y, self.yValuePreProcessor)
			if y is None:
				continue
			
			if self.xValuePreProcessor.errorColumnIndex is not None:
				x_error = row[self.xValuePreProcessor.errorColumnIndex]
			else:
				x_error = 0
			if self.yValuePreProcessor.errorColumnIndex is not None:
				y_error = row[self.yValuePreProcessor.errorColumnIndex]
			else:
				y_error = 0

			if x<min_x:
				min_x = x
			if x>max_x:
				max_x = x
			if y<min_y:
				min_y = y
			if y>max_y:
				max_y = y
			
			if i in chosen_index_set:
				x_chosen_ls.append(x)
				y_chosen_ls.append(y)
				x_chosen_error_ls.append(x_error)
				y_chosen_error_ls.append(y_error)
			else:
				x_ls.append(x)
				y_ls.append(y)
				x_error_ls.append(x_error)
				y_error_ls.append(y_error)
		
		ax.clear()
		if self.xValuePreProcessor.logScale:
			ax.set_xscale('log')
		if self.yValuePreProcessor.logScale:
			ax.set_yscale('log')
		
		if self.x_error_column_index is not None and self.y_error_column_index is not None:
			ax.errorbar(x_ls, y_ls, xerr=x_error_ls, yerr=y_error_ls, ecolor='g', fmt='o')
		else:
			ax.plot(x_ls, y_ls, '.')
		
		
		"""
		#diagonal line give a rough feeling about the notion, more NA, worse calling
		diagonal_start = min(min_x, min_y)-0.1
		diagonal_end = max(max_x, max_x)+0.1
		ax.plot([diagonal_start, diagonal_end],[diagonal_start, diagonal_end])
		"""
		if x_chosen_ls and y_chosen_ls:	#highlight
			titleWithStats = "Highlighted data\n" + yh_matplotlib.constructTitleFromTwoDataSummaryStat(x_chosen_ls, y_chosen_ls)
			
			ax.plot(x_chosen_ls, y_chosen_ls, '.', c='r')
			if self.x_error_column_index is not None and self.y_error_column_index is not None:
				ax.errorbar(x_chosen_ls, y_chosen_ls, xerr=x_chosen_error_ls, yerr=y_chosen_error_ls, ecolor='r', color='r', fmt='o')
		else:	#take all data
			titleWithStats = yh_matplotlib.constructTitleFromTwoDataSummaryStat(x_ls+x_chosen_ls, y_ls+y_chosen_ls)
		if plot_title:
			ax.set_title("%s %s"%(plot_title, titleWithStats))
		else:
			ax.set_title(titleWithStats)
		
		xlabel = "(%s)"%self.column_header[x_column]
		xlabel = self.decorateAxisLabel(xlabel, self.xValuePreProcessor)
		ax.set_xlabel(xlabel)
		ylabel = "(%s)"%self.column_header[y_column]
		ylabel = self.decorateAxisLabel(ylabel, self.yValuePreProcessor)
		ax.set_ylabel(ylabel)
		canvas.draw()
	
	def plot_row(self, treeview, path, view_column):
		if self._idClick==None:
			self._idClick = self.canvas.mpl_connect('button_press_event', self.onUserClickCanvas)
		self.plotXY(self.ax, self.canvas, self.liststore, self.plot_title, path)
	
	def setupColumns(self, treeview):
		"""
		2009-3-13
		"""
		if not getattr(self, 'column_header', None):
			sys.stderr.write("Nothing in columns yet.\n")
			return
		self.liststore = gtk.ListStore(*self.column_types)
		#self.add_columns(self.treeview_matrix)
		yh_gnome.create_columns(self.treeview_matrix, self.column_header, self.editable_flag_ls, self.liststore)
		yh_gnome.fill_treeview(self.treeview_matrix, self.liststore, self.list_2d, reorderable=True)
		self.treeselection = self.treeview_matrix.get_selection()
	
	def on_button_PlotXY_clicked(self, widget, data=None):
		"""
		2008-02-12
		to update the no_of_selected rows (have to double click a row to change a cursor if it's multiple selection)
		2008-02-05
		"""
		if self._idClick==None:
			self._idClick = self.canvas.mpl_connect('button_press_event', self.onUserClickCanvas)
		pathlist_strains1 = []
		self.treeselection.selected_foreach(yh_gnome.foreach_cb, pathlist_strains1)
		index_ls = []
		for path in pathlist_strains1:
			index_ls.append(path[0])
		self.app1_appbar1.push("%s rows selected."%len(pathlist_strains1))
		self.plotXY(self.ax, self.canvas, self.liststore, self.plot_title, index_ls)
	
	def on_button_save_clicked(self, widget, data=None):
		"""
		2008-02-05
		"""
		self.filechooserdialog_save.show_all()
	
	def on_button_filechooserdialog_cancel_ok_clicked(self, widget, data=None):
		"""
		2008-02-05
		"""
		self.filechooserdialog_save.hide()
	
	def on_button_filechooserdialog_save_ok_clicked(self, widget, data=None):
		"""
		2008-02-12
		to update the no_of_selected rows (have to double click a row to change a cursor if it's multiple selection)
		2008-02-05
		"""
		output_fname = self.filechooserdialog_save.get_filename()
		self.filechooserdialog_save.hide()
		pathlist_strains1 = []
		self.treeselection.selected_foreach(yh_gnome.foreach_cb, pathlist_strains1)
		self.app1_appbar1.push("%s rows selected."%len(pathlist_strains1))
		if self.header and self.strain_acc_list and self.category_list and self.data_matrix:
			selected_index_set = set()
			for path in pathlist_strains1:
				row = self.liststore[path[0]]
				id = row[0]
				index_in_data_matrix = row[-1]
				selected_index_set.add(index_in_data_matrix)
				if self.id_is_strain:
					id = id[1:-1].split(',')	#id is a tuple of (ecotypeid,duplicate)
					self.strain_acc_list[index_in_data_matrix] = id[0].strip()	#remove extra space
					self.category_list[index_in_data_matrix] = id[1].strip()
				#else:
				#	self.header[index_in_data_matrix+2] = id
			FilterStrainSNPMatrix_instance = FilterStrainSNPMatrix()
			if self.id_is_strain:
				rows_to_be_tossed_out = set(range(len(self.strain_acc_list))) - selected_index_set
				FilterStrainSNPMatrix_instance.write_data_matrix(self.data_matrix, output_fname, self.header, self.strain_acc_list, self.category_list,\
								rows_to_be_tossed_out, cols_to_be_tossed_out=set(), nt_alphabet=0)
			else:
				cols_to_be_tossed_out = set(range(len(self.header)-2)) - selected_index_set
				FilterStrainSNPMatrix_instance.write_data_matrix(self.data_matrix, output_fname, self.header, self.strain_acc_list, self.category_list,\
								rows_to_be_tossed_out=set(), cols_to_be_tossed_out=cols_to_be_tossed_out, nt_alphabet=0)
	
	def show_all(self):
		"""
		2008-02-05
			preserve the old interface. in order not to change anything in plot_col_NA_mismatch_rate() and plot_row_NA_mismatch_rate() of QualityControl.py
		"""
		self.app1.show_all()
	
	def on_button_PlotHistogram_clicked(self, widget, data=None):
		"""
		2015.01.28 add summary stats to title
		2009-5-20
			get the number of bins from entry_no_of_bins 
		2009-3-13
			draw histogram of specific hist_column
		2008-02-06
		"""
		if not getattr(self, 'column_header', None):
			sys.stderr.write("Nothing in columns yet.\n")
			return
		self.setUserDataPreprocessingFlags()
		
		self.ax.clear()
		self.canvas.mpl_disconnect(self._idClick)	#drop the signal handler
		self._idClick = None	#reset the _idClick
		hist_ls = []
		hist_column = int(self.entry_hist_column.get_text())
		for i in range(len(self.liststore)):
			x = self.liststore[i][hist_column]
			if not x:
				continue
			x = self.processDataValue(x, self.xValuePreProcessor)
			if x is None:
				continue
			if self.xValuePreProcessor.logScale:
				if x>0:
					x = math.log10(x)
				else:
					sys.stderr.write("x value %s, not good for log10.\n"%(x))
					continue
			hist_ls.append(x)
		title = "%s %s %s"%(self.plot_title, self.column_header[hist_column],
				yh_matplotlib.constructTitleFromDataSummaryStat(hist_ls))
		self.ax.set_title(title);	#"Histogram of %s %s"%(self.plot_title, self.column_header[hist_column]))
		no_of_bins = int(self.entry_no_of_bins.get_text())
		
		#if self.x_logScale:
		#	self.ax.set_xscale('log')
		if self.yValuePreProcessor.logScale:
			self.ax.set_yscale('log')
		
		xlabel = "(%s)"%self.column_header[hist_column]
		xlabel = self.decorateAxisLabel(xlabel, self.xValuePreProcessor)
		if self.xValuePreProcessor.logScale:
			xlabel = "log10(%s)"%(xlabel)
		self.ax.set_xlabel(xlabel)
		self.ax.hist(hist_ls, no_of_bins)
		self.canvas.draw()
	
	def update_no_of_selected(self, treeview, app1_appbar1):
		"""
		2008-02-12
			to update the no_of_selected rows (have to double click a row to change a cursor if it's multiple selection)
		"""
		pathlist_strains1 = []
		self.treeselection.selected_foreach(yh_gnome.foreach_cb, pathlist_strains1)
		app1_appbar1.push("%s rows selected."%len(pathlist_strains1))
		return True
	
	def readInDataToPlot(self, input_fname, sampling_probability=1.0):
		"""
		2015.01.23 added argument sampling_probability to sub-sample data
		2013.07.11 use MatrixFile to read in the file
		2009-5-20
			add the column index into the column header for easy picking
		2009-3-13
			wrap the float conversion part into try...except to report what goes wrong
		2009-3-13
		"""
		if sampling_probability>1 or sampling_probability<0:
			sampling_probability=1.0
		reader = MatrixFile(inputFname=input_fname)
		self.column_header=reader.next()
		for i in range(len(self.column_header)):
			self.column_header[i] = '%s %s'%(i, self.column_header[i])
		no_of_cols = len(self.column_header)
		self.column_types = [str]*2 + [float]*(no_of_cols-2)
		self.column_editable_flag_ls = [True, True] + [False]*(no_of_cols-2)
		self.list_2d = []
		for row in reader:
			if sampling_probability>0 and sampling_probability<1:
				if random.random()>sampling_probability:	#skip
					continue
			float_part = row[2:]
			try:
				float_part = map(float, float_part)
			except:
				sys.stderr.write('Except type: %s\n'%repr(sys.exc_info()))
				traceback.print_exc()
			new_row = row[:2]+float_part
			self.list_2d.append(new_row)
		reader.close()
		self.setupColumns(self.treeview_matrix)
		#update status to reflect the input filename
		self.app1.set_title(os.path.basename(input_fname))
		self.app1_appbar1.push(input_fname)
		self.plotXY(self.ax, self.canvas, self.liststore, self.plot_title)
		
	
	def readInRawMatrixData(self, input_fname):
		"""
		2009-3-13
		"""
		delimiter = figureOutDelimiter(input_fname)
		self.header, self.strain_acc_list, self.category_list, self.data_matrix = read_data(input_fname, delimiter=delimiter)
		
	def on_imagemenuitem_open_activate(self, widget, data=None):
		"""
		2009-3-13
		"""
		self.filechooserdialog_open.show_all()
	
	def on_button_fileopen_cancel_clicked(self, widget, data=None):
		"""
		2015.01.23
		"""
		self.filechooserdialog_open.hide()
		
	
	def on_button_fileopen_ok_clicked(self, widget, data=None):
		"""
		2009-3-13
		"""
		input_fname = self.filechooserdialog_open.get_filename()
		sampling_probability = float(self.entry_sampling_probability.get_text())
		self.filechooserdialog_open.hide()
		self.readInDataToPlot(input_fname, sampling_probability)
	
	def on_entry_plot_title_change(self, widget, data=None):
		"""
		2009-3-13
			upon any change in the entry_plot_title
		"""
		self.plot_title = self.entry_plot_title.get_text()
Example #9
0
 def __init__(self, cube, parent_window, cmap=None):
     gtk.VBox.__init__(self, False)
     
     self.cube = cube
     self._x, self._y, self._z = 0,0,0 # Coordinates of our current view in the cube. Read/write via the .x .y and .z properties
     self.last_drawn_x,self.last_drawn_y, self.last_drawn_z = 0,0,0 # what the coordinates were last time we drew   
     
     fig = matplotlib.figure.Figure()
     self.fig = fig # Save a reference to the figure
     self.axes = fig.add_subplot(111)
     if cmap is None: # Use the default color map:
         #cmap = "spectral"
         cmap = CubeViewWidget.default_cmap 
     self.imgplot = self.axes.imshow(cube.data[:,:,self._z].transpose(1,0), cmap=cmap,vmin=0, vmax=np.nanmax(cube.data))
     self._colorbar = fig.colorbar(self.imgplot) # Add a color scale at the right-hand side
     self.axes.set_xlabel(u"Right Ascension \u03b1")
     self.axes.xaxis.set_major_formatter(self._AxisFormatter(self.cube))
     self.axes.set_ylabel(u"Declination \u03b4")
     self.axes.yaxis.set_major_formatter(self._AxisFormatter(self.cube))
     self.axes.set_ylim(0,cube.data.shape[1])
     
     self._imgplot_highlight = None # An imshow plot of a highlight mask, if any
     self._highlight_mask = None
     
     self.xline = self.axes.axvline(x=self._x, linewidth=4, color="white", alpha=0.5)
     self.yline = self.axes.axhline(y=self._y, linewidth=4, color="white", alpha=0.5)
     
     canvas = FigureCanvasGTKAgg(fig)  # a gtk.DrawingArea
     self.pack_start(canvas)
     
     # The toolbar:
     self.pack_start(gtk.HSeparator(), False,False)
     self.toolbar = self._NavigationToolbar(cube, canvas, parent_window) # parent_window is needed for the "Save image..." file chooser dialog
     self.toolbar.remove(self.toolbar.get_nth_item(6)) # Remove the "Configure subplots" button which causes rendering issues if used
     self.pack_start(self.toolbar, False, False)
     
     canvas.mpl_connect('button_press_event', self._figure_mousedown)
     canvas.mpl_connect('button_release_event', self._figure_mouseup)
     canvas.mpl_connect('motion_notify_event', self._figure_mousemoved)
     self._is_mouse_down = False # is the mouse button currently pressed?
     
     # A list of methods to call when the user clicks on a point. Passes an (x,y,z) tuple and a flux value to each function
     self.click_notify = [] 
     
     # The velocity navigation:
     self.pack_start(gtk.HSeparator(), False,False)
     scale = gtk.HScale()
     self.scale = scale
     scale.set_digits(0)
     self._initialize_scale_element() # Set up the range and marks on the Z slider scale
     scale.set_value(self._z)
     scale.set_draw_value(False)# Hide the built in display of the current value since it's not in real units (not in km/s)
     self.pack_start(scale, False, False)
     scale.connect("value-changed", self._update_velocity)
     
     self.needs_redraw = False # Set this to True if you want the canvas to be repainted
     gtk.idle_add(CubeViewWidget._check_redraw, self) # we only want to re re-drawing when the GUI is idle, for maximum interactivity
     
     self.toolbar.update_mouseout_message()
     
     # A list of "highlighters" that can be used to color in specific
     # areas of the plot:
     self._highlighters = []
Example #10
0
 def _get_canvas(self):
     canvas = FigureCanvas(self.figure)
     canvas.mpl_connect("pick_event", self.on_pick)
     return canvas
Example #11
0
class DataMatrixGuiXYProbe(gtk.Window):
	"""
	2009-3-13
		migrated from QCVisualize.py. now become a standalone program and able to read data from a file and plot ...
		QCVisualize.py inherits from here
	2008-02-05
		embed it into a bigger gnome app, add more buttons, and change the __init__()
	2008-01-01
		class to visualize the results from QualityControl.py
	"""
	def __init__(self, plot_title='', id_is_strain=1, header=None, strain_acc_list=None, category_list=None, data_matrix=None):
		"""
		2008-01-10
			use a paned window to wrap the scrolledwindow and the canvas
			so that the relative size of canvas to the scrolledwindow could be adjusted by the user.
		"""
		prog = gnome.program_init('DataMatrixGuiXYProbe', '0.1')	#this must be called before any initialization for gnome app
		
		program_path = os.path.dirname(__init__.__file__)	#sys.argv[0])
		xml = gtk.glade.XML(os.path.join(program_path, 'DataMatrixGuiXYProbe.glade'))
		xml.signal_autoconnect(self)
		self.app1 = xml.get_widget("app1")
		self.app1.connect("delete_event", gtk.main_quit)
		self.app1.set_default_size(800, 1000)
		self.app1.set_title(plot_title)
		
		self.plot_title = plot_title
		self.id_is_strain = id_is_strain
		self.header = header
		self.strain_acc_list = strain_acc_list
		self.category_list = category_list
		self.data_matrix = data_matrix
		
		self.column_types = None
		self.column_header = None
		self.column_editable_flag_ls = None
		self.list_2d = None
		
		
		self.column_types = None
		self.list_2d = None
		self.column_header = None
		self.editable_flag_ls = None
		
		self.vbox1 = xml.get_widget("vbox1")
		self.treeview_matrix = xml.get_widget("treeview_matrix")
		
		# matplotlib stuff
		fig = Figure(figsize=(8,8))
		self.canvas = FigureCanvas(fig)  # a gtk.DrawingArea
		self._idClick = self.canvas.mpl_connect('button_press_event', self.on_click)
		self.vpaned1 = xml.get_widget("vpaned1")
		self.vpaned1.add2(self.canvas)
		
		#vbox.pack_start(self.canvas, True, True)
		self.ax = fig.add_subplot(111)
		self.treeview_matrix.connect('row-activated', self.plot_row)
		
		toolbar = NavigationToolbar(self.canvas, self.app1)
		self.vbox1.pack_start(toolbar, False, False)
		
		self.checkbutton_label_dot = xml.get_widget('checkbutton_label_dot')
		self.entry_dot_label_column = xml.get_widget('entry_dot_label_column')
		self.entry_x_column = xml.get_widget('entry_x_column')
		self.entry_y_column = xml.get_widget('entry_y_column')
		self.entry_hist_column = xml.get_widget('entry_hist_column')
		self.entry_no_of_bins = xml.get_widget('entry_no_of_bins')	#2009-5-20
		self.entry_plot_title = xml.get_widget('entry_plot_title')
		self.entry_plot_title.set_text(self.plot_title)
		
		self.filechooserdialog_save = xml.get_widget("filechooserdialog_save")
		self.filechooserdialog_save.connect("delete_event", yh_gnome.subwindow_hide)
		
		self.filechooserdialog_open = xml.get_widget("filechooserdialog_open")
		self.filechooserdialog_open.connect("delete_event", yh_gnome.subwindow_hide)
		
		self.app1_appbar1 = xml.get_widget('app1_appbar1')
		self.app1_appbar1.push('Status Message.')	#import gnome.ui has to be executed.
		
		self.treeview_matrix.connect('cursor-changed', self.update_no_of_selected, self.app1_appbar1)
		self.app1.show_all()
		
		#self.add_events(gdk.BUTTON_PRESS_MASK|gdk.KEY_PRESS_MASK|gdk.KEY_RELEASE_MASK)
	
	def on_click(self, event):
		"""
		2009-3-13
			use (x_lim[1]-x_lim[0])/200. as the resolution for a dot to be called identical to a data point.
			similar for the y_data
		2009-3-13
			deal with checkbutton_label_dot, entry_dot_label_column, entry_x_column, entry_y_column
		2008-01-01
			derived from on_click_row() of QualityControl.py
			reaction when user clicked in the plot
		"""
		# get the x and y coords, flip y from top to bottom
		x, y = event.x, event.y
		to_label_dot = self.checkbutton_label_dot.get_active()
		dot_label_column = int(self.entry_dot_label_column.get_text())
		x_column = int(self.entry_x_column.get_text())
		y_column = int(self.entry_y_column.get_text())
		x_lim = self.ax.get_xlim()
		x_grain_size = (x_lim[1]-x_lim[0])/200.
		y_lim = self.ax.get_ylim()
		y_grain_size = (y_lim[1]-y_lim[0])/200.
		if event.button==1:
			if event.inaxes is not None:
				print 'data coords', event.xdata, event.ydata
				for row in self.list_2d:
					x_data = row[x_column]
					y_data = row[y_column]
					if abs(x_data-event.xdata)<x_grain_size and abs(y_data-event.ydata)<y_grain_size:
						info = row[dot_label_column]
						if to_label_dot:
							self.ax.text(event.xdata, event.ydata, info, size=8)
							self.canvas.draw()
						sys.stderr.write("%s: %s, %s: %s, xy=(%s, %s), info: %s.\n"%(self.column_header[0], row[0], self.column_header[1], row[1], x_data, y_data, info))
	
	def plotXY(self, ax, canvas, liststore, plot_title='', chosen_index_ls=[]):
		"""
		2009-3-13
			rename plot_NA_mismatch_rate to plotXY()
		2008-02-05
			chosen_index => chosen_index_ls
		2007-12-14
		"""
		x_column = int(self.entry_x_column.get_text())
		y_column = int(self.entry_y_column.get_text())
		plot_title = self.entry_plot_title.get_text()
		
		min_x = 1
		min_y = 1
		max_x = 0
		max_y = 0
		
		x_ls = []
		y_ls = []
		x_chosen_ls = []
		y_chosen_ls = []
		from sets import Set
		chosen_index_set = Set(chosen_index_ls)
		for i in range(len(liststore)):
			row = liststore[i]
			x = row[x_column]
			y = row[y_column]
			if x<min_x:
				min_x = x
			if x>max_x:
				max_x = x
			if y<min_y:
				min_y = y
			if y>max_y:
				max_y = y
			if i in chosen_index_set:
				x_chosen_ls.append(x)
				y_chosen_ls.append(y)
			else:
				x_ls.append(x)
				y_ls.append(y)
		ax.clear()
		ax.plot(x_ls, y_ls, '.')
		
		"""
		#diagonal line give a rough feeling about the notion, more NA, worse calling
		diagonal_start = min(min_x, min_y)-0.1
		diagonal_end = max(max_x, max_x)+0.1
		ax.plot([diagonal_start, diagonal_end],[diagonal_start, diagonal_end])
		"""
		if x_chosen_ls and y_chosen_ls:	#highlight
			ax.plot(x_chosen_ls, y_chosen_ls, '.', c='r')
		if plot_title:
			ax.set_title(plot_title)
		ax.set_xlabel(self.column_header[x_column])
		ax.set_ylabel(self.column_header[y_column])
		canvas.draw()
	
	def plot_row(self, treeview, path, view_column):
		if self._idClick==None:
			self._idClick = self.canvas.mpl_connect('button_press_event', self.on_click)
		self.plotXY(self.ax, self.canvas, self.liststore, self.plot_title, path)
	
	def setupColumns(self, treeview):
		"""
		2009-3-13
		"""
		if not getattr(self, 'column_header', None):
			sys.stderr.write("Nothing in columns yet.\n")
			return
		self.liststore = gtk.ListStore(*self.column_types)
		#self.add_columns(self.treeview_matrix)
		yh_gnome.create_columns(self.treeview_matrix, self.column_header, self.editable_flag_ls, self.liststore)
		yh_gnome.fill_treeview(self.treeview_matrix, self.liststore, self.list_2d, reorderable=True)
		self.treeselection = self.treeview_matrix.get_selection()
	
	def on_button_highlight_clicked(self, widget, data=None):
		"""
		2008-02-12
		to update the no_of_selected rows (have to double click a row to change a cursor if it's multiple selection)
		2008-02-05
		"""
		if self._idClick==None:
			self._idClick = self.canvas.mpl_connect('button_press_event', self.on_click)
		pathlist_strains1 = []
		self.treeselection.selected_foreach(yh_gnome.foreach_cb, pathlist_strains1)
		index_ls = []
		for path in pathlist_strains1:
			index_ls.append(path[0])
		self.app1_appbar1.push("%s rows selected."%len(pathlist_strains1))
		self.plotXY(self.ax, self.canvas, self.liststore, self.plot_title, index_ls)
	
	def on_button_save_clicked(self, widget, data=None):
		"""
		2008-02-05
		"""
		self.filechooserdialog_save.show_all()
	
	def on_button_filechooserdialog_cancel_ok_clicked(self, widget, data=None):
		"""
		2008-02-05
		"""
		self.filechooserdialog_save.hide()
	
	def on_button_filechooserdialog_save_ok_clicked(self, widget, data=None):
		"""
		2008-02-12
		to update the no_of_selected rows (have to double click a row to change a cursor if it's multiple selection)
		2008-02-05
		"""
		output_fname = self.filechooserdialog_save.get_filename()
		self.filechooserdialog_save.hide()
		pathlist_strains1 = []
		self.treeselection.selected_foreach(yh_gnome.foreach_cb, pathlist_strains1)
		self.app1_appbar1.push("%s rows selected."%len(pathlist_strains1))
		if self.header and self.strain_acc_list and self.category_list and self.data_matrix:
			selected_index_set = Set()
			for path in pathlist_strains1:
				row = self.liststore[path[0]]
				id = row[0]
				index_in_data_matrix = row[-1]
				selected_index_set.add(index_in_data_matrix)
				if self.id_is_strain:
					id = id[1:-1].split(',')	#id is a tuple of (ecotypeid,duplicate)
					self.strain_acc_list[index_in_data_matrix] = id[0].strip()	#remove extra space
					self.category_list[index_in_data_matrix] = id[1].strip()
				#else:
				#	self.header[index_in_data_matrix+2] = id
			from variation.src.FilterStrainSNPMatrix import FilterStrainSNPMatrix
			FilterStrainSNPMatrix_instance = FilterStrainSNPMatrix()
			if self.id_is_strain:
				rows_to_be_tossed_out = Set(range(len(self.strain_acc_list))) - selected_index_set
				FilterStrainSNPMatrix_instance.write_data_matrix(self.data_matrix, output_fname, self.header, self.strain_acc_list, self.category_list,\
								rows_to_be_tossed_out, cols_to_be_tossed_out=Set(), nt_alphabet=0)
			else:
				cols_to_be_tossed_out = Set(range(len(self.header)-2)) - selected_index_set
				FilterStrainSNPMatrix_instance.write_data_matrix(self.data_matrix, output_fname, self.header, self.strain_acc_list, self.category_list,\
								rows_to_be_tossed_out=Set(), cols_to_be_tossed_out=cols_to_be_tossed_out, nt_alphabet=0)
	
	def show_all(self):
		"""
		2008-02-05
			preserve the old interface. in order not to change anything in plot_col_NA_mismatch_rate() and plot_row_NA_mismatch_rate() of QualityControl.py
		"""
		self.app1.show_all()
	
	def on_button_histogram_clicked(self, widget, data=None):
		"""
		2009-5-20
			get the number of bins from entry_no_of_bins 
		2009-3-13
			draw histogram of specific hist_column
		2008-02-06
		"""
		if not getattr(self, 'column_header', None):
			sys.stderr.write("Nothing in columns yet.\n")
			return
		self.ax.clear()
		self.canvas.mpl_disconnect(self._idClick)	#drop the signal handler
		self._idClick = None	#reset the _idClick
		hist_ls = []
		hist_column = int(self.entry_hist_column.get_text())
		for i in range(len(self.liststore)):
			hist_ls.append(self.liststore[i][hist_column])
		self.ax.set_title("Histogram of %s %s"%(self.plot_title, self.column_header[hist_column]))
		no_of_bins = int(self.entry_no_of_bins.get_text())
		self.ax.hist(hist_ls, no_of_bins)
		self.canvas.draw()
	
	def update_no_of_selected(self, treeview, app1_appbar1):
		"""
		2008-02-12
			to update the no_of_selected rows (have to double click a row to change a cursor if it's multiple selection)
		"""
		pathlist_strains1 = []
		self.treeselection.selected_foreach(yh_gnome.foreach_cb, pathlist_strains1)
		app1_appbar1.push("%s rows selected."%len(pathlist_strains1))
		return True
	
	def readInDataToPlot(self, input_fname):
		"""
		2009-5-20
			add the column index into the column header for easy picking
		2009-3-13
			wrap the float conversion part into try...except to report what goes wrong
		2009-3-13
		"""
		reader = csv.reader(open(input_fname), delimiter=figureOutDelimiter(input_fname))
		self.column_header=reader.next()
		for i in range(len(self.column_header)):
			self.column_header[i] = '%s %s'%(i, self.column_header[i])
		no_of_cols = len(self.column_header)
		self.column_types = [str]*2 + [float]*(no_of_cols-2)
		self.column_editable_flag_ls = [True, True] + [False]*(no_of_cols-2)
		self.list_2d = []		
		for row in reader:
			float_part = row[2:]
			try:
				float_part = map(float, float_part)
			except:
				sys.stderr.write('Except type: %s\n'%repr(sys.exc_info()))
				traceback.print_exc()
			new_row = row[:2]+float_part
			self.list_2d.append(new_row)
		self.setupColumns(self.treeview_matrix)
		self.plotXY(self.ax, self.canvas, self.liststore, self.plot_title)
	
	def readInRawMatrixData(self, input_fname):
		"""
		2009-3-13
		"""
		delimiter = figureOutDelimiter(input_fname)
		self.header, self.strain_acc_list, self.category_list, self.data_matrix = read_data(input_fname, delimiter=delimiter)
		
	def on_imagemenuitem_open_activate(self, widget, data=None):
		"""
		2009-3-13
		"""
		self.filechooserdialog_open.show_all()
	
	def on_button_fileopen_ok_clicked(self, widget, data=None):
		"""
		2009-3-13
		"""
		input_fname = self.filechooserdialog_open.get_filename()
		self.filechooserdialog_open.hide()
		self.readInDataToPlot(input_fname)
	
	def on_entry_plot_title_change(self, widget, data=None):
		"""
		2009-3-13
			upon any change in the entry_plot_title
		"""
		self.plot_title = self.entry_plot_title.get_text()
Example #12
0
class TesiDogs:
	"""This is the application main class - there is only one class because socialists don't believe in the class system."""
    
	def __init__(self):
	    self.builder = gtk.Builder()
	    self.builder.add_from_file("tesidog.glade")
	    dic = {"mainwindowdestroy" : gtk.main_quit, "fwdbtnclicked" : self.LoadNextFrame, "backbtnclicked" : self.LoadPreviousFrame, "file1fileset":self.FileLoad, "zoomoutbtnclicked": self.ZoomOut, "zoominbtnclicked":self.ZoomIn, "panleftbtnclicked":self.PanLeft, "panrightbtnclicked":self.PanRight, "pandownbtnclicked":self.PanDown, "panupbtnclicked":self.PanUp, "mainwindowkeypress":self.GetKeyPress, "basebtnclicked":self.BaseButtonClicked, "tailbtnclicked":self.TailButtonClicked, "nolinebtnclicked":self.NoLineButtonClicked, "drawtailendbtnclicked":self.DrawTailEndButtonClicked, "autorunbtnclicked":self.AutorunButtonClicked, "pklchoosefileset":self.PickleFileSet, "imagesavebtnclicked":self.ShowImageSaveDialog, "imagesaveokbtnclicked":self.SaveImageOkButtonClicked, "imagesavecancelbtnclicked":self.SaveImageCancelButtonClicked, "copytailbasepointbtnclicked":self.ShowCopyDialog, "copybaselinebtnclicked":self.ShowCopyDialog, "copyokbtnclicked":self.CopyOkButtonClicked, "copycancelbtnclicked":self.CopyCancelButtonClicked}
	    self.builder.connect_signals(dic)

	    self.conid=self.builder.get_object("statusbar").get_context_id("maps")        
	    self.curid=None

	    self.copybtn=None
	    filterplot2 = gtk.FileFilter()
	    filterplot2.set_name("PKL")
	    filterplot2.add_pattern("*.pkl")
	    filterplot2.add_pattern("*.PKL")

	    self.builder.get_object("pklchoose").add_filter(filterplot2)
	    self.images=[]
	    self.clickstate="none"
            self.linewidth=3.
	    self.circleradius=2
	    self.circlealpha=0.4
	    self.taillinealpha=0.7
	    self.points=[]
	    self.currentbase1=None
	    self.currentbase2=None
	    self.currenttail1=None
	    self.baseline=None
	    self.hoverline=None
	    self.tailline=None
            self.paraline=None
            self.autorun=True
            self.datafile=None
            self.datastr=None
	    self.builder.get_object("autorunbtn").set_sensitive(0)
	    self.builder.get_object("toolbar1").set_sensitive(0)
	    self.builder.get_object("pklchoose").set_sensitive(0)
            self.origin="lower"
            now = datetime.datetime.now()
            self.timestr=now.strftime("%d_%m_%H%M")
            self.textbuffer=gtk.TextBuffer()
            self.builder.get_object("dataview").set_buffer(self.textbuffer)
	def ClearLines(self):
		self.axis.clear()
		self.hoverline=None
		self.tailline=None

	def FileLoad(self, widget):
	        self.points=[]
		self.folder=widget.get_filenames()[0] #get full path
		self.filenames = os.listdir(self.folder)
		i=0
		while i<len(self.filenames):
			if self.filenames[i][-3:]!="BMP" and self.filenames[i][-3:]!="bmp":
				self.filenames.pop(i)
			else:
				self.filenames[i]=self.folder+"/"+self.filenames[i]
				i+=1

		if len(self.filenames)==0:
			if self.curid!=None:
				self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
			self.curid=self.builder.get_object("statusbar").push(self.conid, "Error: No BMPs in given folder!")
			return 0
		self.filenames.sort()


                try:
                    self.datafilename=self.filenames[0].split("/")[-1].split("_")[0]+self.timestr+".dat"
                except:
                    self.datafilename=self.filenames[0].split("/")[-1].split(".")[0]+self.timestr+".dat"
                self.builder.get_object("toolbar1").set_sensitive(1)
                if (self.filenames[0].split(".")[-1]=="bmp") or (self.filenames[0].split(".")[-1]=="BMP"):
                    self.origin="lower"
                else:
                    self.origin="upper"
        #Reset other data here - TODO
		for filen in self.filenames: #no faster
			self.images.append(mpimg.imread(filen))
		self.figure=Figure()
		self.axis=self.figure.add_subplot(111)
		img=mpimg.imread(self.filenames[0])
		self.frame=0
		self.points.append({"base1":None, "base2":None, "tail1":None, "tail2":None, "angle":None, "side":None, "topbottom":None, "length":None})
		self.axis.imshow(img, origin=self.origin)
		self.canvas=FigureCanvasGTKAgg(self.figure)
		self.canvas.show()
		self.canvas.mpl_connect('motion_notify_event', self.HoverOnImage)
		self.canvas.mpl_connect('button_release_event', self.CaptureClick)
		self.builder.get_object("npbox").pack_start(self.canvas, True, True)
                self.builder.get_object("pklchoose").set_sensitive(1)
		self.SetClickState("base1")
		self.UpdateInstructions("Zoom in and click two points along the dog's feet to draw the base line")
	def LoadNextFrame(self, widget):
		xlims=self.axis.get_xlim()
		ylims=self.axis.get_ylim()
        #Load next frame

		self.ClearLines()
		self.frame+=1

                if self.curid!=None:
                    self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
                self.curid=self.builder.get_object("statusbar").push(self.conid, 'Click mode: "'+self.clickstate+'". Autorun: ' + str(self.autorun) + '. Frame: '+ str(self.frame+1) + "/" + str(len(self.filenames)) +".")



		if (self.frame >= len(self.points)): #if image unseen, prepare dictionary - this code disallows skipping, assumption is the mother of all fuckups
			self.points.append({"base1":self.currentbase1, "base2":self.currentbase2, "tail1":self.currenttail1, "tail2":None, "angle":None, "side":None, "topbottom":None, "length":None})

		img=self.images[self.frame]
		self.axis.imshow(img, origin=self.origin)
		self.axis.set_xlim(left=xlims[0], right=xlims[1])
		self.axis.set_ylim(top=ylims[1], bottom=ylims[0])


		if self.points[self.frame]["base2"] != None: #if already line, draw that one
			self.baseline = lines.Line2D(np.array([self.points[self.frame]["base1"][0],self.points[self.frame]["base2"][0]]), np.array([self.points[self.frame]["base1"][1],self.points[self.frame]["base2"][1]]), lw=self.linewidth, color='r', alpha=0.9)
                        self.currentbase1=(self.points[self.frame]["base1"][0], self.points[self.frame]["base1"][1])
                        self.currentbase2=(self.points[self.frame]["base2"][0], self.points[self.frame]["base2"][1])
			self.axis.add_line(self.baseline)
                        self.DrawParallelLine()


		elif (self.points[self.frame]["base2"] == None) and (self.currentbase2!=None): #if not line, use previous one, don't think this is ever run
			self.baseline = lines.Line2D(np.array([self.currentbase1[0],self.currentbase2[0]]), np.array([self.currentbase1[1],self.currentbase2[1]]), lw=self.linewidth, color='r', alpha=0.9)
			self.axis.add_line(self.baseline)
                        self.DrawParallelLine()

                if self.clickstate=="none":
                    self.UpdateInstructions("Browsing mode. Use toolbar buttons to edit points. Autorun disabled. Frame " + str(self.frame+1) + "/" + str(len(self.filenames)))
                    if self.points[self.frame]["tail2"] != None: #if already line, draw that one
			self.tailline = lines.Line2D(np.array([self.points[self.frame]["tail1"][0],self.points[self.frame]["tail2"][0]]), np.array([self.points[self.frame]["tail1"][1],self.points[self.frame]["tail2"][1]]), lw=self.linewidth, color='b', alpha=self.taillinealpha)
			self.axis.add_line(self.tailline)
                        self.currenttail1=(self.points[self.frame]["tail1"][0], self.points[self.frame]["tail1"][1]) #bad hack to fix parallel line
                    if (self.frame-1>=0):
                        self.builder.get_object("backbtn").set_sensitive(1)
                    else:
                        self.builder.get_object("backbtn").set_sensitive(0)                            

                    if (len(self.filenames)<=self.frame+1):
                        self.builder.get_object("fwdbtn").set_sensitive(0)
                    else:
                        self.builder.get_object("fwdbtn").set_sensitive(1)     
                    
		self.canvas.draw()

        

	def LoadPreviousFrame(self, widget):
		xlims=self.axis.get_xlim()
		ylims=self.axis.get_ylim()
        #Load next frame


		self.ClearLines()
		self.frame-=1
		img=self.images[self.frame]
		self.axis.imshow(img, origin=self.origin)
		self.axis.set_xlim(left=xlims[0], right=xlims[1])
		self.axis.set_ylim(top=ylims[1], bottom=ylims[0])

                if self.curid!=None:
                    self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
                self.curid=self.builder.get_object("statusbar").push(self.conid, 'Click mode: "'+self.clickstate+'". Autorun: ' + str(self.autorun) + '. Frame: '+ str(self.frame+1) + "/" + str(len(self.filenames)) +".")

                if self.points[self.frame]["base2"] != None: #if already line, draw that one
                    self.baseline = lines.Line2D(np.array([self.points[self.frame]["base1"][0],self.points[self.frame]["base2"][0]]), np.array([self.points[self.frame]["base1"][1],self.points[self.frame]["base2"][1]]), lw=self.linewidth, color='r', alpha=0.9)
                    self.axis.add_line(self.baseline)
                    self.currentbase1=(self.points[self.frame]["base1"][0], self.points[self.frame]["base1"][1])
                    self.currentbase2=(self.points[self.frame]["base2"][0], self.points[self.frame]["base2"][1])
                    self.DrawParallelLine()

                if self.clickstate=="none":
                    self.UpdateInstructions("Browsing mode. Use toolbar buttons to edit points. Autorun disabled. Frame " + str(self.frame+1) + "/" + str(len(self.filenames)))
                    if self.points[self.frame]["tail2"] != None: #if already line, draw that one
			self.tailline = lines.Line2D(np.array([self.points[self.frame]["tail1"][0],self.points[self.frame]["tail2"][0]]), np.array([self.points[self.frame]["tail1"][1],self.points[self.frame]["tail2"][1]]), lw=self.linewidth, color='b', alpha=self.taillinealpha)
			self.axis.add_line(self.tailline)
                        self.currenttail1=(self.points[self.frame]["tail1"][0], self.points[self.frame]["tail1"][1]) #bad hack to fix parallel line

                    if (len(self.filenames)<=self.frame+1):
                        self.builder.get_object("fwdbtn").set_sensitive(0)
                    else:
                        self.builder.get_object("fwdbtn").set_sensitive(1)
	    
                    if (self.frame-1<0):
                        self.builder.get_object("backbtn").set_sensitive(0)
                    else:
                        self.builder.get_object("backbtn").set_sensitive(1)
                            
		self.canvas.draw()
        
	def HoverOnImage(self, event):
		if event.x!=None and event.y!=None and event.xdata!=None and event.ydata!=None:
			if self.curid!=None:
				self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
			self.curid=self.builder.get_object("statusbar").push(self.conid, 'Click mode: "'+self.clickstate+'", Autorun: ' + str(self.autorun) + '. Frame: '+ str(self.frame+1) + "/" + str(len(self.filenames)) + '. x=%d, y=%d'%(int(round(event.xdata)), int(round(event.ydata))))
			if self.clickstate=="base2":
				if self.hoverline==None:
					self.hoverline = lines.Line2D(np.array([self.points[self.frame]["base1"][0],int(round(event.xdata))]), np.array([self.points[self.frame]["base1"][1],int(round(event.ydata))]), lw=self.linewidth, color='y', alpha=0.5)
					self.axis.add_line(self.hoverline)
				else:
					self.hoverline.set_data(np.array([self.points[self.frame]["base1"][0],int(round(event.xdata))]), np.array([self.points[self.frame]["base1"][1],int(round(event.ydata))]))
				self.canvas.draw()

			if self.clickstate=="tail2":
				if self.hoverline==None:
					self.hoverline = lines.Line2D(np.array([self.points[self.frame]["tail1"][0],int(round(event.xdata))]), np.array([self.points[self.frame]["tail1"][1],int(round(event.ydata))]), lw=self.linewidth, color='y', alpha=0.5)
					self.axis.add_line(self.hoverline)
				else:
					self.hoverline.set_data(np.array([self.points[self.frame]["tail1"][0],int(round(event.xdata))]), np.array([self.points[self.frame]["tail1"][1],int(round(event.ydata))]))
				self.canvas.draw()
        


	def ZoomIn(self, widget):
		xlims=self.axis.get_xlim()
		ylims=self.axis.get_ylim()
		xchange=abs(xlims[1]-xlims[0])*0.1
		ychange=abs(ylims[1]-ylims[0])*0.1
		self.axis.set_xlim(left=xlims[0]+xchange, right=xlims[1]-xchange)
		self.axis.set_ylim(top=ylims[1]-ychange, bottom=ylims[0]+ychange)
		self.builder.get_object("npbox").remove(self.canvas)
		self.builder.get_object("npbox").pack_start(self.canvas, True, True)
        
	def ZoomOut(self, widget):
		xlims=self.axis.get_xlim()
		ylims=self.axis.get_ylim()
		xchange=abs(xlims[1]-xlims[0])*0.111
		ychange=abs(ylims[1]-ylims[0])*0.111
		self.axis.set_xlim(left=xlims[0]-xchange, right=xlims[1]+xchange)
		self.axis.set_ylim(top=ylims[1]+ychange, bottom=ylims[0]-ychange)
		self.builder.get_object("npbox").remove(self.canvas)
		self.builder.get_object("npbox").pack_start(self.canvas, True, True)

	def PanLeft(self, widget):
		xlims=self.axis.get_xlim()
		xchange=abs(xlims[1]-xlims[0])*0.1
		self.axis.set_xlim(left=xlims[0]-xchange, right=xlims[1]-xchange)
		self.builder.get_object("npbox").remove(self.canvas)
		self.builder.get_object("npbox").pack_start(self.canvas, True, True)

	def PanRight(self, widget):
		xlims=self.axis.get_xlim()
		xchange=abs(xlims[1]-xlims[0])*0.1
		self.axis.set_xlim(left=xlims[0]+xchange, right=xlims[1]+xchange)
		self.builder.get_object("npbox").remove(self.canvas)
		self.builder.get_object("npbox").pack_start(self.canvas, True, True)

	def PanUp(self, widget):
		ylims=self.axis.get_ylim()
		ychange=abs(ylims[1]-ylims[0])*0.1
		self.axis.set_ylim(top=ylims[1]+ychange, bottom=ylims[0]+ychange)
		self.builder.get_object("npbox").remove(self.canvas)
		self.builder.get_object("npbox").pack_start(self.canvas, True, True)
	    
	def PanDown(self, widget):
		ylims=self.axis.get_ylim()
		ychange=abs(ylims[1]-ylims[0])*0.1
		self.axis.set_ylim(top=ylims[1]-ychange, bottom=ylims[0]-ychange)
		self.builder.get_object("npbox").remove(self.canvas)
		self.builder.get_object("npbox").pack_start(self.canvas, True, True)
	    
	def UpdateInstructions(self, message):
		self.builder.get_object("instructions").set_label(message)
		
	def CaptureClick(self, event):
		#self.clickstate can be "none", "base1", "base2", "tail1", "tail2"
		#Datastructure is list of dicts - one list for each frame
		#dict contains  base1 point, base2 point, tail1 point, tail2 point
		#base can be changed per frame but is assumed from previous frame by default
		if self.clickstate=="none":
			return 0
		elif event.x==None or event.y==None or event.xdata==None or event.ydata==None:
			return 0
		elif self.clickstate=="base1":
			self.currentbase1=(int(round(event.xdata)), int(round(event.ydata)))
			self.points[self.frame]["base1"]=(int(round(event.xdata)), int(round(event.ydata)))
			self.SetClickState("base2")
			
		elif self.clickstate=="base2":
			self.currentbase2=(int(round(event.xdata)), int(round(event.ydata)))
			self.points[self.frame]["base2"]=(int(round(event.xdata)), int(round(event.ydata)))

			self.baseline = lines.Line2D(np.array([self.points[self.frame]["base1"][0],self.points[self.frame]["base2"][0]]), np.array([self.points[self.frame]["base1"][1],self.points[self.frame]["base2"][1]]), lw=self.linewidth, color='r', alpha=0.9)
			self.axis.add_line(self.baseline)
			if self.points[self.frame]["tail1"]!=None:
				self.DrawParallelLine()
			self.canvas.draw()
                        if self.points[self.frame]["tail2"]!=None:
                            self.CalculateAngle()
                        if self.autorun==True:
                            self.SetClickState("tail1")
                        elif self.autorun==False:
                            self.SetClickState("none")                           

		elif self.clickstate=="tail1":
			if self.points[self.frame]["tail1"]!=None:
				#point already there, must clear
				already=True
			else:
                                already=False
			self.currenttail1=(int(round(event.xdata)), int(round(event.ydata)))
			self.points[self.frame]["tail1"]=(int(round(event.xdata)), int(round(event.ydata)))
                        self.DrawParallelLine()
                        if self.points[self.frame]["tail2"]!=None:
                            self.CalculateAngle()

			if already==True:
				self.SetClickState("none")
				self.frame=self.frame-1
				self.LoadNextFrame(None)
				
			
			if self.autorun==True:
				self.SetClickState("tail2")
			else:
				self.SetClickState("none")
                        #Draw parallel line and circle


		elif self.clickstate=="tail2":

			self.points[self.frame]["tail2"]=(int(round(event.xdata)), int(round(event.ydata)))
			self.tailline = lines.Line2D(np.array([self.points[self.frame]["tail1"][0],self.points[self.frame]["tail2"][0]]), np.array([self.points[self.frame]["tail1"][1],self.points[self.frame]["tail2"][1]]), lw=self.linewidth, color='b', alpha=0.9)
			self.axis.add_line(self.tailline)
			self.canvas.draw()
                        self.CalculateAngle()
			if (len(self.filenames)<=self.frame+1):
				self.SetClickState("none")
				self.UpdateInstructions("Finished")
			else:
                            if self.autorun==True:
				self.UpdateInstructions("Click the end of the tail. Frame " + str(self.frame+2) + "/" + str(len(self.filenames)))
				self.LoadNextFrame(None)
                            elif self.autorun==False:
                                self.SetClickState("none")


        def DrawParallelLine(self):
            if self.currenttail1==None and self.points[self.frame]["tail1"]==None:
		    return 0
	    if self.currenttail1==None:
		    if self.points[self.frame]["tail1"]==None:
			    return 0;
		    else:
			    self.currenttail1=self.points[self.frame]["tail1"]

	    if self.points[self.frame]["base2"]!=None: #draw actual line
		    if self.points[self.frame]["tail1"]!=None:
			    circle=Circle(self.points[self.frame]["tail1"], radius=self.circleradius, alpha=self.circlealpha, color="yellow") #put here because here has check for tail1
			    basem=(float(self.points[self.frame]["base2"][1]-self.points[self.frame]["base1"][1]))/(float(self.points[self.frame]["base2"][0]-self.points[self.frame]["base1"][0]))
			    c=self.points[self.frame]["base2"][1]-(basem*self.points[self.frame]["base2"][0])
			    ydiff=self.points[self.frame]["tail1"][1]-((basem*self.points[self.frame]["tail1"][0])+c) #fails if points[self.frame]["tail1"]==None - should never be called in this case
			    self.paraline = lines.Line2D(np.array([self.points[self.frame]["base1"][0], self.points[self.frame]["base2"][0]]), np.array([self.points[self.frame]["base1"][1]+ydiff, self.points[self.frame]["base2"][1]+ydiff]), lw=self.linewidth, color='r', alpha=0.3)
		    else:
			    circle=Circle(self.currenttail1, radius=self.circleradius, alpha=self.circlealpha, color="yellow") #put here because here has check for tail1		    
			    basem=(float(self.points[self.frame]["base2"][1]-self.points[self.frame]["base1"][1]))/(float(self.points[self.frame]["base2"][0]-self.points[self.frame]["base1"][0]))
			    c=self.points[self.frame]["base2"][1]-(basem*self.points[self.frame]["base2"][0])
			    ydiff=self.currenttail1[1]-((basem*self.currenttail1[0])+c) #fails if currenttail1==None - should never be called in this case
			    self.paraline = lines.Line2D(np.array([self.points[self.frame]["base1"][0], self.points[self.frame]["base2"][0]]), np.array([self.points[self.frame]["base1"][1]+ydiff, self.points[self.frame]["base2"][1]+ydiff]), lw=self.linewidth, color='r', alpha=0.3)

	    elif self.points[self.frame]["base2"] == None:
		    if self.points[self.frame]["tail1"]!=None:
			    circle=Circle(self.points[self.frame]["tail1"], radius=self.circleradius, alpha=self.circlealpha, color="yellow") #put here because here has check for tail1
			    basem=(float(self.currentbase2[1]-self.currentbase1[1]))/(float(self.currentbase2[0]-self.currentbase1[0]))
			    c=self.currentbase2[1]-(basem*self.currentbase2[0])
			    ydiff=self.points[self.frame]["tail1"][1]-((basem*self.points[self.frame]["tail1"][0])+c) #fails if points[self.frame]["tail1"]==None - should never be called in this case
			    self.paraline = lines.Line2D(np.array([self.currentbase1[0], self.currentbase2[0]]), np.array([self.currentbase1[1]+ydiff, self.currentbase2[1]+ydiff]), lw=self.linewidth, color='r', alpha=0.3)
		    else:
			    circle=Circle(self.currenttail1, radius=self.circleradius, alpha=self.circlealpha, color="yellow") #put here because here has check for tail1		    
			    basem=(float(self.currentbase2[1]-self.currentbase1[1]))/(float(self.currentbase2[0]-self.currentbase1[0]))
			    c=self.currentbase2[1]-(basem*self.currentbase2[0])
			    ydiff=self.currenttail1[1]-((basem*self.currenttail1[0])+c) #fails if currenttail1==None - should never be called in this case
			    self.paraline = lines.Line2D(np.array([self.currentbase1[0], self.currentbase2[0]]), np.array([self.currentbase1[1]+ydiff, self.currentbase2[1]+ydiff]), lw=self.linewidth, color='r', alpha=0.3)


            self.axis.add_line(self.paraline)
	    self.axis.add_patch(circle)
            self.canvas.draw()
            
        def GetKeyPress(self, widget, event):
            if event.keyval==65307: #ESC key pressed
                self.SetClickState("none")

        def SetClickState(self, clickstate):
            if clickstate=="none":
                self.UpdateInstructions("Browsing mode. Use toolbar buttons to edit points. Autorun disabled. Frame " + str(self.frame+1) + "/" + str(len(self.filenames)))
                if self.hoverline!=None: #Remove hover line
                    self.hoverline.set_data(np.array([0,0]),np.array([0,0]))
                    self.canvas.draw()
                    self.hoverline=None

                self.builder.get_object("nolinebtn").set_sensitive(0) #Make noline button insensitive
                self.builder.get_object("basebtn").set_sensitive(1) 
                self.builder.get_object("tailbtn").set_sensitive(1) 
                self.builder.get_object("tailendbtn").set_sensitive(1) 
                self.builder.get_object("copytailbasepointbtn").set_sensitive(1) 
                self.builder.get_object("copybaselinebtn").set_sensitive(1) 
                self.builder.get_object("tailendbtn").set_sensitive(1) 
                #Attempt to make next/prev buttons sensitive
                if (self.frame-1>=0):
                    self.builder.get_object("backbtn").set_sensitive(1)
                if (len(self.filenames)>self.frame+1):
                    self.builder.get_object("fwdbtn").set_sensitive(1)
                self.autorun=False
                self.builder.get_object("autorunbtn").set_sensitive(1)


            elif clickstate=="base1":
                self.UpdateInstructions("Click the first base point. Frame " + str(self.frame+1) + "/" + str(len(self.filenames)))
                if self.baseline!=None:
                    self.baseline.set_data(np.array([0,0]),np.array([0,0]))
                    self.canvas.draw()
                if self.paraline!=None:
                    self.paraline.set_data(np.array([0,0]),np.array([0,0]))
                    self.canvas.draw()
                self.builder.get_object("nolinebtn").set_sensitive(1) 
                self.builder.get_object("basebtn").set_sensitive(0) 
                self.builder.get_object("tailbtn").set_sensitive(0) 
                self.builder.get_object("tailendbtn").set_sensitive(0) 
                self.builder.get_object("backbtn").set_sensitive(0)
                self.builder.get_object("fwdbtn").set_sensitive(0)
                self.builder.get_object("copytailbasepointbtn").set_sensitive(0) 
                self.builder.get_object("copybaselinebtn").set_sensitive(0) 

            elif clickstate=="base2":
                self.UpdateInstructions("Click the second base point. Frame " + str(self.frame+1) + "/" + str(len(self.filenames)))


            elif clickstate=="tail1":
                self.UpdateInstructions("Click the base of the tail on the dog. Frame " + str(self.frame+1) + "/" + str(len(self.filenames)))
                self.builder.get_object("nolinebtn").set_sensitive(1) 
                self.builder.get_object("basebtn").set_sensitive(0) 
                self.builder.get_object("tailbtn").set_sensitive(0) 
                self.builder.get_object("tailendbtn").set_sensitive(0) 

                self.builder.get_object("backbtn").set_sensitive(0)
                self.builder.get_object("fwdbtn").set_sensitive(0)
                self.builder.get_object("copytailbasepointbtn").set_sensitive(0) 
                self.builder.get_object("copybaselinebtn").set_sensitive(0) 

            elif clickstate=="tail2":
                if self.points[self.frame]["tail1"]==None:
                    self.SetClickState("none")
                    if self.curid!=None:
                        self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
                    self.curid=self.builder.get_object("statusbar").push(self.conid, "Error: First tail point not set!")
                    return None
                else:
                    self.UpdateInstructions("Click the end of the tail. Frame " + str(self.frame+1) + "/" + str(len(self.filenames)))
                    if self.tailline!=None:
                        self.tailline.set_data(np.array([0,0]),np.array([0,0]))
                        self.canvas.draw()

                    self.builder.get_object("nolinebtn").set_sensitive(1) 
                    self.builder.get_object("basebtn").set_sensitive(0) 
                    self.builder.get_object("tailbtn").set_sensitive(0) 
                    self.builder.get_object("tailendbtn").set_sensitive(0) 

                    self.builder.get_object("backbtn").set_sensitive(0)
                    self.builder.get_object("fwdbtn").set_sensitive(0)
		    self.builder.get_object("copytailbasepointbtn").set_sensitive(0) 
		    self.builder.get_object("copybaselinebtn").set_sensitive(0) 
                
            #Push changed message to statusbar
            self.clickstate=clickstate
            if self.curid!=None:
                self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
            self.curid=self.builder.get_object("statusbar").push(self.conid, 'Changed click mode to "'+clickstate+'". Autorun: ' + str(self.autorun) + '. Frame: '+ str(self.frame+1) + "/" + str(len(self.filenames)) +".")

        def BaseButtonClicked(self, widget):
            self.SetClickState("base1")
        def TailButtonClicked(self, widget):
            self.SetClickState("tail1")
        def DrawTailEndButtonClicked(self, widget):
            self.SetClickState("tail2")
        def NoLineButtonClicked(self, widget):
            self.SetClickState("none")
        def AutorunButtonClicked(self, widget):
            self.autorun=True
	    self.builder.get_object("autorunbtn").set_sensitive(0)
        def CalculateAngle(self):
            #Angle always measured from normal, above and below
            #Find line between tail2 and tail1
            graderror=False
            try:
                tailm=(float(self.points[self.frame]["tail2"][1]-self.points[self.frame]["tail1"][1]))/(float(self.points[self.frame]["tail2"][0]-self.points[self.frame]["tail1"][0]))
                tailc=self.points[self.frame]["tail2"][1]-(tailm*self.points[self.frame]["tail2"][0])
            except:
                #Assume divide by zero error
                poix=self.points[self.frame]["tail2"][0]
                graderror=True

            try:
                basem=(float(self.points[self.frame]["base2"][1]-self.points[self.frame]["base1"][1]))/(float(self.points[self.frame]["base2"][0]-self.points[self.frame]["base1"][0]))
                basec=self.points[self.frame]["base2"][1]-(basem*self.points[self.frame]["base2"][0])

            except:
                poix=self.points[self.frame]["base2"][0]
                graderror=True
            if graderror==False:
                poix=((tailc-basec)/(basem-tailm))

            try:
                poiy=(basem*poix)+basec
            except:
                poiy=(tailm*poix)+tailc
                #if both fail then divergent

            self.points[self.frame]["angle"]=abs(90-math.degrees(math.acos((((self.points[self.frame]["tail2"][0] - poix)*(self.points[self.frame]["base1"][0] - poix)) + ((self.points[self.frame]["tail2"][1] - poiy)*(self.points[self.frame]["base1"][1] - poiy)))/(math.sqrt( ((math.pow(self.points[self.frame]["tail2"][0] - poix,2)) + (math.pow(self.points[self.frame]["tail2"][1] - poiy,2))) * ( ((math.pow(self.points[self.frame]["base1"][0] - poix,2)) + (math.pow(self.points[self.frame]["base1"][1] - poiy,2))))) ))))

            if ((self.points[self.frame]["tail2"][0]-self.points[self.frame]["tail1"][0])>=0):
                self.points[self.frame]["side"]="R"
            else:
                self.points[self.frame]["side"]="L"
            if ((self.points[self.frame]["tail2"][1]-self.points[self.frame]["tail1"][1])>=0):
                self.points[self.frame]["topbottom"]="T"
            else:
                self.points[self.frame]["topbottom"]="B"
            self.points[self.frame]["length"]=math.sqrt(pow(self.points[self.frame]["tail2"][1]-self.points[self.frame]["tail1"][1],2) + pow(self.points[self.frame]["tail2"][0]-self.points[self.frame]["tail1"][0],2) )

            self.SaveData()
        def SaveData(self):
            #get datastr from dictionary
            #save that, pickle dictionary
            base1xlist=[]
            base1ylist=[]
            base2xlist=[]
            base2ylist=[]
            tail1xlist=[]
            tail1ylist=[]
            tail2xlist=[]
            tail2ylist=[]
            anglelist=[]
            sidelist=[]
            topbottomlist=[]
            lengthlist=[]
            
            for item in self.points:
                try:
                    base1xlist.append(item["base1"][0])
                except:
                     base1xlist.append("NA")                   
                try:
                    base1ylist.append(item["base1"][1])
                except:
                    base1ylist.append("NA")
                try:
                    base2xlist.append(item["base2"][0])
                except:
                    base2xlist.append("NA")
                try:
                    base2ylist.append(item["base2"][1])
                except:
                    base2ylist.append("NA")
                try: 
                    tail1xlist.append(item["tail1"][0])
                except:
                    tail1xlist.append("NA")
                try:
                    tail1ylist.append(item["tail1"][1])
                except:
                    tail1ylist.append("NA")
                try:
                    tail2xlist.append(item["tail2"][0])
                except:
                    tail2xlist.append("NA")
                try:
                    tail2ylist.append(item["tail2"][1])
                except:
                    tail2ylist.append("NA")
                try:
                    if item["angle"]!=None:
			    anglelist.append(item["angle"])
		    else:
			    anglelist.append("NA")
                except:
                    anglelist.append("NA")
                try:
                    if item["side"]!=None:
			    sidelist.append(item["side"])
		    else:
			    sidelist.append("NA")
                except:
                    sidelist.append("NA")
                try:
                    if item["topbottom"]!=None:
			    topbottomlist.append(item["topbottom"])
		    else:
			    topbottomlist.append("NA")
                except:
                    topbottomlist.append("NA")
                try:
                    if item["length"]!=None:
			    lengthlist.append(item["length"])
		    else:
			    lengthlist.append("NA")
                except:
                    lengthlist.append("NA")

            for i in range(len(self.filenames)-len(self.points)):
                base1xlist.append("NA")
                base1ylist.append("NA")
                base2xlist.append("NA")
                base2ylist.append("NA")
                tail1xlist.append("NA")
                tail1ylist.append("NA")
                tail2xlist.append("NA")
                tail2ylist.append("NA")
                anglelist.append("NA")
                sidelist.append("NA")
                topbottomlist.append("NA")
                lengthlist.append("NA")

            self.datastr="id,base1x,base1y,base2x,base2y,tail1x,tail1y,tail2x,tail2y,angle,length,side,topbottom\n"
            for i in range(len(base1xlist)):
                self.datastr+=str(i+1) +","+str(base1xlist[i])+ ","+str(base1ylist[i]) + "," +str(base2xlist[i]) +"," +str(base2ylist[i]) + "," + str(tail1xlist[i]) + "," + str(tail1ylist[i]) + "," + str(tail2xlist[i]) + "," + str(tail2ylist[i]) + "," + str(anglelist[i]) + "," + str(lengthlist[i]) + "," + str(sidelist[i]) + "," + str(topbottomlist[i]) +"\n"
            
            self.textbuffer.set_text(self.datastr)
            self.datafile=open(self.datafilename, "w")
            self.datafile.write(self.datastr)
            self.datafile.close()
            picklefile=open(self.datafilename[:-3]+"pkl", "w")
            pickle.dump(self.points,picklefile)
            picklefile.close()

        def PickleFileSet(self, widget):
            self.SetClickState("none")
            pklfilename=widget.get_filenames()[0]
            try:
                picklefile=open(pklfilename, "r")
                temppoints=pickle.load(picklefile)
                picklefile.close()
            except:
                return 0
	    if len(temppoints)>len(self.filenames):
		    if self.curid!=None:
			    self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
		    self.curid=self.builder.get_object("statusbar").push(self.conid, "Error: PKL file had more frames than frames loaded!")
		    return 0

            self.points=temppoints
            self.datafilename=pklfilename[:-3]+"dat"
            self.SaveData()
	    i=0
	    while i < len(self.points): #hopefully this works, might need to initialise full list
		    if self.points[i]["tail2"]==None:
			    self.frame=i
			    break
		    i+=1

	    if i == len(self.points):
		    if len(self.filenames)>len(self.points):
			    self.frame = len(self.points)
		    else:
			    self.frame=0
	    
            #redraw canvas, load data
            self.frame=self.frame-1
            self.LoadNextFrame(None)
	    if self.frame==0:
		    self.SetClickState("none")
	    else:
		    #assumes these are defined
		    self.currentbase1=(self.points[self.frame-1]["base1"][0], self.points[self.frame-1]["base1"][1])
		    self.currentbase2=(self.points[self.frame-1]["base2"][0], self.points[self.frame-1]["base2"][1])
		    self.currenttail1=(self.points[self.frame-1]["tail1"][0], self.points[self.frame-1]["tail1"][1])

		    if self.points[self.frame]["base1"]==None:
			    self.points[self.frame]["base1"]=self.currentbase1

		    if self.points[self.frame]["base2"]==None:
			    self.points[self.frame]["base2"]=self.currentbase2

		    if self.points[self.frame]["tail1"]==None:
			    self.points[self.frame]["tail1"]=self.currenttail1
		    self.frame=self.frame-1
		    self.LoadNextFrame(None)

		    self.AutorunButtonClicked(None)
		    self.SetClickState("tail2")


	def ShowImageSaveDialog(self, widget):
		self.builder.get_object("imagesavedialog").set_visible(1)

	def SaveImageCancelButtonClicked(self, widget):
		self.builder.get_object("imagesavedialog").set_visible(0)

	def SaveImageOkButtonClicked(self, widget):
		filename=self.builder.get_object("imagesavedialog").get_filenames()[0]
		if filename[-4:]!=".png" and filename[-4:]!=".PNG":
			filename=filename+".png"

		self.figure.savefig(filename, format="png")
		self.builder.get_object("imagesavedialog").set_visible(0)

	def ShowCopyDialog(self, widget):
		self.SetClickState("none")
		if gtk.Buildable.get_name(widget) == "copybaselinebtn":
			self.builder.get_object("copylabel").set_label("From which frame number (1-" + str(len(self.points))+") do you wish to copy the base line?")
			self.copybtn="base"
		else:
			self.builder.get_object("copylabel").set_label("From which frame number (1-" + str(len(self.points))+") do you wish to copy the tail basepoint?")
			self.copybtn="tail"
		self.builder.get_object("copydialog").set_visible(1)
		
	def CopyCancelButtonClicked(self, widget):
		self.builder.get_object("copydialog").set_visible(0)		

	def CopyOkButtonClicked(self, widget):
		try:
			number=int(self.builder.get_object("entry1").get_text())
		except:
			self.builder.get_object("copydialog").set_visible(0)
			if self.curid!=None:
				self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
			self.curid=self.builder.get_object("statusbar").push(self.conid, "Error: Frame number given was not an integer!")
			return 0

		if number>len(self.points) or number<1:
			self.builder.get_object("copydialog").set_visible(0)
			if self.curid!=None:
				self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
			self.curid=self.builder.get_object("statusbar").push(self.conid, "Error: Frame number was not within valid range!")
			return 0
			

		if self.copybtn=="base":
			if self.points[number-1]["base2"]==None:
				self.builder.get_object("copydialog").set_visible(0)
				if self.curid!=None:
					self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
				self.curid=self.builder.get_object("statusbar").push(self.conid, "Error: Frame does not have valid base line!")
				return 0
			else:
				self.builder.get_object("copydialog").set_visible(0)
				self.points[self.frame]["base1"]=self.points[number-1]["base1"]
				self.currentbase1=self.points[number-1]["base1"]
				self.points[self.frame]["base2"]=self.points[number-1]["base2"]
				self.currentbase2=self.points[number-1]["base2"]
				self.frame=self.frame-1
				self.LoadNextFrame(None)
				if self.points[self.frame]["tail2"]!=None:
					self.CalculateAngle()

		if self.copybtn=="tail":
			if self.points[number-1]["tail1"]==None:
				self.builder.get_object("copydialog").set_visible(0)
				if self.curid!=None:
					self.builder.get_object("statusbar").remove_message(self.conid, self.curid)
                
				self.curid=self.builder.get_object("statusbar").push(self.conid, "Error: Frame does not have valid tail basepoint!")
				return 0
			else:
				self.builder.get_object("copydialog").set_visible(0)
				self.points[self.frame]["tail1"]=self.points[number-1]["tail1"]
				self.currenttail1=self.points[number-1]["tail1"]
				self.frame=self.frame-1
				self.LoadNextFrame(None)
				if self.points[self.frame]["tail2"]!=None:
					self.CalculateAngle()

				return 0
Example #13
0
class XratersWindow(gtk.Window):
    __gtype_name__ = "XratersWindow"
    
    def __init__(self):
        """__init__ - This function is typically not called directly.
        Creation a XratersWindow requires redeading the associated ui
        file and parsing the ui definition extrenally,
        and then calling XratersWindow.finish_initializing().

        Use the convenience function NewXratersWindow to create
        XratersWindow object.

        """
        self._acc_cal = ((128, 128, 128),
                         (255, 255, 255))
        self._acc = [0, 0, 0]
        self._connected = False
        self._wiiMote = None
        self._resetData()
        self._dataLock = threading.Lock()
        
    isConnected = property(lambda self: self._connected)
    
    def callback(funct):
        """A decorator used to require connection to the Wii Remote
        
        This decorator is used to implement the precondition that 
        the Wii Remote must be connected. 
        """
        def _callback(cls, *args, **kwds):
            if cls.isConnected:
                funct(cls, *args, **kwds)
                return True
            else:
                return False
        return _callback
    
    def _connectCallback(self, connectionMaker):
        """Callback function called upon successful connection to the Wiimote
        """
        if connectionMaker.connected:
            self._connected = True
            self._wiiMote = connectionMaker.wiiMote
            self._resetData()
            gobject.timeout_add(45, self._drawAcc)
            self.widget('actionDisconnect').set_sensitive(True)
            self.widget('actionSave').set_sensitive(True)
            self.widget('actionReset').set_sensitive(True)
            self.widget('actionPause').set_sensitive(True)
            self.widget('toolbutton1').set_related_action(self.widget('actionDisconnect'))
            self._acc_cal = connectionMaker.acc_cal
            self._wiiMote.mesg_callback = self._getAcc
            self._updBatteryLevel()
            gobject.timeout_add_seconds(60, self._updBatteryLevel)
        else:
            self.widget('actionWiiConnect').set_sensitive(True)
            
    @callback
    def _upd_background(self, event):
        """Keep a copy of the figure background
        """
        self.__background = self._accCanvas.copy_from_bbox(self._accAxis.bbox)
    
    def _getAcc(self, messages, theTime=0):
        """Process acceleration messages from the Wiimote
        
        This function is intended to be set as cwiid.mesg_callback
        """
        if self._Paused:
            return
        for msg in messages:
            if msg[0] == cwiid.MESG_ACC:
                # Normalize data using calibration info
                for i, axisAcc in enumerate(msg[1]):
                    self._acc[i] = float(axisAcc-self._acc_cal[0][i])
                    self._acc[i] /=(self._acc_cal[1][i]\
                                    -self._acc_cal[0][i])
                with self._dataLock:
                    # Store time and acceleration in the respective arrays
                    self._time.append(theTime-self._startTime)
                    [self._accData[i].append(self._acc[i]) for i in threeAxes]
                # We only keep about 6 seconds worth of data
                if (self._time[-1] - self._time[0] > 6):
                    with self._dataLock:
                        self._time.pop(0)
                        [self._accData[i].pop(0) for i in threeAxes]

    @callback
    def _drawAcc(self):
        """Update the acceleration graph
        
        """
        # Do nothing while paused or there's no data available
        if self._Paused or len(self._time)==0:
            return
        draw_flag = False
        # Update axes limits if the data fall out of range 
        lims = self._accAxis.get_xlim()
        if self._time[-1] > lims[1]:
            self._accAxis.set_xlim(lims[0], lims[1]+2)
            lims = self._accAxis.get_xlim()
            draw_flag = True
        if (self._time[-1] - lims[0] > 6):
            self._accAxis.set_xlim(lims[0]+2, lims[1])
            draw_flag = True
        if draw_flag:
            gobject.idle_add(self._accCanvas.draw)
        # Do the actual update of the background
        if self.__background != None:
            self._accCanvas.restore_region(self.__background)
        # Do the actual update of the lines
        with self._dataLock:
            [self._lines[i].set_data(self._time, self._accData[i]) for i in threeAxes]
        [self._accAxis.draw_artist(self._lines[i]) for i in threeAxes]
        self._accCanvas.blit(self._accAxis.bbox)

    @callback
    def _updBatteryLevel(self):
        """Callback to update the battery indicator in the status bar
        
        """
        self._wiiMote.request_status()
        self._setBatteryIndicator(float(self._wiiMote.state['battery']) / 
                                  cwiid.BATTERY_MAX)
        
    def _setBatteryIndicator(self, level):
        """Actually update the battery indicator in the status bar
        
        """
        progressBar = self.widget("progressbarBattery")
        progressBar.set_fraction(level)
        progressBar.set_text("Battery: %.0f%%" % (level * 100))
    
    def _resetData(self):
        """Reset stored data and status flags to their defaults
        
        """
        self._accData = [list(), list(), list()]
        self._time = list()
        self._startTime = time.time()
        self._moveTime = self._startTime
        self._Paused = False
        
    def widget(self, name):
        """Helper function to retrieve widget handlers
        
        """ 
        return self.builder.get_object(name)

    def finish_initializing(self, builder):
        """finish_initalizing should be called after parsing the ui definition
        and creating a XratersWindow object with it in order to finish
        initializing the start of the new XratersWindow instance.

        """
        #get a reference to the builder and set up the signals
        self.builder = builder
        self.builder.connect_signals(self)
        
        #uncomment the following code to read in preferences at start up
        dlg = PreferencesXratersDialog.NewPreferencesXratersDialog()
        self.preferences = dlg.get_preferences()

        #code for other initialization actions should be added here
        self._accFigure = Figure(figsize=(8,6), dpi=72)
        self._accAxis = self._accFigure.add_subplot(111)
        self._accAxis.set_xlabel("time (s)")
        self._accAxis.set_ylabel("acceleration (g)")
        self._lines = self._accAxis.plot(self._time, self._accData[X],
                                         self._time, self._accData[Y],
                                         self._time, self._accData[Z], 
                                         animated=True)
        self._accFigure.legend(self._lines, ("X", "Y", "Z"), 
                             'upper center', 
                             ncol=3)
        self._accAxis.set_xlim(0, 2)
        self._accAxis.set_ylim(-3, 3)
        self._accCanvas = FigureCanvas(self._accFigure)
        self._accCanvas.mpl_connect("draw_event", self._upd_background)
        self.__background = self._accCanvas.copy_from_bbox(self._accAxis.bbox)
        self._accCanvas.show()
        self._accCanvas.set_size_request(600, 400)
        vbMain = self.widget("vboxMain")
        vbMain.pack_start(self._accCanvas, True, True)
        vbMain.show()
        vbMain.reorder_child(self._accCanvas, 2)
        self._setBatteryIndicator(0)
        
    def about(self, widget, data=None):
        """about - display the about box for xraters """
        about = AboutXratersDialog.NewAboutXratersDialog()
        response = about.run()
        about.destroy()

    def preferences(self, widget, data=None):
        """preferences - display the preferences window for xraters """
        prefs = PreferencesXratersDialog.NewPreferencesXratersDialog()
        response = prefs.run()
        if response == gtk.RESPONSE_OK:
            #make any updates based on changed preferences here
            self.preferences = prefs.get_preferences()
        prefs.destroy()

    def quit(self, widget, data=None):
        """quit - signal handler for closing the XratersWindow"""
        self.destroy()

    def on_destroy(self, widget, data=None):
        """on_destroy - called when the XratersWindow is close. """
        #clean up code for saving application state should be added here
        if self.isConnected:
            self.on_wiiDisconnect(widget, data)
        gtk.main_quit()
        
    def on_wiiConnect(self, widget, data=None):
        """Signal handler for the WiiConnect action
        
        """
        self.widget('actionWiiConnect').set_sensitive(False)
        connectionMaker = WiiConnectionMaker(self.preferences['wiiAddress'],
                                             self.widget("statusbar"),
                                             self._connectCallback)
        self._accAxis.set_xlim(0, 2)
        gobject.idle_add(self._accCanvas.draw)
        connectionMaker.start()
        
    def on_wiiDisconnect(self, widget, data=None):
        """Signal handler for the WiiDisconnect action
        
        """
        self._wiiMote.close()
        self._connected = False
        self.widget('actionDisconnect').set_sensitive(False)
        self.widget('actionWiiConnect').set_sensitive(True)
        self.widget('actionReset').set_sensitive(False)
        self.widget('actionPause').set_sensitive(False)
        self.widget('toolbutton1').set_related_action(self.widget('actionWiiConnect'))
        self.widget('actionSave').set_sensitive(True)
        self.widget('statusbar').pop(self.widget("statusbar").get_context_id(''))
        self._setBatteryIndicator(0)
        
    def on_Reset(self, widget, data=None):
        """Signal handler for the reset action
        
        """
        self._resetData()
        self._accAxis.set_xlim(0, 2)
        gobject.idle_add(self._accCanvas.draw)
        
    def on_Pause(self, widge, data=None):
        """Signal handler for the pause action
        
        """
        if not self._Paused:
            self.widget('actionPause').set_short_label("Un_pause")
        else:
            self.widget('actionPause').set_short_label("_Pause")
        self._Paused = not (self._Paused)        

    def save(self, widget, data=None):
        """Signal handler for the save action
        
        """
        fileName = os.sep.join([self.preferences['outputDir'], 
                                "acceleration_" + 
                                time.strftime("%Y-%m-%d_%H-%M-%S") + 
                                ".dat"]) 
        try:
            with open(fileName, 'wb') as outFile:
                writer = csv.writer(outFile, 'excel-tab')
                outFile.write(writer.dialect.delimiter.join(("#time",
                                                          "Ax",
                                                          "Ay",
                                                          "Az")))
                outFile.write(writer.dialect.lineterminator)
                outFile.write(writer.dialect.delimiter.join(("#s",
                                                          "g",
                                                          "g",
                                                          "g")))
                outFile.write(writer.dialect.lineterminator)
                with self._dataLock:
                    writer.writerows(zip(self._time, *self._accData))
        except IOError as error:
            dialog = gtk.MessageDialog(parent   = None,
                                       flags    = gtk.DIALOG_DESTROY_WITH_PARENT,
                                       type     = gtk.MESSAGE_ERROR,
                                       buttons  = gtk.BUTTONS_OK,
                                       message_format = str(error))
            dialog.set_title(error[1])
            dialog.connect('response', lambda dialog, response: dialog.destroy())
            dialog.show()
Example #14
0
class PlotWindow:
    def __init__(self, plot, title="", lines=[], shown=False):

        self.plot=plot

        self.window=None
        self.vbox=None
        self.figure=None
        self.canvas=None
        self.axes=None
        self.legend=None

        self.show_cursors=False

        self.plot.shown=shown
        if shown:
            self.show()


    def show(self):
        self.vbox = gtk.VBox()
        self.figure = Figure(figsize=(5,4))

        self.figure.set_size_inches(self.plot.figwidth, self.plot.figheight)

        self.window = gtk.Window()
        self.window.connect("destroy", self.destroy_cb)
    #        self.window.connect("set-focus", self.set_focus_cb)
        self.window.connect("notify::is-active", self.window_focus_cb)
        self.window.add(self.vbox)

        self.canvas = FigureCanvas(self.figure)  # a gtk.DrawingArea

        self.draw()
        self.update(limits=True)

        self.vbox.pack_start(self.canvas)

        toolbar = NavigationToolbar(self.canvas, self.window)
        self.vbox.pack_start(toolbar, False, False)

        if self.plot.window_size != (0,0):
            self.window.resize(self.plot.window_size[0],
                               self.plot.window_size[1])
        else:
            self.window.resize(400, 300)
        if self.plot.window_pos != (0,0):
            self.window.move(self.plot.window_pos[0],
                             self.plot.window_pos[1])

        self.window.set_title(self.plot.title)

        self.cursors, = self.axes.plot(self.plot.lines[0].get_data()[0], self.plot.lines[0].get_data()[1])
        self.cursors.set_linestyle("None")
        self.cursors.set_markersize(10)
        self.cursors.set_markeredgewidth(2)
        self.cursors.set_markeredgecolor("k")
        self.cursors.set_antialiased(False)

        self.window.show_all()

#        self.plot.figwidth=self.figure.get_figwidth()
#        self.plot.figheight=self.figure.get_figheight()



        #   self.pos=self.window.get_position()
        self.plot.shown=True

    def set_focus_cb(self,window,data):
        print "Hej!"

    def window_focus_cb(self,window,data):
        print self.plot.window_size, self.plot.window_pos
        print "window_focus_cb:", self.plot.title
        if window.get_property('is-active'):
            #self.plot.parent.notebook.set_current_page(1)
            print "is-active"
            if self.plot.parent.plt_combo.get_selected_data() != self.plot:
                print "selecting item..."
                self.plot.parent.plt_combo.select_item_by_data(self.plot)
            self.plot.window_size=self.window.get_size()
            self.plot.window_pos=self.window.get_position()

            self.plot.figwidth=self.figure.get_figwidth()
            self.plot.figheight=self.figure.get_figheight()

    def draw(self, items=None, sources=None):
        legend=[]
        print "drawing "+self.plot.title
        def myfmt(x,y): return 'x=%1.6g\ny=%1.6g'%(x,y)
        self.figure.clf()
        self.axes = self.figure.add_subplot(111)
        #self.axes = self.figure.add_axes([0.10,0.10,0.85,0.85])
        #self.figure.subplots_adjust(bottom=0.15, left=0.15)
        self.axes.set_autoscale_on(False)
        self.axes.format_coord = myfmt

    #        self.btn_axes=self.figure.add_axes([0,0,0.1,0.05], frameon=True)
    #        self.cursor_a_btn=Button(self.btn_axes,"A")

        #self.selector=RectangleSelector(self.axes, self.rectangle_cb, useblit=True)
        self.canvas.mpl_connect('button_release_event', self.button_up_cb)

        #self.axes.callbacks.connect("xlim_changed",self.xlim_cb)
        #self.axes.callbacks.connect("ylim_changed",self.ylim_cb)
        self.figure.canvas.mpl_connect('pick_event',self.pick_cb)

        # xaxis=self.axes.get_xaxis()
        # yaxis=self.axes.get_yaxis()

        # xaxis.set_picker(axis_picker)
        # yaxis.set_picker(axis_picker)


        legend=[]

        for line in self.plot.lines:
            self.draw_line(line, draw_canvas=False)
            #source=line.source
            # if line.source is not None:
                # x_data, y_data=line.get_data()

                # line.handle, = self.axes.plot(x_data, y_data,
                                           # color=line.color, ls=line.style,
                                           # linewidth=line.width, picker=5.0)
                                           # #data_clipping=True)
                # line.handle.parent=line
                # legend.append(line.label)
                # #line.handle.set_label(line.label)

        #self.update()


        self.update_legend(draw_canvas=False)
        self.update_ticks(draw_canvas=False)

        self.canvas.draw()

    def draw_line(self, line, draw_canvas=True):
        #source=line.source
        if line.source is not None:
            x_data, y_data=line.get_data()

            line.handle, = self.axes.plot(x_data, y_data,
                                       color=line.color, ls=line.style,
                                       marker= line.marker, mew=0,
                                       linewidth=line.width, picker=5.0,
                                       label=line.label)
                                       #data_clipping=True)
            line.handle.parent=line
            #legend.append(line.label)
            #line.handle.set_label(line.label)

        #self.update()
        if draw_canvas:
            self.canvas.draw()

    def update_ticks(self, draw_canvas=True):

        xMajorFormatter = ScalarFormatter()
        yMajorFormatter = ScalarFormatter()
        xMajorFormatter.set_powerlimits((-3,4))
        yMajorFormatter.set_powerlimits((-3,4))

        xaxis=self.axes.get_xaxis()
        yaxis=self.axes.get_yaxis()

        xaxis.set_major_formatter(xMajorFormatter)
        yaxis.set_major_formatter(yMajorFormatter)

        if self.plot.x_majorticks_enable:
            xMajorLocator = MaxNLocator(self.plot.x_majorticks_maxn)
            xaxis.set_major_locator(xMajorLocator)
        else:
            xaxis.set_major_locator(NullLocator())

        if self.plot.y_majorticks_enable:
            yMajorLocator = MaxNLocator(self.plot.y_majorticks_maxn)
            yaxis.set_major_locator(yMajorLocator)
        else:
            yaxis.set_major_locator(NullLocator())

        if self.plot.x_minorticks_enable:
            xMinorLocator = MaxNLocator(self.plot.x_minorticks_maxn)
            xaxis.set_minor_locator(xMinorLocator)
        else:
            xaxis.set_minor_locator(NullLocator())

        if self.plot.y_minorticks_enable:
            yMinorLocator = MaxNLocator(self.plot.y_minorticks_maxn)
            yaxis.set_minor_locator(yMinorLocator)
        else:
            yaxis.set_minor_locator(NullLocator())

        self.update_margins(draw_canvas=False)

        if draw_canvas:
            self.canvas.draw()

    def update_margins(self, draw_canvas=True):

        margins={"left":0.05, "bottom":0.05}

        if self.plot.x_axis_label_enable:
            margins["bottom"]+=0.05
        if self.plot.y_axis_label_enable:
            margins["left"]+=0.05
        if self.plot.x_majorticks_enable:
            margins["bottom"]+=0.05
        if self.plot.y_majorticks_enable:
            margins["left"]+=0.05

        print margins

        self.figure.subplots_adjust(**margins)

        if draw_canvas:
            self.canvas.draw()

    def update_legend(self, draw_canvas=True):
        if self.plot.legend_enable:
            print "update_legend()"
            lines=[]
            labels=[]
            for line in self.plot.lines:
                labels.append(line.label)
                lines.append(line.handle)
                #line.handle.set_label(line.label)

            self.legend=self.axes.legend(lines, labels, loc=self.plot.legend_loc,
                               prop=FontProperties(size=self.plot.legend_size))
            self.legend.draw_frame(self.plot.legend_border)
            self.legend.set_picker(legend_picker)
        else:
            self.legend=None
            self.axes.legend_=None
        if draw_canvas:
            self.canvas.draw()

    def gupdate(self, source=None):
        """Takes care of updating relevant parts"""

        self.redraw(sources=[source])

        for part in parts:
            if part == "all":
                self.draw()
            elif part == "legend":
                self.update_legend()
            elif part == "margins":
                self.update_margins()
            elif part == "rest":
                self.update()

    def update(self, limits=True, draw_canvas=True):
        """Updates everything but the Lines and legend"""
    #        if self.plot.shown:
        #self.draw()

        #if self.plot.legend_enable:
        #    self.update_legend()

        if self.plot.x_axis_label_enable:
            self.axes.set_xlabel(self.plot.x_axis_label)
        else:
            self.axes.set_xlabel("")

        if self.plot.y_axis_label_enable:
            self.axes.set_ylabel(self.plot.y_axis_label)
        else:
            self.axes.set_ylabel("")

        if self.plot.x_log_enable:
            self.axes.set_xscale("log")
        else:
            self.axes.set_xscale("linear")
        if self.plot.y_log_enable:
            self.axes.set_yscale("log")
        else:
            self.axes.set_yscale("linear")

        xaxis=self.axes.get_xaxis()
        xaxis.grid(self.plot.x_grid_enable, which="major")

        yaxis=self.axes.get_yaxis()
        yaxis.grid(self.plot.y_grid_enable, which="major")

        if limits:
            extr=self.plot.get_extremes()
            print "sxtr:", extr
            if len(extr) == 4:
                print "extr:", extr
                y_pad=(extr[3]-extr[2])*0.05
                #self.axes.set_xlim(extr[0], extr[1])
                #self.axes.set_ylim(extr[2]-y_pad, extr[3]+y_pad)


                if self.plot.xlim_enable:
                    print "xlim"
                    self.axes.set_xlim(self.plot.xlim_min, self.plot.xlim_max,
                                   emit=False)
                else:
                    self.axes.set_xlim(#map(lambda x: round_to_n(x, 5),
                                       extr[0], extr[1]) #)

                if self.plot.ylim_enable:
                    self.axes.set_ylim(self.plot.ylim_min, self.plot.ylim_max,
                                   emit=False)
                else:
                    y_limits=(extr[2], extr[3])#)#map(lambda y: round_to_n(y, 5),

                    y_pad=(y_limits[1]-y_limits[0])/20
                    self.axes.set_ylim(y_limits[0]-y_pad, y_limits[1]+y_pad)


        try:
            mpl_code=compile(self.plot.mpl_commands,'<string>','exec')
            eval(mpl_code, None, {"figure": self.figure,
                                  "axes": self.axes,
                                  "legend": self.legend,
                                  "s": self.plot.parent.source_list[:],
                                  "p": self.plot.parent.plt_combo.get_model_items().values(),
                                  "plot": self.plot})
        except:
            print "Invalid MPL code!"

        if draw_canvas:
            self.canvas.draw()

    def redraw(self, sources, draw_canvas=True):
        if sources != []:
            lines=[]
            for line in self.plot.lines:
                if line.source in sources and line not in lines:
                    lines.append(line)
            #legend=[]

            for line in lines:
                print("Redraw: "+line.source.name)
                source=line.source
                if source:
                    x_data, y_data=line.get_data()
                    #print x_data, y_data
                    # if source.norm_enable:
                        # print "NORMALIZE!"
                        # y_data=(source.y_data-source.y_data[source.norm_min_pt])/\
                                    # (source.y_data[source.norm_max_pt]-\
                                     # source.y_data[source.norm_min_pt])*\
                                    # (source.norm_max_y-source.norm_min_y)+source.norm_min_y
                    # if line.x_scale_enable:
                        # x_data=x_data*line.x_scale
                    # if line.y_scale_enable:
                        # y_data=y_data*line.y_scale
                    # if line.x_shift_enable:
                        # x_data=x_data+line.x_shift
                    # if line.y_shift_enable:
                        # y_data=y_data+line.y_shift
        #                if source.shift_enable:
        #                    x_data=source.x_data+source.shift

                    line.handle.set_data(x_data, y_data)
                    line.update_extremes()

                    line.handle.set_color(line.color)
                    line.handle.set_linewidth(line.width)
                    line.handle.set_marker(line.marker)

            try:
                s=self.plot.parent.source_list.get_selected_rows()[0]
            except:
                pass
            else:
                if self.show_cursors and s.norm_enable:
                    self.cursors.set_data(   #s.x_data, s.y_data)
                            [s.x_data[s.norm_min_pt],
                            s.x_data[s.norm_max_pt]],
                            [s.norm_min_y, s.norm_max_y])
                    self.cursors.set_marker('+')
                else:
                    self.cursors.set_marker("None")

            #print "getting axis limits"
            extr=self.plot.get_extremes()
            if not self.plot.xlim_enable:
                self.axes.set_xlim(extr[0], extr[1])
            if not self.plot.ylim_enable:
                y_pad=(extr[3]-extr[2])*0.05
                self.axes.set_ylim(extr[2]-y_pad, extr[3]+y_pad)

            #self.axes.redraw_in_frame() #????
            if draw_canvas:
                self.canvas.draw()

    def destroy_cb(self, widget):
        self.plot.shown=False
        #TreeDisplay.update_plot_state()
        #self.pos=self.window.get_position()
        #self.size=self.window.get_size()
        #print self.pos
        self.window.destroy()
        #self.plot.shown=False
        self.plot.parent.shown.update(False)
        #self.plot.parent.shown=False
        #self.plot.update_plot_info()

    #callbacks
    def rectangle_cb(self, event1, event2):
        print event1.xdata, event1.ydata, event2.xdata, event2.ydata
        self.plot.x_lim_min=event1.xdata
        self.plot.x_lim_max=event2.xdata
        self.plot.y_lim_min=event1.ydata
        self.plot.y_lim_max=event2.ydata
        self.axes.set_xlim(min(event1.xdata,event2.xdata), max(event1.xdata,event2.xdata))
        self.axes.set_ylim(min(event1.ydata,event2.ydata), max(event1.ydata,event2.ydata))
        self.canvas.draw()

    def button_up_cb(self,event):
        self.plot.xlim_min, self.plot.xlim_max=self.axes.get_xlim()
        self.plot.ylim_min, self.plot.ylim_max=self.axes.get_ylim()

        if not self.plot.xlim_enable:
            self.plot.parent.xlim_min.update(self.plot.xlim_min)
            self.plot.parent.xlim_max.update(self.plot.xlim_max)

        if not self.plot.ylim_enable:
            self.plot.parent.ylim_min.update(self.plot.ylim_min)
            self.plot.parent.ylim_max.update(self.plot.ylim_max)


    def xlim_cb(self,event):
        #print "xlim changed to: "+str(self.axes.get_xlim())
        self.plot.xlim_min, self.plot.xlim_max=self.axes.get_xlim()
        if not self.plot.xlim_enable:
            self.plot.parent.xlim_min.update(self.plot.xlim_min)
            self.plot.parent.xlim_max.update(self.plot.xlim_max)
        #pass

    def ylim_cb(self,event):
        #print "ylim changed to: "+str(self.axes.get_ylim())
        self.plot.ylim_min, self.plot.ylim_max=self.axes.get_ylim()
        if not self.plot.ylim_enable:
            self.plot.parent.ylim_min.update(self.plot.ylim_min)
            self.plot.parent.ylim_max.update(self.plot.ylim_max)
        #pass

    def pick_cb (self, event ) :
        print event.artist
        if isinstance(event.artist, Line2D):
            print event.artist.parent.label
            xdata=event.artist.get_xdata()
            ydata=event.artist.get_ydata()
            print event.ind[0]
            print xdata[event.ind[0]], ydata[event.ind[0]]
            axes_h=self.axes.get_ylim()
            print axes_h

            self.plot.parent.plot_notebook.set_current_page(0)
            self.plot.parent.lines_list.select(event.artist.parent)

    #            arrow_h=0.1*(axes_h[1]-axes_h[0])
    #            self.axes.arrow(xdata[event.ind[0]],ydata[event.ind[0]],0,arrow_h,label="A", visible=True)
    #            self.canvas.draw()
            #self.axes.arrow(0.5,0.5,0.1,0.1)

        if isinstance(event.artist, Legend):
            print "legend clicked"
            self.plot.parent.plot_notebook.set_current_page(2)

        else:
            print event
Example #15
0
		new_y = 0
	if new_y > 100:
		new_y = 100
	y_data.append(new_y)
	global frames, start_time
	frames += 1
	if frames % 50 == 0:
		print frames / float(time.time() - start_time)
	return True

pressed = False
def press(event):
	global pressed, y_val
	pressed = True
	y_val = event.ydata
canvas.mpl_connect('button_press_event', press)

def release(event):
	global pressed, y_val
	pressed = False
	y_val = event.ydata
canvas.mpl_connect('button_release_event', release)

def motion(event):
	if pressed and event.inaxes == ax:
		global y_val
		y_val = event.ydata
canvas.mpl_connect('motion_notify_event', motion)

win.add(canvas)
win.show_all()
Example #16
0
class Plotter():
    def __init__(self, context, data, fitfunction):
        self.context = context
        self.data = data
        self.fitfunction = fitfunction

        self.fig = Figure(figsize=(6, 4))  # create fig
        self.canvas = FigureCanvas(self.fig)  # a gtk.DrawingArea
        self.canvas.set_size_request(600, 400)  # set min size
        self.markers = [
            '.', ',', '+', 'x', '|', '_', 'o', 'v', '^', '<', '>', '8', 's',
            'p', '*', 'h', 'H', 'D', 'd'
        ]
        self.colors = [
            'black', 'blue', 'green', 'red', 'cyan', 'magenta', 'yellow',
            'purple', 'white'
        ]
        self.pstyle = [
            'bmh', 's', '6', 'red', '0.8', 'black', '2', 'black', '0.3', '',
            '25', '', '', '20', '15', '', '', '20', '15'
        ]

        self.styledict = {}
        self.styledict["style"] = 'bmh'
        self.styledict["point_style"] = 's'
        self.styledict["point_size"] = '6'
        self.styledict["point_color"] = 'red'
        self.styledict["point_alpha"] = '0.8'
        self.styledict["line_color"] = 'black'
        self.styledict["line_width"] = '2'
        self.styledict["band_color"] = 'black'
        self.styledict["band_alpha"] = '0.3'
        self.styledict["title_size"] = '25'
        self.styledict["xtitle_size"] = '20'
        self.styledict["xlabel_size"] = '15'
        self.styledict["ytitle_size"] = '20'
        self.styledict["ylabel_size"] = '15'

        self.nselec = [1, 12, 5, 3, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1]
        self.plot_labels = []
        self.plot_labels.append(data.labels[3] + " vs " +
                                data.labels[0])  # plot title
        self.plot_labels.append(data.labels[0])  # x-axis title
        self.plot_labels.append(data.labels[3])  # y-axis title
        self.plot_labels.append("[Gy]")  # x-axis unit
        self.plot_labels.append(" ")  # y-axis unit
        #print plt.style.available

        self.fit_toggle = 'active'
        self.points_toggle = 1
        self.function_toggle = 1
        self.err_toggle = 1
        self.ci_func_toggle = 1
        self.ci_points_toggle = 1
        toolbar = NavigationToolbar(self.canvas, self)
        toolbarbox = gtk.HBox()
        image = gtk.Image()
        image.set_from_stock(gtk.STOCK_PROPERTIES, gtk.ICON_SIZE_LARGE_TOOLBAR)
        options_button = gtk.Button()
        options_button.add(image)
        image2 = gtk.Image()
        image2.set_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_LARGE_TOOLBAR)
        refresh_button = gtk.Button()
        refresh_button.add(image2)
        toolbarbox.pack_start(toolbar, True, True)
        toolbarbox.pack_end(options_button, False, True)
        toolbarbox.pack_end(refresh_button, False, True)
        self.vbox = gtk.VBox()
        self.vbox.pack_start(toolbarbox, False, False)
        self.vbox.pack_start(self.canvas, True, True)

        # signals
        self.canvas.mpl_connect('pick_event', self.on_pick)
        options_button.connect('clicked', self.mpl_options)
        refresh_button.connect('clicked', self.on_refresh_clicked)

    def on_pick(self, event):
        artist = event.artist
        xmouse, ymouse = event.mouseevent.xdata, event.mouseevent.ydata
        x, y = artist.get_xdata(), artist.get_ydata()
        ind = event.ind
        print 'Artist picked:', event.artist
        print '{} vertices picked'.format(len(ind))
        print 'Pick between vertices {} and {}'.format(min(ind), max(ind))
        print 'x, y of mouse: {:.2f},{:.2f}'.format(xmouse, ymouse)
        print 'Data point:', x[ind[0]], y[ind[0]]
        print
        self.context.log('Data point:\t  ' + str(x[ind[0]]) + '\t' +
                         str(y[ind[0]]))
        self.context.treeview.treeview.set_cursor(min(ind))
        self.context.treeview.treeview.grab_focus()

    def mpl_options(self, button):
        """Create GTKDialog containing options for plotting and connect signals."""
        mpl_options_dialog = MPLOptions(self.context, self)

    def on_refresh_clicked(self, button):
        """Refresh canvas - plot everything again"""
        self.plotting()

    def plotvline(self, **kwargs):
        self.ax1.axvline(**kwargs)

    def plothline(self, **kwargs):
        self.ax1.axhline(**kwargs)

    def replot(self):
        self.canvas.draw()

    def plotting(self):
        """Generating matplotlib canvas"""

        plt.style.use(self.pstyle[0])

        self.ax1 = self.fig.add_subplot(111)
        self.ax1.clear()

        if self.points_toggle == 1:
            self.ax1.errorbar(self.data.get_xdata(),
                              self.data.get_ydata(),
                              self.data.get_yerr(),
                              fmt='none',
                              ecolor='black',
                              elinewidth=0.5,
                              capsize=0.5,
                              capthick=0.5)
            self.ax1.plot(self.data.get_xdata(),
                          self.data.get_ydata(),
                          color=self.pstyle[3],
                          label=self.data.labels[3],
                          marker=self.pstyle[1],
                          alpha=float(self.pstyle[4]),
                          linestyle='None',
                          markersize=float(self.pstyle[2]),
                          picker=float(self.pstyle[2]))

        self.ax1.set_title(self.plot_labels[0], fontsize=self.pstyle[10])
        self.ax1.set_xlabel(self.plot_labels[1] + self.plot_labels[3],
                            fontsize=int(self.pstyle[13]))
        self.ax1.set_ylabel(self.plot_labels[2] + self.plot_labels[4],
                            fontsize=int(self.pstyle[17]))
        self.ax1.tick_params(axis='x',
                             which='both',
                             labelsize=int(self.pstyle[14]))
        self.ax1.tick_params(axis='y',
                             which='both',
                             labelsize=int(self.pstyle[18]))

        x = np.arange(-0.1, max(20, max(self.data.get_xdata())) * 1.1, 0.05)

        if (self.fit_toggle == 'active'):
            if len(self.data.get_xdata()) >= 3:
                print "before fit", self.fitfunction.params
                print "before fit", self.fitfunction.params
                print "xdata", self.data.get_xdata()
                print "ydata", self.data.get_ydata()
                self.fitfunction.fit_function(self.data.get_xdata(),
                                              self.data.get_ydata(),
                                              self.data.get_yerr())
                print "after fit", self.fitfunction.params
                print "after fit", self.fitfunction.params
                self.context.functiontab.function_changed()
            else:
                self.context.log("Too few data to fit the function!")

        if self.function_toggle == 1:
            y = self.fitfunction.func(x, self.fitfunction.params)
            self.ax1.plot(x,
                          y,
                          color=self.pstyle[5],
                          marker='.',
                          linestyle='None',
                          markersize=float(self.pstyle[6]))

        if self.ci_func_toggle == 1 and self.fit_toggle == 'active':
            conf = confidence(x, self.data.get_xdata(), len(x),
                              np.mean(self.data.get_xdata()),
                              self.fitfunction.dof, self.fitfunction.rmse)
            upper = self.fitfunction.func(x, self.fitfunction.params) + conf
            lower = self.fitfunction.func(x, self.fitfunction.params) - conf
            self.ax1.fill_between(x,
                                  lower,
                                  upper,
                                  facecolor=self.pstyle[7],
                                  alpha=float(self.pstyle[8]))

        if self.ci_points_toggle == 1:
            upper = self.fitfunction.func(
                x, self.fitfunction.params) + confidence_points(
                    x, self.fitfunction.std_err)
            lower = self.fitfunction.func(
                x, self.fitfunction.params) - confidence_points(
                    x, self.fitfunction.std_err)
            self.ax1.fill_between(x,
                                  lower,
                                  upper,
                                  facecolor='blue',
                                  alpha=float(self.pstyle[8]))

        if self.err_toggle == 1:
            upper = self.fitfunction.func(
                x, self.fitfunction.params) + uncertainty(
                    x, self.fitfunction.std_err)
            lower = self.fitfunction.func(
                x, self.fitfunction.params) - uncertainty(
                    x, self.fitfunction.std_err)
            self.ax1.fill_between(x,
                                  lower,
                                  upper,
                                  facecolor='green',
                                  alpha=float(self.pstyle[8]))

        self.fig.subplots_adjust(left=0.13,
                                 right=0.96,
                                 top=0.91,
                                 bottom=0.13,
                                 hspace=0.04)
        self.canvas.draw()

        print self.fitfunction.params
        print self.fitfunction.std_err
Example #17
0
    def __init__(self):
        # assign gtk-Layout
        builder = gtk.Builder()
        builder.add_from_file("panoptikum.glade")
        builder.connect_signals(self)
        self.window = builder.get_object("window1")
        self.windowMessage = builder.get_object("messagedialog1")
        self.filechooserProject = builder.get_object("filechooserdialog1")
        self.filefilter = builder.get_object("filefilter1")
        self.filefilter.add_pattern("*.cfg")
        self.large_atom_check_button = builder.get_object("large_atom_check_button")
        self.live_mode_check_button = builder.get_object("live_mode_check_button")
        self.roiOnly_check_button = builder.get_object("roiOnly_check_button")
        self.sameID_check_button = builder.get_object("sameID_check_button")
        self.radio_buttons_imageCategory = builder.get_object("action1")
        self.window.connect("destroy", self.__del__)
        self.statusbar = builder.get_object("statusbar1")
        self.hbox_Rb = builder.get_object("hboxRb")
        self.vbox_Rb = builder.get_object("vboxRb")
        self.vbox_RbLast10 = builder.get_object("vboxRbLast10")
        self.hbox_Li = builder.get_object("hboxLi")
        self.vbox_Li = builder.get_object("vboxLi")
        self.www_Rb = builder.get_object("togglebuttonRbWww")
        self.www_Li = builder.get_object("togglebuttonLiWww")

        # global Variables
        self.MessageType = "N_Li"
        self.maxImageSize = array([0, 1392, 0, 1040])

        ######### TODO ############
        """
        self.TEST = builder.get_object('filechooserbutton1Rb')
        self.TEST2 = builder.get_object('entry1')
        #import time
        #self.time_start = 0
        #self.time_end = 0
        try:
            print p['pixelSizeTextField'].get_value()
            print self.TEST.get_filename()
            self.TEST.set_filename('rb_recenta.fit')
            self.TEST2.set_text(str(p['part'])[1:-1])
        except:
            pass
        """
        """
        self.time_start = time.clock()
                self.time_end = time.clock()
        print self.time_end - self.time_start
        """
        ######### TODO ############

        # matplotlib
        self.whiteCMap = loadColormap.whiteCMap()
        self.initNav()
        self.shiftPressed = False

        # Rb __init__
        self.figure_Rb = plt.figure()
        gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1])
        ax1 = plt.subplot(gs[0])
        ax1.set_xlabel(u"\u00b5m")
        ax1.set_ylabel(u"\u00b5m")
        ax1.xaxis.set_label_coords(0.97, -0.06)
        ax3 = plt.subplot(gs[1])
        ax3.xaxis.set_label_coords(0.97, -0.16)
        canvas_Rb = FigCanvas(self.figure_Rb)
        plt.subplots_adjust(hspace=0.25, bottom=0.05, right=0.95)
        nav_Rb = Nav(canvas_Rb, self.window)
        self.vbox_Rb.pack_start(nav_Rb, False, False)
        self.vbox_Rb.pack_start(canvas_Rb)
        self.figure_RbLast10 = plt.figure()
        self.ax1Last10 = plt.subplot(111)
        self.canvas_RbLast10 = FigCanvas(self.figure_RbLast10)
        self.vbox_RbLast10.pack_start(self.canvas_RbLast10)
        RbValues2calc = [
            "N_Rb",
            "T_Rb",
            "fwhmV_Rb",
            "fwhmH_Rb",
            "PosV_Rb",
            "PosH_Rb",
            "AmpV_Rb",
            "AmpH_Rb",
            "OffV_Rb",
            "OffH_Rb",
            "______AUTOMATISIERUNG_",
            "AUTO_N_POS",
            "AUTO_STEP_POS",
            "AUTO_START",
            "AUTO_STEP",
            "AUTO_BREAK",
            "ABB_TOF_RB",
        ]
        RbIndexLst = [s.lower().strip("_" + "rb") for s in RbValues2calc]
        self.RbParameters = {
            "pixelSize": 6.57e-6,
            "pixelSizeTextField": builder.get_object("spinbutton1"),
            "axScale": 1e6,
            "species": "Rb",
            "folder": "F:\\INBOX\\Apogee\\",
            "filenames": ["rb_recenta.fit", "rb_recentb.fit", "rb_recentc.fit"],
            "adwinfile": "..\\ADwin\\adwin_code_recent.acm",
            "savefilename": "rb_result.png",
            "fullFrame": zeros(2),
            "partAtomCount": array([550, 750, 500, 800]),
            "partLumCorr": array([550, 750, 800, 950]),
            "part": self.maxImageSize,
            "xylim": [(0, 6826), (9138, 0)],
            "Marker1Pos": (0, 0),
            "Marker2Pos": (0, 0),
            "imageAx": ax1,
            "linescanAx": ax3,
            "canvasObj": canvas_Rb,
            "ODmaxAuto": builder.get_object("checkbuttonRbAutoOD"),
            "ODmaxLabel": builder.get_object("labelRbOD"),
            "ODmax": builder.get_object("hscaleRbOD"),
            "adwinID": builder.get_object("adwinIDRb"),
            "imageCategory": "opt. Dichte",
            "values2calc": RbValues2calc,
            "indexLst": RbIndexLst,
            "last10": pd.DataFrame(index=RbIndexLst),
        }

        # Li __init__
        self.figure_Li = plt.figure()
        gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1])
        ax0 = plt.subplot(gs[0])
        ax0.set_xlabel(u"\u00b5m")
        ax0.set_ylabel(u"\u00b5m")
        ax0.xaxis.set_label_coords(0.97, -0.06)
        ax2 = plt.subplot(gs[1])
        ax2.xaxis.set_label_coords(0.97, -0.16)
        canvas_Li = FigCanvas(self.figure_Li)
        plt.subplots_adjust(hspace=0.25, bottom=0.05, right=0.95)
        nav_Li = Nav(canvas_Li, self.window)
        self.vbox_Li.pack_start(nav_Li, False, False)
        self.vbox_Li.pack_start(canvas_Li)
        LiValues2calc = [
            "N_Li",
            "T_Li",
            "fwhmV_Li",
            "fwhmH_Li",
            "PosV_Li",
            "PosH_Li",
            "AmpV_Li",
            "AmpH_Li",
            "OffV_Li",
            "OffH_Li",
            "______AUTOMATISIERUNG_",
            "AUTO_N_POS",
            "AUTO_STEP_POS",
            "AUTO_START",
            "AUTO_STEP",
            "AUTO_BREAK",
            "ABB_TOF_LI",
        ]
        LiIndexLst = [s.lower().strip("_" + "li") for s in LiValues2calc]
        self.LiParameters = {
            "pixelSize": 6.57e-6,
            "axScale": 1e6,
            "species": "Li",
            "folder": "F:\\INBOX\\Apogee\\",
            "filenames": ["li_recenta.fit", "li_recentb.fit", "li_recentc.fit"],
            "adwinfile": "..\\ADwin\\adwin_code_recent.acm",
            "savefilename": "li_result.png",
            "fullFrame": zeros(2),
            "partAtomCount": array([550, 750, 500, 800]),
            "partLumCorr": array([550, 750, 800, 950]),
            "part": self.maxImageSize,
            "xylim": [(0, 6826), (9138, 0)],
            "Marker1Pos": (0, 0),
            "Marker2Pos": (0, 0),
            "imageAx": ax0,
            "linescanAx": ax2,
            "canvasObj": canvas_Li,
            "ODmaxAuto": builder.get_object("checkbuttonLiAutoOD"),
            "ODmaxLabel": builder.get_object("labelLiOD"),
            "ODmax": builder.get_object("hscaleLiOD"),
            "adwinID": builder.get_object("adwinIDLi"),
            "imageCategory": "opt. Dichte",
            "values2calc": LiValues2calc,
            "indexLst": LiIndexLst,
            "last10": pd.DataFrame(index=LiIndexLst),
        }

        # reload Parameters of last Session
        try:
            with open("restoreLastSession.pickle", "rb") as infile:
                parameterFromStorage = pickle.load(infile)
                self.RbParameters["part"] = parameterFromStorage[0]
                self.RbParameters["partAtomCount"] = parameterFromStorage[1]
                self.RbParameters["partLumCorr"] = parameterFromStorage[2]
                self.RbParameters["xylim"] = parameterFromStorage[3]
                self.RbParameters["Marker1Pos"] = parameterFromStorage[4]
                self.RbParameters["Marker2Pos"] = parameterFromStorage[5]
                self.LiParameters["part"] = parameterFromStorage[6]
                self.LiParameters["partAtomCount"] = parameterFromStorage[7]
                self.LiParameters["partLumCorr"] = parameterFromStorage[8]
                self.LiParameters["xylim"] = parameterFromStorage[9]
                self.LiParameters["Marker1Pos"] = parameterFromStorage[10]
                self.LiParameters["Marker2Pos"] = parameterFromStorage[11]
        except:
            print "Cannot load last Session!"

        # set working directory
        os.chdir(self.RbParameters["folder"])

        # draw matplotlib stuff
        self.initLines(self.RbParameters)
        self.initLines(self.LiParameters)
        self.updateFullFrameImage(self.RbParameters)
        self.updateFullFrameImage(self.LiParameters)
        self.last10Rb = self.drawImageArea(self.RbParameters)
        self.last10Li = self.drawImageArea(self.LiParameters)

        # show gtk-window
        self.window.set_default_size(1024, 800)
        self.window.set_size_request(600, 800)
        self.window.set_title("Panoptikum - LiRb-Lab Image Analyse")
        self.window.show_all()
        # self.statusbar1_text_pushed('Li image updated... waiting for images...')

        # GTK-event handlers
        self.window.connect("key_press_event", self.on_key_press)
        self.window.connect("key_release_event", self.on_key_released)

        # matplotlib-event handlers
        canvas_Rb.mpl_connect("button_press_event", self.mouse_press_callback_Rb)
        canvas_Rb.mpl_connect("button_release_event", self.mouse_release_callback_Rb)
        canvas_Rb.mpl_connect("scroll_event", self.mouse_scrolled_callback_Rb)
        canvas_Li.mpl_connect("button_press_event", self.mouse_press_callback_Li)
        canvas_Li.mpl_connect("button_release_event", self.mouse_release_callback_Li)
        canvas_Li.mpl_connect("scroll_event", self.mouse_scrolled_callback_Li)
        rectprops = dict(facecolor="black", edgecolor="black", alpha=0.1, fill=True)
        self.RS_Rb = RectangleSelector(
            ax1,
            self.RectangleSelector_callback_Rb,
            drawtype="box",
            useblit=True,
            button=[1, 3],
            minspanx=10,
            minspany=10,
            spancoords="pixels",
            rectprops=rectprops,
        )

        self.RS_Li = RectangleSelector(
            ax0,
            self.RectangleSelector_callback_Li,
            drawtype="box",
            useblit=True,
            button=[1, 3],
            minspanx=10,
            minspany=10,
            spancoords="pixels",
            rectprops=rectprops,
        )

        # GIO-event handlers
        fileRb = gio.File(self.RbParameters["filenames"][-1])
        self.monitorRb = fileRb.monitor_file()
        self.monitorRbID = self.monitorRb.connect("changed", self.file_changedRb)

        fileLi = gio.File("li_recentc.fit")
        self.monitorLi = fileLi.monitor_file()
        self.monitorLiID = self.monitorLi.connect("changed", self.file_changedLi)
Example #18
0
class WindGraph(gtk.Window):
  def table(self, winds, subplot, step):
    x = []
    y = []

    for wind, next_wind in itertools.izip(winds, winds[1:]):
      u = float(wind[0])
      u1 = float(next_wind[0])

      while u < u1:
        x.append(u)
        y.append(float(eval(wind[1])))
        u += step*(u1-u)

    x.append(float(winds[-1][0]))
    y.append(float(eval(winds[-1][1])))

    subplot.plot(x, y)

  def weibull(self, weibull, subplot, step):
    shape = weibull[0]
    scale = weibull[1]
    stop = weibull[2]
    numargs = exponweib.numargs
    [a, c] = [weibull[0]] * numargs
    rv = exponweib(a, c, scale=weibull[1])
    x = arange(start=0, stop=weibull[2], step=step/2)
    subplot.plot(x, rv.pdf(x)*100)

  def __init__(self, winds=None, weibull=None, step=0.5, title="Wind Graph", parent=None):
    gtk.Window.__init__(self)
 
    try:
      self.set_screen(parent.get_screen())
    except AttributeError:
      self.connect('destroy', lambda *w: self.destroy())

    if parent is not None:
      self.set_parent(parent)
    self.set_title(title)
    self.set_destroy_with_parent(True)
    self.set_default_size(600, 400)

    vbox = gtk.VBox()
    self.add(vbox)

    figure = Figure(figsize=(5,4), dpi=100)
    subplot = figure.add_subplot(111)
    subplot.set_title("Wind Distribution")
    subplot.set_xlabel("Speed (u) [m/s]")
    subplot.set_ylabel("Probability density [%]")
    subplot.grid(True)

    if winds is not None:
      self.table(winds, subplot, step)
    elif weibull is not None:
      self.weibull(weibull, subplot, step/2)

    self.canvas = FigureCanvas(figure)
    self.canvas.mpl_connect('key_press_event', self.on_key_event)
    vbox.pack_start(self.canvas)

    self.toolbar = NavigationToolbar(self.canvas, self)
    vbox.pack_start(self.toolbar, False, False)

    self.show_all()

  def on_key_event(self, event):
    key_press_handler(event, self.canvas, self.toolbar)
class spectrum_plotter:
	def __init__(self, xs, ys):
		self.xs=xs
		self.ys=ys
		
		self.win = gtk.Window()
		self.win.connect("destroy", lambda x: gtk.main_quit())
		self.win.set_default_size(800,600)
		self.win.set_title("openSpectrometer")

		self.vbox = gtk.VBox()
		self.win.add(self.vbox)
		
		self.fig = Figure(figsize=(5,4), dpi=100)
		self.canvas = FigureCanvas(self.fig)  # a gtk.DrawingArea
		
		self.ax = self.fig.add_subplot(111)
		
		self.canvas.mpl_connect('pick_event', self.onpick)
		
		self.vbox.pack_start(self.canvas)
		self.toolbar = NavigationToolbar(self.canvas, self.win)
		self.hbox = gtk.HBox()
		self.button=gtk.Button('Select this point as lambda max')
		self.button.connect("clicked", self.buttonClick)
		self.hbox.pack_start(self.toolbar)
		self.hbox.pack_start(self.button)
		self.vbox.pack_start(self.hbox, False, False)
		
		self.lastind = 0

		self.text = self.ax.text(0.05, 0.95, 'Datapoint index selected: none',
                            transform=self.ax.transAxes, va='top')
	def plot(self, *args, **kwargs):
		self.ax.plot(*args, **kwargs)
	def plotSelectable(self, *args, **kwargs):
		self.line=self.ax.plot(*args, **kwargs)
	def selectPoint(self, x, y):
		self.selected = self.ax.plot([x],[y], 'o', ms=20, alpha=0.4, 
									   color='yellow', visible=False)
	def show(self):
		self.win.show_all()
		gtk.main()
	def buttonClick(self):
		return self.lastind
	def onpick(self, event):
		if event.artist!=self.line[0]: return True
		
		N = len(event.ind)
		if not N: return True
		print 'here'

		if N > 1:
			print '%i points found!' % N
		print event.ind

		# the click locations
		x = event.mouseevent.xdata
		y = event.mouseevent.ydata

		dx = numpy.array(x-self.xs[event.ind],dtype=float)
		dy = numpy.array(y-self.ys[event.ind],dtype=float)

		distances = numpy.hypot(dx,dy)
		indmin = distances.argmin()
		dataind = event.ind[indmin]

		self.lastind = dataind
		self.update()

	def update(self):
		if self.lastind is None: return

		dataind = self.lastind
		
		self.selected[0].set_visible(True)
		self.selected[0].set_data(self.xs[dataind], self.ys[dataind])

		# put a user function in here!        
		self.userfunc(dataind)

		self.fig.canvas.draw()

	def userfunc(self,dataind):
		self.text.set_text('datapoint index selected: %d'%dataind)
		print 'No userfunc defined'
		pass
Example #20
0
class MainView(BasePlotView, gtk.Frame):
    """
    A Gtk Frame based plotting widget for dreampy
    that contains additional tool bar items for printing
    and adding notes
    """
    def __init__(self, win, **kwargs):
        gtk.Frame.__init__(self)
        BasePlotView.__init__(self, **kwargs)
        self.win = win
        self.title = None

        #Put some stuff
        # self.suppress_header = kwargs.get('suppress_header', False)
        # self.suppress_title = kwargs.get('suppress_title', False)
        # self.suppress_legend = kwargs.get('suppress_legend', False)
        self.vbox = gtk.VBox(False, 0)
        self.add(self.vbox)
        self.sw = gtk.ScrolledWindow()
        self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.vbox.pack_start(self.sw, True, True, 0)
        self.sw.show()
        self.f = Figure(figsize=(5,4), dpi=100)
        self.canvas = FigureCanvas(self.f)  # a gtk.DrawingArea
        self.canvas.set_size_request(400,300)
        self.sw.add_with_viewport (self.canvas)
        self.canvas.show_all()
        self.toolbar = NavToolBar(self.canvas, self.win)
        self.vbox.pack_start(self.toolbar, False, False)
        self.toolbar.show()
        self.vbox.show()
        # self.autoscale = True
        # self.xmin = None
        # self.xmax = None
        # self.ymin = None
        # self.ymax = None
        # self.image = None
        # self.hold_plot = False
        # self.keyid = None
        # self.filter = None
        # self.labelsize = 8
        # self.titlesize = 10
        # self.ticklabelsize = 8
        # self.ticklabelweight = 'normal'
        # self.labelweight = 'bold'
        # self.titleweight = 'bold'
        # self.legendsize = 8
        # self.legendweight = 'normal'
        # self.hdrlabelsize = 9
        # self.hdrlabelweight = 'normal'
        # self.cur_axname = None
        self.refresh_canvas()
        self.show_all()
        #self.gtk_catchup()
        
    def gtk_catchup(self):
        gtk.gdk.threads_enter()
        while gtk.events_pending():
            gtk.main_iteration()
        gtk.gdk.threads_leave()        
        
    def create_arrow_button(self, arrow_type, shadow_type):
        button = gtk.Button()
        self.arrow = gtk.Arrow(arrow_type, shadow_type)
        button.add(self.arrow)
        button.show()
        self.arrow.show()
        return button

    def list_widgets_turnoff(self):
        self.left_button.set_sensitive(False)
        self.right_button.set_sensitive(False)
        self.ignore_button.set_sensitive(False)        
        #if self.keyid:
        #    self.canvas.disconnect(self.keyid)


    def disconnect_event(self, sig):
        if self.canvas:
            self.canvas.mpl_disconnect(sig)

    def connect_event(self, eventname, eventfunc):
        if self.canvas:
            self.canvas.set_flags(gtk.CAN_FOCUS)  #to grab focus for keystrokes
            self.canvas.grab_focus()    #to grab focus for keystrokes
            return self.canvas.mpl_connect(eventname, eventfunc)

    def redraw_plot(self):
        if self.hold_plot is False:
            if hasattr(self.canvas, 'show_all'):
                self.canvas.show_all()
            self.canvas.draw()
        self.gtk_catchup()
Example #21
0
class Graph_viewer:
    def __init__(self, graph, actions=['nothing'], callback=None):
        """
            weights : dictionary mapping name to weight
                      kmers will be colored in rank order of weight
        
        """

        self.graph = graph
        self.callback = callback

        self.window = gtk.Window()
        self.window.connect('destroy', lambda x: gtk.main_quit())
        self.window.set_default_size(800, 600)
        self.window.set_title('Graph viewer')

        vbox = gtk.VBox()
        self.window.add(vbox)

        self.figure = Figure(figsize=(8, 6), dpi=50)
        self.axes = self.figure.add_subplot(111)

        colors = numpy.empty((len(graph.names), 3))
        sizes = numpy.empty(len(graph.names))

        sizes[:] = 2.0

        #if weights is None:
        #    #self.axes.plot(graph.positions[:,0], graph.positions[:,1], ',')
        #
        #    colors[:,:] = [[0.0,0.0,0.0]]
        #
        #else:

        #names = weights.keys()
        #values = weights.values()
        ##names.sort(key=lambda x: weights[x])
        #idents = numpy.array([ graph.name_to_ident[name] for name in names ])

        #x = numpy.array(values, dtype='float64')
        x = numpy.array(graph.weights, dtype='float64')

        x = numpy.log(x)

        x -= numpy.minimum.reduce(x)
        x /= numpy.average(x) * 2.0
        #x /= numpy.sum(x*x)*2.0/numpy.sum(x)

        xx = numpy.minimum(x, 1.0)
        #x = numpy.arange(len(graph.names)) / float(len(graph.names))

        colors[:, 0] = 0.5 - xx * 0.5
        colors[:, 1] = 0.75 - xx * 0.5
        colors[:, 2] = 1.0 - xx * 0.5

        sizes[:] = numpy.maximum(x, 1.0)**2  #*2.0

        #n = 20
        #for i in xrange(n):
        #    start = i*len(names)//n
        #    end = (i+1)*len(names)//n
        #    if start == end: continue
        #
        #    x = (1.0-float(i)/(n-1))
        #    position_block = graph.positions[idents[start:end]]
        #    self.axes.scatter(position_block[:,0],
        #               position_block[:,1],
        #               linewidths=0,
        #               marker='s',
        #               s=10.0,
        #               c=(0.0,x,x*0.5+0.5),
        #               zorder=i)

        dots = Dots(graph.positions[:, 1], graph.positions[:, 0], colors,
                    sizes)
        self.axes.add_artist(dots)

        #if len(graph.links) < 1000:
        #    for i, (other, other_sign, other_travel) in enumerate(graph.links):
        #        for j in other:
        #            if j > i:
        #                self.axes.plot([graph.positions[i,0],graph.positions[j,0]],
        #                           [graph.positions[i,1],graph.positions[j,1]],
        #                           'k-')

        self.axes.axis('scaled')
        self.axes.set_xlim(0.0,
                           numpy.maximum.reduce(graph.positions[:, 0]) * 1.1)
        self.axes.set_ylim(0.0,
                           numpy.maximum.reduce(graph.positions[:, 1]) * 1.1)

        self.figure.subplots_adjust(top=0.99,
                                    bottom=0.05,
                                    right=0.99,
                                    left=0.05)

        #pylab.connect('button_press_event', self._on_click)

        self.annotation_pylab = []
        self.clear_annotation()

        self.canvas = FigureCanvas(self.figure)  # a gtk.DrawingArea
        self.canvas.mpl_connect('button_press_event', self._on_down)
        self.canvas.mpl_connect('button_release_event', self._on_up)

        vbox.pack_start(self.canvas)

        hbox = gtk.HBox()
        vbox.pack_start(hbox, False, False, 10)

        label = gtk.Label('Middle click:')
        hbox.pack_start(label, False, False, 5)

        self.radios = {}
        last = None
        for action in actions:
            radio = gtk.RadioButton(group=last, label=action)
            last = radio
            self.radios[action] = radio
            hbox.pack_start(radio, False, False, 5)

        label = gtk.Label('Right click: clear')
        hbox.pack_end(label, False, False, 5)

        self.radios[actions[0]].set_active(True)

        toolbar = NavigationToolbar(self.canvas, self.window)
        vbox.pack_start(toolbar, False, False)

    def run(self):
        self.window.show_all()
        gtk.main()

    def clear_annotation(self):
        self.annotation = {}

    def label(self, name, label):
        ident = self.graph.name_to_ident[name]
        self.axes.text(self.graph.positions[ident, 0],
                       self.graph.positions[ident, 1],
                       label,
                       horizontalalignment='center',
                       verticalalignment='bottom',
                       zorder=100000)

    def arrow(self, names, label):
        positions = [
            self.graph.positions[self.graph.name_to_ident[name]]
            for name in names if self.graph.has(name)
        ]

        if not positions: return  #Error?

        max_positions = max(4, (len(positions) + 29) // 30)  #20
        if len(positions) > max_positions:
            positions = [
                positions[i * (len(positions) - 1) // (max_positions - 1)]
                for i in xrange(max_positions)
            ]

        arrow = Arrow(positions, label, True)

        #names = [ name for name in names if self.graph.has(name) ]
        #
        #if len(names) < 2: return #Error?
        #
        #ident1 = self.graph.name_to_ident[names[0]]
        #ident2 = self.graph.name_to_ident[names[-1]]
        #
        #arrow = Arrow(self.graph.positions[ident1],
        #              self.graph.positions[ident2],
        #              label,
        #              True)
        self.axes.add_artist(arrow)

    def annotate(self, name, mass, r, g, b):
        r *= mass
        g *= mass
        b *= mass
        old_mass, old_r, old_g, old_b = self.annotation.get(
            name, (0.0, 0.0, 0.0, 0.0))
        self.annotation[name] = (old_mass + mass, old_r + r, old_g + g,
                                 old_b + b)

    def refresh_annotation(self):
        while self.annotation_pylab:
            item = self.annotation_pylab.pop(-1)
            item.remove()

        xs = []
        ys = []
        colors = []
        sizes = []
        for name in self.annotation:
            mass, r, g, b = self.annotation[name]
            if not mass: continue

            ident = self.graph.name_to_ident[name]
            xs.append(self.graph.positions[ident, 0])
            ys.append(self.graph.positions[ident, 1])
            colors.append((r / mass, g / mass, b / mass))
            sizes.append(mass)

        if xs:
            #thing = self.axes.scatter(
            #    xs,
            #    ys,
            #    s=sizes,
            #    c=colors,
            #    linewidths=0,
            #    marker='s',
            #    zorder=10000)
            thing = Dots(numpy.array(ys),
                         numpy.array(xs),
                         numpy.array(colors),
                         numpy.array(sizes),
                         zorder=2)
            self.axes.add_artist(thing)
            self.annotation_pylab.append(thing)

        self.canvas.draw()

    def name_from_position(self, x, y):
        xoff = self.graph.positions[:, 0] - x
        yoff = self.graph.positions[:, 1] - y
        dist2 = xoff * xoff + yoff * yoff
        best = numpy.argmin(dist2)

        return self.graph.names[best]

    def _on_down(self, event):
        self.down_name = self.name_from_position(event.xdata, event.ydata)

    def _on_up(self, event):
        if event.inaxes and event.button == 3:
            self.clear_annotation()
            self.refresh_annotation()

        elif event.inaxes and event.button == 2:
            name = self.name_from_position(event.xdata, event.ydata)

            if self.callback:
                action = None
                for item in self.radios:
                    if self.radios[item].get_active():
                        action = item

                self.callback(self, action, self.down_name, name)
                self.refresh_annotation()

            del self.down_name
Example #22
0
class SensorWindow(object):
	def __init__(self, mainThread, gladefile = 'sensor_window.glade'):
		self.builder = gtk.Builder()
		self.builder.add_from_file(gladefile)
		self.builder.connect_signals(self)

		self._stopped = False
		self.mainThread = mainThread

		self.fig = plt.figure()
		self.numLines = 1

		# lines plot
		self.ax = self.fig.add_subplot(111)
		self.ax.set_xlabel('Time')
		self.ax.set_ylabel('Power')
		self.ax.xaxis.set_animated(True)
		self.ax.yaxis.set_animated(True)
		self.ax.set_title('Light Intensity')
		self.ax.grid(True)

		self.start = time.time()
		self.background1 = None
		self.prev_time = self.start
		self.prev_pixel_offset = 0
		self.x0 = 0
		self.value = [0] * self.numLines

		self.ax.set_ylim(-1, 256)

		self.lines = []
		for i in range(self.numLines):
			line, = self.ax.plot([], [], animated = True, lw = 2)
			self.lines.append(line)

		self.canvas = FigureCanvas(self.fig)

		self.graphview = self.builder.get_object("box2")
		self.graphview.pack_start(self.canvas)
		self.graphview.reorder_child(self.canvas, 0)

		self.img = self.builder.get_object("image1")
		self.img.set_from_file("off.svg")
		self.lamp = False

		self.canvas.show()

		gobject.idle_add(self.update_line)
		self.canvas.mpl_connect('draw_event', self.on_draw)

		self.barpath = []


	def close_window(self, obj):
		print "closing window"
		self.builder.get_object("window1").destroy()

	def destroy_callback(self, obj):
		print "destroying window"
		self.mainThread.stop()
		self._stopped = True

	def close_from_mainthread(self):
		print "close from mainthread"
		self.builder.get_object("window1").destroy()


	def toggle_lamp(self):
		print "toggle lamp!!"
		self.img = self.builder.get_object("image1")
		if(self.lamp):
			self.lamp = False
			self.img.set_from_file("off.svg")
		else:
			self.lamp = True
			self.img.set_from_file("on.svg")

	def update_line(self, *args):

		if self._stopped:
			self.destroy_callback(None)
			return False

		if self.background1 is None:
			return True

		cur_time = time.time()
		pixel_offset = int((cur_time - self.start) * 40.)
		dx_pixel = pixel_offset - self.prev_pixel_offset
		self.prev_pixel_offset = pixel_offset
		dx_data = self.get_dx_data(dx_pixel) #cur_time - self.prev_time)

		x0 = self.x0
		self.x0 += dx_data
		self.prev_time = cur_time

		self.ax.set_xlim(self.x0-2, self.x0+0.1)

		# restore background which will plot lines from previous plots
		self.restore_background_shifted(dx_pixel) #x0, self.x0)

		# now plot line segment within [x0, x0+dx_data],
		# Note that we're only plotting a line between [x0, x0+dx_data].
		xx = np.array([x0, self.x0])
		for i in range(len(self.lines)):
			line = self.lines[i]
			line.set_xdata(xx)

			# the for loop below could be improved by using collection.
			line.set_ydata(np.array([self.value[i], self.value[i]]))
			self.ax.draw_artist(line)

		self.background2 = self.canvas.copy_from_bbox(self.get_bg_bbox())

		self.ax.draw_artist(self.ax.xaxis)
		self.ax.draw_artist(self.ax.yaxis)

		self.canvas.blit(self.ax.get_figure().bbox)
		return True

	def get_dx_data(self, dx_pixel):
		tp = self.ax.transData.inverted().transform_point
		x0, y0 = tp((0, 0))
		x1, y1 = tp((dx_pixel, 0))
		return (x1 - x0)

	def get_bg_bbox(self):
		return self.ax.bbox.padded(-3)

	def save_bg(self):
		self.background1 = self.canvas.copy_from_bbox(self.ax.get_figure().bbox)
		self.background2 = self.canvas.copy_from_bbox(self.get_bg_bbox())

	def on_draw(self, *args):
		self.save_bg()
		return False

	def restore_background_shifted(self, dx_pixel):
		"""
		restore bacground shifted by dx in data coordinate. This only
		works if the data coordinate system is linear.
		"""

		# restore the clean slate background
		self.canvas.restore_region(self.background1)

		# restore subregion (x1+dx, y1, x2, y2) of the second bg
		# in a offset position (x1-dx, y1)
		x1, y1, x2, y2 = self.background2.get_extents()
		self.canvas.restore_region(self.background2,
					bbox=(x1+dx_pixel, y1, x2, y2),
					xy=(x1-dx_pixel, y1))

		return dx_pixel

	def update(self, data):
		if type(data) == ListType:
			assert(len(self.lines) == len(data))
			self.value = data
		else:
			assert(len(self.lines) == 1)
			self.value = [data]
Example #23
0
class spectrum_plotter:
	def __init__(self, xs, ys):
		self.xs=xs
		self.ys=ys
		
		self.win = gtk.Window()
		self.win.connect("destroy", lambda x: gtk.main_quit())
		self.win.set_default_size(800,600)
		self.win.set_title("openSpectrometer")

		self.vbox = gtk.VBox()
		self.win.add(self.vbox)
		
		self.fig = Figure(figsize=(5,4), dpi=100)
		self.canvas = FigureCanvas(self.fig)  # a gtk.DrawingArea
		
		self.ax = self.fig.add_subplot(111)
		
		self.canvas.mpl_connect('pick_event', self.onpick)
		
		self.vbox.pack_start(self.canvas)
		self.toolbar = NavigationToolbar(self.canvas, self.win)
		self.hbox = gtk.HBox()
		self.button=gtk.Button('Select this point as lambda max')
		self.button.connect("clicked", self.buttonClick)
		self.hbox.pack_start(self.toolbar)
		self.hbox.pack_start(self.button)
		self.vbox.pack_start(self.hbox, False, False)
		
		self.lastind = 0

		self.text = self.ax.text(0.05, 0.95, 'Datapoint index selected: none',
                            transform=self.ax.transAxes, va='top')
	def plot(self, *args, **kwargs):
		self.ax.plot(*args, **kwargs)
	def plotSelectable(self, *args, **kwargs):
		self.line=self.ax.plot(*args, **kwargs)
	def selectPoint(self, x, y):
		self.selected = self.ax.plot([x],[y], 'o', ms=20, alpha=0.4, 
									   color='yellow', visible=False)
	def show(self):
		self.win.show_all()
		gtk.main()
		return self.lastind
	def buttonClick(self, event):
		self.win.hide_all()
		gtk.main_quit()
	def onpick(self, event):
		if event.artist!=self.line[0]: return True
		
		N = len(event.ind)
		if not N: return True

		if N > 1:
			print '%i points found!' % N

		# the click locations
		x = event.mouseevent.xdata
		y = event.mouseevent.ydata

		dx = numpy.array(x-self.xs[event.ind],dtype=float)
		dy = numpy.array(y-self.ys[event.ind],dtype=float)

		distances = numpy.hypot(dx,dy)
		indmin = distances.argmin()
		dataind = event.ind[indmin]

		self.lastind = dataind
		self.update()

	def update(self):
		if self.lastind is None: return

		dataind = self.lastind
		
		self.selected[0].set_visible(True)
		self.selected[0].set_data(self.xs[dataind], self.ys[dataind])

		# put a user function in here!        
		self.userfunc(dataind)

		self.fig.canvas.draw()

	def userfunc(self,dataind):
		self.text.set_text('datapoint index selected: %d'%dataind)
		print 'No userfunc defined'
		pass
		
Example #24
0
class PopUpImage(object):
	def __init__(self, xdata, ydata, xlabel, ylabel, title):
		self.popupwin=gtk.Window()
		self.popupwin.set_size_request(600,550)
		self.popupwin.set_position(gtk.WIN_POS_CENTER)
		self.popupwin.set_border_width(10)
		self.xdata = xdata
		self.ydata = ydata
		vbox = gtk.VBox()
		self.fig=Figure(dpi=100)
		self.ax  = self.fig.add_subplot(111)
		self.canvas  = FigureCanvas(self.fig)
		self.main_figure_navBar = NavigationToolbar(self.canvas, self)
		self.cursor = Cursor(self.ax, color='k', linewidth=1, useblit=True)
		self.canvas.mpl_connect("button_press_event",self.on_press)
		self.ax.set_xlabel(xlabel, fontsize = 18)
		self.ax.set_ylabel(ylabel, fontsize = 18)
		self.ax.set_title(title, fontsize = 18)
		self.ax.plot(self.xdata, self.ydata, 'b-', lw=2)
		
		self.textes = []
		self.plots  = []
		vbox.pack_start(self.main_figure_navBar, False, False, 0)
		vbox.pack_start(self.canvas, True, True, 2)
		self.popupwin.add(vbox)
		self.popupwin.connect("destroy", self.dest)
		self.popupwin.show_all()
	
	def dest(self,widget):
		self.popupwin.destroy()
	
	def on_press(self, event):
		if event.inaxes == self.ax and event.button==3:
			self.clear_notes()
			xc = event.xdata
			#***** Find the closest x value *****
			residuel = self.xdata - xc
			residuel = N.abs(residuel)
			j = N.argmin(residuel)
			#y = self.ydata[i-1:i+1]
			#yc= y.max()
			#j = N.where(self.ydata == yc)
			#j = j[0][0]
			xc= self.xdata[j]
			x_fit = self.xdata[j-3:j+3]
			y_fit = self.ydata[j-3:j+3]
			fitted_param, fitted_data = fit(x_fit, y_fit, xc, True)
			x_fit = N.linspace(x_fit.min(), x_fit.max(), 200)
			y_fit = psdVoigt(fitted_param, x_fit)
			period = fitted_param['xc'].value
			std_err= fitted_param['xc'].stderr
			
			p = self.ax.plot(x_fit, y_fit,'r-')
			p2 = self.ax.axvline(period,color='green',lw=2)
			
			txt=self.ax.text(0.05, 0.9, 'Period = %.4f +- %.4f (nm)'%(period, std_err), transform = self.ax.transAxes, color='red')
			self.textes.append(txt)
			self.plots.append(p[0])
			self.plots.append(p2)
		elif event.inaxes == self.ax and event.button==2:
			dif = N.diff(self.ydata)
			dif = dif/dif.max()
			p3  = self.ax.plot(dif,'r-')
			self.plots.append(p3[0])
		self.canvas.draw()
	
	def clear_notes(self):
		if len(self.textes)>0:
			for t in self.textes:
				t.remove()
		if len(self.plots)>0:
			for p in self.plots:
				p.remove()
		self.textes = []
		self.plots  = []
Example #25
0
class gui:
    """Main application class."""
    def __init__(self):
        self.builder=gtk.Builder()
        self.dsizes=[]
        self.builder.add_from_file("gladeb.glade")
        myscreen=gtk.gdk.Screen()
        self.screensize=(myscreen.get_width(),myscreen.get_height())
        print self.screensize
        dic={"mainwindowdestroy" : gtk.main_quit,"openwindow":self.openWindow, "closewindow":self.closeWindow, "devicenumchanged":self.changeDeviceNumber, "btnclicked":self.btnclicked, "fileset":self.fileSet, "mctoolbarbtn":self.mctoolbarClicked, "trkeypress":self.getKeyPress}
        self.builder.connect_signals(dic)

        #Initialise defaults
        #Camera config window
        self.devicenumcb = gtk.combo_box_new_text()
        self.builder.get_object("combospace").add(self.devicenumcb)
        self.builder.get_object("combospace").show_all()


        self.devicenumcb.append_text('0')
        self.devicenumcb.append_text('1')
        self.devicenumcb.set_active(0)
        self.devicenumcb.connect("changed", self.changeDeviceNumber)
        self.figurecc=Figure()
        self.axiscc=self.figurecc.add_subplot(111)
        try:
            self.cap = cv2.VideoCapture(self.devicenumcb.get_active())
        except:
            pass

        self.pixelthreshold=0

        #Monitor config window
        self.tolerance=25
        self.blocksize=7
        self.d1size=(80,50)
        self.d2size=None
        self.builder.get_object("tolerance").set_text("25")
        self.builder.get_object("blocksize").set_text("7")
        self.builder.get_object("d1x").set_text("50")
        self.builder.get_object("d1y").set_text("80")
        self.figuremc=Figure()
        self.axismc=self.figuremc.add_subplot(111)
        self.figuretmc=Figure()
        self.axistmc=self.figuretmc.add_subplot(111)
        self.mcflipx=False
        self.mcflipy=False
        self.clickstate="none"
        self.crop1=None
        self.crop2=None
        self.builder.get_object("tolerance").set_editable(True)
        self.builder.get_object("blocksize").set_editable(True)
        self.builder.get_object("d1x").set_editable(True)
        self.builder.get_object("d1y").set_editable(True)
        self.builder.get_object("d2x").set_editable(True)
        self.builder.get_object("d2y").set_editable(True)

        self.contours=[]
        self.dlist=[]
        self.trdlist=[]
        self.figuretr=Figure()
        self.axistr=self.figuretr.add_subplot(111)
        self.trframe=0
        self.trtotal=0
        self.traindict={}
        self.solsdict={}

    #General functions
    def fileSet(self, widget):
        call=gtk.Buildable.get_name(widget)
        if call=="monitorconfigloadfile":
            self.loadMonitorImage(widget.get_filename())
        elif call=="trainingfilechooser":
            self.loadTrainingImage(widget.get_filename())
        elif call=="testmcfile":
            self.loadMonitorImage(widget.get_filename(), testmc=True)

    def btnclicked(self, widget):
        call=gtk.Buildable.get_name(widget)
        if call=="resbtn":
            self.setResolution()
        elif call=="imagesavebtn":
            fname=self.builder.get_object("imagesavetext").get_text()
            if fname!="" and fname!=None:
                self.saveImage(fname)
        elif call=="videosavebtn":
            fname=self.builder.get_object("videosavefile").get_text()
            if fname!="" and fname!=None:
                self.saveVideo(fname)
        elif call=="setparameters":
            self.setParameters()
        elif call=="setdigits":
            self.setDigitSizes()
        elif call=="mcflipx":
            if self.mcflipx==False:
                self.mcflipx=True
            else:
                self.mcflipx=False
            self.loadMonitorImage(self.builder.get_object("monitorconfigloadfile").get_filename())
        elif call=="mcflipy":
            if self.mcflipy==False:
                self.mcflipy=True
            else:
                self.mcflipy=False
            self.loadMonitorImage(self.builder.get_object("monitorconfigloadfile").get_filename())
        elif call=="addtag":
            self.setClickMode("tag")
        elif call=="cleartags":
            #TODO Clear tags
            pass
        elif call=="addcontour":
            self.setClickMode("addcontour1")
        elif call=="rmcontour":
            self.setClickMode("rmcontour")
        elif call=="splitcontour":
            self.setClickMode("splitcontour")
        elif call=="cropimage":
            self.setClickMode("crop1")
        elif call=="getdigitsize":
            self.setClickMode("getdigit1")
        elif call=="tagokbtn":
            self.curtag=self.builder.get_object("tagname").get_text()   
            self.builder.get_object("tagwindow").set_visible(0)   
            self.contours.append(Contour(self.tempditem,self.tempitem,self.curtag))
            if not (self.d1size in self.dsizes):
                self.dsizes.append(self.d1size)
        elif call=="tagcancelbtn":
            self.setClickMode("none")
            self.builder.get_object("tagwindow").set_visible(0)
        elif call=="trnext":
            self.trNext()

        elif call=="trprev":
            if self.trframe>0:
                self.trframe-=1
                self.updateTrainingDataWindow()
        elif call=="savetrdata":
            fn=self.builder.get_object("trfile").get_text()
            f=open(fn, "w")
            pickle.dump(self.traindict, f)
            f.close()
        elif call=="allconts":
            #show all contours in monitor config window
            self.loadMonitorImage(self.builder.get_object("monitorconfigloadfile").get_filename(), allconts=True)
            
        elif call=="clearunsaved":
            #redraw only those ritems in self.contours
            self.drawMonitor(clearunsaved=True)
            
        elif call=="liverecord":
            #TODO test? Fix all parameters here
            #start loop to get data
            fn=self.builder.get_object("livefile").get_text()
            f=open(fn,"r")
            #log to f

            while True:
                self.livelist=[]
                #get image using current camera config
                ret,im=self.cap.read()
                #run contour detection
                (self.monimage,self.dlist,self.rlist)=self.getContours(a,self.d1size)
                #take only labelled ones
                for i in range(len(self.rlist)):
                    for j in range(len(self.contours)):
                        #if self.rlist[i]==cont.ritem:
                        #TODO remove hidden parameters here
                        cont=self.contours[j]
                        if np.abs(self.rlist[i][0][0]-cont.ritem[0][0])<=4 and np.abs(self.rlist[i][0][1]-cont.ritem[0][1])<=4:
                            #Need to append x position, label
                            self.livelist.append((self.dlist[i],j))
                    #could add width, height check as well
                
                #run digit analysis
                #TODO - modify this for known number of digits?
                for item2 in self.livelist:
                    item=item2[0][0]
                    q=False
                    #data = np.zeros((esize), dtype=np.uint8)
                    esize1=self.d1size[0]*self.d1size[1]
                #results=[]
                #err=[]
                    data=item.flatten()
                    boolarray=(data>self.pixelthreshold)
                    resultd=[]
                    #print self.traindict.keys()
                    for j in range(len(self.traindict.keys())):
                        result=np.sum(self.traindict[j][boolarray])
                        #penalisation factor
                        result-=4*np.sum(self.traindict[j][data<=self.pixelthreshold])
                        resultd.append(result/float(esize1))
                    #print resultd
                    # sr=reversed(sorted(resultd))
                    # srlist=[]
                    # for j in sr:
                    #     srlist.append(j)
                    # err.append(srlist[0]-srlist[1])
                    resultf=(resultd.index(max(resultd)))
                    #print resultf
                    if max(resultd)<-0.1:
                        #print "IGNORE!"
                        q=True

                    #print "---"
                    #cv2.imshow("newtest",item)
                    #cv2.waitKey(0)
                    #Append digit to correct place
                    #rl = {mlabel:{x:(1,q)}}

                    #use label instead of y co-ordinate as constant
                    if self.contours[item2[1]].label in rl.keys():
                        rl[self.contours[item2[1]].label][item2[0][1]]=(resultf, q)
                    else:
                        rl[self.contours[item2[1]].label]={item2[0][1]:(resultf,q)}

                #Want data structure instead of string
                
                for key in sorted(rl.iterkeys()):
                    #print "%s: %s" % (key, mydict[key]) 

                    for key2 in sorted(rl[key].iterkeys()):
                        string+=str(rl[key][key2][0])
                        #if rl[key][key2][1]==False:
                            #create solutions dictionary
                            #string+=str(rl[key][key2][0])
                            
                        #if rl[key][key2][1]==True:
                            #string+="?"
                    solsdict[self.contours[item2[1]].label]=string
                #reconstruct labelled data
                for item in solsdict.keys():
                    f.write(item +":" + solsdict[item])
                f.write("\n")
                #log to f


    def trNext(self):
        if self.trframe<(self.trtotal-1):
            self.trframe+=1    
            self.updateTrainingDataWindow()
        
    def openWindow(self, widget):

        #Make dict of widgets to functions
        call=gtk.Buildable.get_name(widget)
        if call=="opencameraconfig":
            self.openCameraConfig()
        elif call=="openimagesave": 
            self.builder.get_object("imagesavewindow").set_visible(1)
        elif call=="openrecordvideo": 
            self.builder.get_object("videosavewindow").set_visible(1)
        elif call=="openmonitorconfig": 
            self.builder.get_object("monitorconfig").set_visible(1)
        elif call=="opentrainingdatawindow": 
            self.builder.get_object("trainingdatawindow").set_visible(1)
        elif call=="openlive": 
            self.builder.get_object("livewindow").set_visible(1)
        elif call=="opentmc":
            self.builder.get_object("testmcwindow").set_visible(1)

    def closeWindow(self,widget):
        call=gtk.Buildable.get_name(widget)
        if call=="closecameraconfig":
            self.applyCameraConfig()
        elif call=="imagesaveclosebtn":
            self.builder.get_object("imagesavewindow").set_visible(0)
        elif call=="closevideowindow":
            self.builder.get_object("videosavewindow").set_visible(0)
        elif call=="closemonitorconfig":
            self.builder.get_object("monitorconfig").set_visible(0)
        elif call=="closetrainingwindow":
            self.builder.get_object("trainingdatawindow").set_visible(0)
        elif call=="closelive":
            self.builder.get_object("livewindow").set_visible(0)
        elif call=="closetc":
            self.builder.get_object("testmcwindow").set_visible(0)
    #Camera config functions
    def openCameraConfig(self):
        try:
            self.builder.get_object("ccimgbox").remove(self.canvascc)
        except:
            pass
        ret,img = self.cap.read() 
        try:
            img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
            #cv2.imshow("newtest",img)
        except:
            img=np.zeros((100,100))
        self.builder.get_object("resx").set_text(str(img.shape[1]))
        self.builder.get_object("resy").set_text(str(img.shape[0]))
        self.resolution=(img.shape[1], img.shape[0])

        if img.shape[1]<self.screensize[0] and img.shape[0]<self.screensize[1]:
            pass
        else:
            img=imresize(img, (img.shape[0]/2, img.shape[1]/2))
            

        self.axiscc.imshow(img, cmap=cm.gray) #set scale to 0,255 somehow
        self.canvascc=FigureCanvasGTKAgg(self.figurecc)
        self.canvascc.draw()
        self.canvascc.show()
        self.builder.get_object("ccimgbox").pack_start(self.canvascc, True, True)

        self.builder.get_object("cameraconfig").set_visible(1)
    def applyCameraConfig(self):
        self.builder.get_object("cameraconfig").set_visible(0)
    def changeDeviceNumber(self, widget):
        self.cap = cv2.VideoCapture(self.devicenumcb.get_active())
        self.openCameraConfig()

    def setResolution(self):
        x=self.builder.get_object("resx").get_text()
        y=self.builder.get_object("resy").get_text()
        self.cap.set(3,int(x))
        self.cap.set(4,int(y))
        self.resolution=(int(x),int(y))
        self.openCameraConfig()

    #Image saving
    def saveImage(self,fname):
        if fname!="" or None:
            ret,im=self.cap.read()
            cv2.imwrite(fname,im)

    #Video saving
    def saveVideo(self,fname):
        try:
            if fname.lower()[-4:]!=".avi":
                fname=fname+".avi"
        except:
            fname=fname+".avi"
        video  = cv2.VideoWriter(fname,CV_FOURCC(ord("D"),ord("I"),ord("V"),ord("X")), 25, self.resolution)
        ret,im = self.cap.read() 
        for i in range(1000):
            ret,im = self.cap.read() 
            video.write(im)
        video.release()
        #TODO: May want to chuck away last frame - perhaps do this in analysis

    #Monitor configuration
    def loadMonitorImage(self,fname, allconts=False, testmc=False):
        if fname[-4:].lower()==".avi":
            #TODO get first frame - look this up
            pass
        elif fname[-4:].lower()==".png" or fname[-4:].lower()==".jpg":
            a=cv2.imread(fname, 0) #note 0 implies grayscale
            #getcontours
        else:
            #Error
            pass
        if self.mcflipx==True and self.mcflipy==True:
            a=cv2.flip(a,-1)
        elif self.mcflipx==True and self.mcflipy==False:
            a=cv2.flip(a,0)
        if self.mcflipy==True and self.mcflipx==False:
            a=cv2.flip(a,1)
        if self.crop1!=None and self.crop2!=None:
            #print str(self.crop1)
            #print str(self.crop2)
            a=a[np.min([self.crop1[1],self.crop2[1]]):np.max([self.crop1[1],self.crop2[1]]),np.min([self.crop1[0],self.crop2[0]]):np.max([self.crop1[0],self.crop2[0]])] 

            #TODO add other digit sizes
        if testmc==True:
            self.trlist=[]
            for dsize in self.dsizes:
                (self.tmonimage,self.dlist,rlist)=self.getContours(a,dsize)
                self.trlist+=rlist
            self.drawMonitorTest()
        else:
            if allconts==False:
                (self.monimage,self.dlist,self.rlist)=self.getContours(a,self.d1size)
                self.drawMonitor()
            else:
                (self.monimage,self.rlist1,self.rlist2)=self.getAllContours(a)
                self.drawMonitor(allconts=True)

    def setParameters(self):
        self.tolerance=int(self.builder.get_object("tolerance").get_text())
        self.blocksize=int(self.builder.get_object("blocksize").get_text())
        self.loadMonitorImage(self.builder.get_object("monitorconfigloadfile").get_filename())

    def setDigitSizes(self):
        if (self.builder.get_object("d1y").get_text()!=None and self.builder.get_object("d1y").get_text()!="") and (self.builder.get_object("d1x").get_text()!="" and self.builder.get_object("d1x").get_text()!=None):
            self.d1size=(int(self.builder.get_object("d1y").get_text()),int(self.builder.get_object("d1x").get_text()))
        else:
            self.d1size=None

        if (self.builder.get_object("d2y").get_text()!=None and self.builder.get_object("d2y").get_text()!="") and (self.builder.get_object("d2x").get_text()!="" and self.builder.get_object("d2x").get_text()!=None):
            self.d2size=(int(self.builder.get_object("d2y").get_text()),int(self.builder.get_object("d2x").get_text()))
        else:
            self.d2size=None
            
        #Redo contours, etc.
        self.loadMonitorImage(self.builder.get_object("monitorconfigloadfile").get_filename())

    def getContours(self,a,dsize):
        a=cv2.GaussianBlur(a,(3,3), 0)
        orig=a.copy()
        a=cv2.adaptiveThreshold(a, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, self.tolerance, self.blocksize)
        b=a.copy()
        contours, hierarchy = cv2.findContours(a, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS)
        mask = np.zeros(a.shape, dtype=np.uint8)
        dlist=[]
        output=np.zeros(b.shape,dtype=np.uint8)
        rlist=[]
        for cont in contours:

            br=cv2.boundingRect(cont)
            charray=np.zeros(dsize, dtype=np.uint8)
            temp=b[br[1]:br[1]+br[3], br[0]:br[0]+br[2]]

            if temp.shape[0]>10 and temp.shape[1]>10:
                temp=cv2.bitwise_not(temp)
                temp2=temp.copy()
                contours2, hierarchy = cv2.findContours(temp2, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
                for cont2 in contours2:
                    br2=cv2.boundingRect(cont2)
                    #important hidden parameters
                    if br2[3]<dsize[0]+20 and br2[3]>dsize[0]-20 and br2[2]<dsize[1]+20 and br2[2]>dsize[1]-60:
                        #After cropping, edge constrains not necessary
                        # and br2[0]>0+(temp.shape[1]/40.0) and br2[0]<temp.shape[1]-(temp.shape[1]/40.0)
                        mask = np.zeros(temp2.shape, dtype=np.uint8)
                        cv2.drawContours(mask,[cont2],0,255,-1)

                        temp2=temp.copy()
                        temp2[mask==0]=0

                        temp3=temp2[br2[1]:br2[1]+br2[3], br2[0]:br2[0]+br2[2]]
                        charray=temp3.copy()
                        charray=imresize(charray, dsize)
                        #dlist.append((charray, br[0]+br2[0], br[1]))

                        if br2[2]>5 and br2[3]>5:
                            #cv2.rectangle(b, (br[0]+br2[0],br[1]+br2[1]), (br[0]+br2[0]+br2[2],br[1]+br2[1]+br2[3]), 100)
                            dlist.append((charray, br[0]+br2[0], br[1]))
                            rlist.append(((br[0]+br2[0], br[1]+br2[1]), br2[2], br2[3]))


        return (b,dlist,rlist)

    def getAllContours(self,a):
        a=cv2.GaussianBlur(a,(3,3), 0)
        orig=a.copy()
        a=cv2.adaptiveThreshold(a, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, self.tolerance, self.blocksize)
        b=a.copy()
        contours, hierarchy = cv2.findContours(a, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS)
        mask = np.zeros(a.shape, dtype=np.uint8)

        output=np.zeros(b.shape,dtype=np.uint8)
        rlist1=[]
        rlist2=[]
        for cont in contours:

            br=cv2.boundingRect(cont)
            rlist1.append(((br[0], br[1]), br[2], br[3]))
            temp=b[br[1]:br[1]+br[3], br[0]:br[0]+br[2]]

            if temp.shape[0]>5 and temp.shape[1]>5:
                temp=cv2.bitwise_not(temp)
                temp2=temp.copy()
                contours2, hierarchy = cv2.findContours(temp2, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
                for cont2 in contours2:
                    br2=cv2.boundingRect(cont2)

                    #if br2[3]<dsize[0]+10 and br2[3]>dsize[0]-10 and br2[2]<dsize[1]+10 and br2[2]>dsize[1]-50 and br2[0]>0+(temp.shape[1]/30) and br2[0]<temp.shape[1]-(temp.shape[1]/5):
                    mask = np.zeros(temp2.shape, dtype=np.uint8)
                    cv2.drawContours(mask,[cont2],0,255,-1)

                    temp2=temp.copy()
                    temp2[mask==0]=0

                    temp3=temp2[br2[1]:br2[1]+br2[3], br2[0]:br2[0]+br2[2]]
                    #dlist.append((charray, br[0]+br2[0], br[1]))

                    if br2[2]>3 and br2[3]>3:
                        #cv2.rectangle(b, (br[0]+br2[0],br[1]+br2[1]), (br[0]+br2[0]+br2[2],br[1]+br2[1]+br2[3]), 100)
                        #dlist.append((charray, br[0]+br2[0], br[1]))
                        rlist2.append(((br[0]+br2[0], br[1]+br2[1]), br2[2], br2[3]))


        return (b,rlist1, rlist2)


    def drawMonitor(self, allconts=False, clearunsaved=False):
        try:
            self.builder.get_object("monitorconfigspace").remove(self.canvasmc)
            self.axismc.clear()
            #self.builder.get_object("mctoolbar").remove(self.mctoolbar)	
        except:
            pass

        #Add cropping
        self.axismc.imshow(self.monimage, cmap=cm.gray) #set scale to 0,255 somehow

        #Maybe this needn't be redefined for every draw - only need draw() but not drawn often anyway
        self.canvasmc=FigureCanvasGTKAgg(self.figuremc)

        self.canvasmc.draw()
        self.canvasmc.show()
        self.canvasmc.mpl_connect('motion_notify_event', self.mcHoverOnImage)
        self.canvasmc.mpl_connect('button_release_event', self.mcCaptureClick)

        self.builder.get_object("monitorconfigspace").pack_start(self.canvasmc, True, True)

        #TODO stop this getting so complicated
        if clearunsaved==False:
            if allconts==False:
                for item in self.rlist:
                    #Structure of rlist:
                    #rlist.append(((br[0]+br2[0], br[1]+br2[1]), br2[2], br2[3]))
                    r=Rectangle(item[0], item[1], item[2], fill=False, color="red")
                    #Rectangle has (lowerleft, width, height)
                    self.axismc.add_patch(r)               
            elif allconts==True:
                #allcontours
                for item in self.rlist1:
                    #Structure of rlist:
                    #rlist.append(((br[0]+br2[0], br[1]+br2[1]), br2[2], br2[3]))
                    r=Rectangle(item[0], item[1], item[2], fill=False, color="blue")
                    #Rectangle has (lowerleft, width, height)
                    self.axismc.add_patch(r)
                for item in self.rlist2:
                    #Structure of rlist:
                    #rlist.append(((br[0]+br2[0], br[1]+br2[1]), br2[2], br2[3]))
                    r=Rectangle(item[0], item[1], item[2], fill=False, color="green")
                    #Rectangle has (lowerleft, width, height)
                    self.axismc.add_patch(r)

        #Always draw saved contours in blue
        for ditem in self.contours:
            item=ditem.ritem
            r=Rectangle(item[0], item[1], item[2], fill=False, color="blue")
            self.axismc.add_patch(r)


    def drawMonitorTest(self):
        try:
            self.builder.get_object("tmcspace").remove(self.canvastmc)
            self.axistmc.clear()
        except:
            pass
        #Add cropping
        self.axistmc.imshow(self.tmonimage, cmap=cm.gray) #set scale to 0,255 somehow

        #Maybe this needn't be redefined for every draw - only need draw() but not drawn often anyway
        self.canvastmc=FigureCanvasGTKAgg(self.figuretmc)

        self.canvastmc.draw()
        self.canvastmc.show()
        self.builder.get_object("tmcspace").pack_start(self.canvastmc, True, True)


        for i in range(len(self.trlist)):
            for cont in self.contours:
                #if self.rlist[i]==cont.ritem:
                #TODO remove hidden parameters here
                if np.abs(self.trlist[i][0][0]-cont.ritem[0][0])<=4 and np.abs(self.trlist[i][0][1]-cont.ritem[0][1])<=4:
                    item=self.trlist[i]
                    r=Rectangle(item[0], item[1], item[2], fill=False, color="blue")
                    self.axistmc.add_patch(r)
                    #could add width, height check as well

        #Always draw saved contours in blue
        for ditem in self.contours:
            item=ditem.ritem



    def mcHoverOnImage(self, event):
        #add contour stuff here if not too expensive
        #find innermost contour
        #Cannot afford to redraw, must work out how to remove rectangle afterwards since only one at a time
        #TODO
        if event.x!=None and event.y!=None and event.xdata!=None and event.ydata!=None:
            pass
        
    def mcCaptureClick(self, event):
        #print "click"
        if self.clickstate=="none":
            pass
        #elif not(event.x==None or event.y==None or event.xdata==None or event.ydata==None):
        else:
            if self.clickstate=="crop1":
                self.crop1=(int(round(event.xdata)), int(round(event.ydata)))
                self.setClickMode("crop2")

            elif self.clickstate=="getdigit1":
                self.getdigit1=(int(round(event.xdata)), int(round(event.ydata)))
                self.setClickMode("getdigit2")

            elif self.clickstate=="crop2":
                self.crop2=(int(round(event.xdata)), int(round(event.ydata)))
                self.setClickMode("none")
                self.loadMonitorImage(self.builder.get_object("monitorconfigloadfile").get_filename())    

            elif self.clickstate=="getdigit2":
                self.getdigit2=(int(round(event.xdata)), int(round(event.ydata)))
                #apply stuff
                self.d1size=(np.abs(self.getdigit2[1]-self.getdigit1[1]),np.abs(self.getdigit2[0]-self.getdigit1[0]))
                self.builder.get_object("d1x").set_text(str(np.abs(self.getdigit2[0]-self.getdigit1[0])))
                self.builder.get_object("d1y").set_text(str(np.abs(self.getdigit2[1]-self.getdigit1[1])))
                self.setClickMode("none")
                self.loadMonitorImage(self.builder.get_object("monitorconfigloadfile").get_filename())


            elif self.clickstate=="tag":
                #Check if we are inside contour, if so present label window, if not, ignore
                #Contours checked by rlist?
                coords=(int(round(event.xdata)), int(round(event.ydata)))
                #found=False
                #Find innermost not just first contour
                fitem=None
                fi=None
                for i in range(len(self.rlist)):
                    item=self.rlist[i]
                    if (coords[0] >= item[0][0]) and (coords[0] <= (item[0][0]+item[1])) and (coords[1] >= item[0][1]) and (coords[1] <= item[0][1]+item[2]):
                        #Found contour, create contour object for final contour list
                        if fitem==None:
                            fitem=item
                            fi=i
                        else:
                            if (item[0][0] >= fitem[0][0]) and (item[0][0]+item[1] <= (fitem[0][0]+fitem[1])) and (item[0][1] >= fitem[0][1]) and (item[0][1]+item[2] <= fitem[0][1]+fitem[2]):
                                fitem=item
                                fi=i
                if fitem!=None:
                    self.tempitem=fitem
                    self.tempditem=self.rlist[fi]
                    self.builder.get_object("tagwindow").set_visible(1)
                        #self.contours.append(Contour(item,self.curtag))
                        

    def mctoolbarClicked(self,widget):
        call=gtk.Buildable.get_name(widget)
        if call=="mczoomin":
            self.mcZoomIn()
        elif call=="mczoomout":
            self.mcZoomOut()
        elif call=="mcpanleft":
            self.mcPanLeft()
        elif call=="mcpanright":
            self.mcPanRight()
        elif call=="mcpanup":
            self.mcPanUp()
        elif call=="mcpandown":
            self.mcPanDown()
        elif call=="mcresetzoom":
            self.mcResetZoom()


    def mcZoomIn(self):
        xlims=self.axismc.get_xlim()
        ylims=self.axismc.get_ylim()
        xchange=abs(xlims[1]-xlims[0])*0.1
        ychange=abs(ylims[1]-ylims[0])*0.1
        self.axismc.set_xlim(left=xlims[0]+xchange, right=xlims[1]-xchange)
        self.axismc.set_ylim(top=ylims[1]+ychange, bottom=ylims[0]-ychange)
        self.builder.get_object("monitorconfigspace").remove(self.canvasmc)
        self.builder.get_object("monitorconfigspace").pack_start(self.canvasmc, True, True)
        
    def mcZoomOut(self):
        xlims=self.axismc.get_xlim()
        ylims=self.axismc.get_ylim()
        xchange=abs(xlims[1]-xlims[0])*0.111
        ychange=abs(ylims[1]-ylims[0])*0.111
        self.axismc.set_xlim(left=xlims[0]-xchange, right=xlims[1]+xchange)
        self.axismc.set_ylim(top=ylims[1]-ychange, bottom=ylims[0]+ychange)
        self.builder.get_object("monitorconfigspace").remove(self.canvasmc)
        self.builder.get_object("monitorconfigspace").pack_start(self.canvasmc, True, True)

    def mcPanLeft(self):
        xlims=self.axismc.get_xlim()
        xchange=abs(xlims[1]-xlims[0])*0.1
        self.axismc.set_xlim(left=xlims[0]-xchange, right=xlims[1]-xchange)
        self.builder.get_object("monitorconfigspace").remove(self.canvasmc)
        self.builder.get_object("monitorconfigspace").pack_start(self.canvasmc, True, True)

    def mcPanRight(self):
        xlims=self.axismc.get_xlim()
        xchange=abs(xlims[1]-xlims[0])*0.1
        self.axismc.set_xlim(left=xlims[0]+xchange, right=xlims[1]+xchange)
        self.builder.get_object("monitorconfigspace").remove(self.canvasmc)
        self.builder.get_object("monitorconfigspace").pack_start(self.canvasmc, True, True)

    def mcPanDown(self):
        ylims=self.axismc.get_ylim()
        ychange=abs(ylims[1]-ylims[0])*0.1
        self.axismc.set_ylim(top=ylims[1]+ychange, bottom=ylims[0]+ychange)
        self.builder.get_object("monitorconfigspace").remove(self.canvasmc)
        self.builder.get_object("monitorconfigspace").pack_start(self.canvasmc, True, True)
	    
    def mcPanUp(self):
        ylims=self.axismc.get_ylim()
        ychange=abs(ylims[1]-ylims[0])*0.1
        self.axismc.set_ylim(top=ylims[1]-ychange, bottom=ylims[0]-ychange)
        self.builder.get_object("monitorconfigspace").remove(self.canvasmc)
        self.builder.get_object("monitorconfigspace").pack_start(self.canvasmc, True, True)

    def mcResetZoom(self):
        #Reset view to original somehow - fit entire image
        pass

    def setClickMode(self,mode):
        #none, crop1, crop2, tag, addcontour1, addcontour2, rmcontour, splitcontour, getdigit1, getdigit2
        self.builder.get_object("mcclickmode").set_label("Mode:" + str(mode))
        self.clickstate=mode

    def loadTrainingImage(self,fname):
        if fname[-4:].lower()==".avi":
            #get first frame - look this up
            pass
        elif fname[-4:].lower()==".png" or fname[-4:].lower()==".jpg":
            a=cv2.imread(fname, 0) #note 0 implies grayscale
            #getcontours
        else:
            #Error
            pass
        if self.mcflipx==True and self.mcflipy==True:
            a=cv2.flip(a,-1)
        elif self.mcflipx==True and self.mcflipy==False:
            a=cv2.flip(a,0)
        if self.mcflipy==True and self.mcflipx==False:
            a=cv2.flip(a,1)
        if self.crop1!=None and self.crop2!=None:
            #print str(self.crop1)
            #print str(self.crop2)
            a=a[np.min([self.crop1[1],self.crop2[1]]):np.max([self.crop1[1],self.crop2[1]]),np.min([self.crop1[0],self.crop2[0]]):np.max([self.crop1[0],self.crop2[0]])] 
        (self.monimage,self.dlist,self.rlist)=self.getContours(a,self.d1size)

        #for cont in self.contours:
            #add individual digits to list, then tag list
            #self.dlist.append(self.monimage[cont.ritem[0][1]:cont.ritem[0][1]+cont.ritem[2],cont.ritem[0][0]:cont.ritem[0][0]+cont.ritem[1]])

        #TODO FIX THIS - need to take ditem of new image, not config one, where the coords are the same
        #for cont in self.contours:
            #self.dlist.append(cont.ditem[0])
        for i in range(len(self.rlist)):
            for cont in self.contours:
                #if self.rlist[i]==cont.ritem:
                #TODO remove hidden parameters here
                if np.abs(self.rlist[i][0][0]-cont.ritem[0][0])<=4 and np.abs(self.rlist[i][0][1]-cont.ritem[0][1])<=4:
                    self.trdlist.append(self.dlist[i])
                    self.trtotal+=1
                    #could add width, height check as well

        #update display
        self.updateTrainingDataWindow()

    def updateTrainingDataWindow(self):
        #Use curframe number, like TesiDogs program
        try:
            self.builder.get_object("bvbox3").remove(self.canvastr)
            self.axistr.clear()
        except:
            pass

        self.axistr.imshow(self.trdlist[self.trframe][0], cmap=cm.gray) #set scale to 0,255 somehow
        self.canvastr=FigureCanvasGTKAgg(self.figuretr)
        self.canvastr.draw()
        self.canvastr.show()
        self.builder.get_object("bvbox3").pack_start(self.canvastr, True, True)
        self.builder.get_object("trframecount").set_label(str(self.trframe+1) + "/" + str(self.trtotal))
        #self.builder.get_object("trcursol").set_label(str(self.trframe+1) + "/" + str(self.trtotal))
        
        #TODO update labels
        #bvbox3
        #trframecount
        #trcursol

    def getKeyPress(self, widget, event):
        #TODO training
        #GTKwidget keyreleaseevent
        ci=event.keyval
        ci=ci-48
        if event.keyval==45:
            #set to not a number
            self.trNext()
        elif ci in [0,1,2,3,4,5,6,7,8,9]:
            data=self.trdlist[self.trframe][0].flatten()
            if ci in self.traindict.keys():
                self.traindict[ci]+=data
                self.traindict[ci]/=2.0
                self.trNext()
            else:
                self.traindict[ci]=data
                self.trNext()

    def sumpmtestlive(self):
        rl={}

        for item2 in dlist:
            item=item2[0]
            q=False
            data = np.zeros((esize1), dtype=np.uint8)
        #results=[]
        #err=[]
            data=item.flatten()
            boolarray=(data>self.pixelthreshold)
            resultd=[]
            #print tdict.keys()
            for j in range(len(tdict.keys())):
                result=np.sum(tdict[j][boolarray])
                #penalisation factor
                result-=4*np.sum(tdict[j][data<=self.pixelthreshold])
                resultd.append(result/float(esize1))
            #print resultd
            # sr=reversed(sorted(resultd))
            # srlist=[]
            # for j in sr:
            #     srlist.append(j)
            # err.append(srlist[0]-srlist[1])
            resultf=(resultd.index(max(resultd)))
            #print resultf
            if max(resultd)<-0.1:
                #print "IGNORE!"
                q=True

            #print "---"
            #cv2.imshow("newtest",item)
            #cv2.waitKey(0)
            #Append digit to correct place
            #rl = {y:{x:(1,q)}}

            if item2[2] in rl.keys():
                rl[item2[2]][item2[1]]=(resultf, q)
            else:
                rl[item2[2]]={item2[1]:(resultf,q)}

        string=""
        for key in sorted(rl.iterkeys()):
            #print "%s: %s" % (key, mydict[key]) 

            for key2 in sorted(rl[key].iterkeys()):
                if rl[key][key2][1]==False:
                    string+=str(rl[key][key2][0])
                #if rl[key][key2][1]==True:
                    #string+="?"
            string+=" "

        print string
Example #26
0
class DataManager(gtk.Window):
        # read default data from a file into the list view
	read_data_csv()

        # global variables needed to share among classes
	global labels
	global data

        # dimensions of data
	numRows=len(data[0])
	numCols=len(labels)

        ###########################################################################################
	def __init__(self):
                # init gtk::Window
		gtk.Window.__init__(self)
		self.set_default_size(600, 800)
		self.connect('destroy', lambda win: gtk.main_quit())

                # load data for plots
		self.data=data
		self.xdata=self.data[0]
		self.ydata=self.data[3]

		self.set_title('DOSEMATIC v0.1')

                # variable name -- TODO
		self.xvariable="Dose"
		self.xvar="D"
		self.xunits="Gy"
		self.yvariable="Yield"
		self.yvar="Y"
		self.yunits=""

                # main layout container
		main_eb = gtk.EventBox()

                # horizontal box
		hbox = gtk.HBox(False, 8)
                # vertical box
		VBOX = gtk.VBox(False, 0)

		main_eb.add(VBOX)
		#main_eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(red=60000,green=60000,blue=60000))
		self.add(main_eb)
		vbox1 = gtk.VBox(False,8)
		vbox2 = gtk.VBox(False,8)
		hbox.pack_start(vbox1, True, True)
		hbox.pack_start(vbox2, True, True)

		top_band = gtk.HBox()
		bottom_band = gtk.HBox()
		top_eb = gtk.EventBox()
		bottom_eb = gtk.EventBox()
		top_eb.add(top_band)
		bottom_eb.add(bottom_band)
		top_eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0,0,0))
		bottom_eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0,0,0))
		l1 = gtk.Label('DOSEMATIC v1.0 --- beta testing --- module 1, basic view')
		l2 = gtk.Label('author: Maciej Lewicki                                       [email protected],   [email protected]')
		top_band.add(l1)
		bottom_band.add(l2)
		hruler = gtk.HSeparator()
		hruler2 = gtk.HSeparator()
		VBOX.pack_start(top_eb,False,False)
		VBOX.pack_start(hruler,False,True,5)
		VBOX.pack_start(hbox,True,True)
		VBOX.pack_start(hruler2,False,True,5)
		VBOX.pack_end(bottom_eb,False,False)

		# TREE VIEW________________________________________________________
		self.model = self.create_model()		# MODEL
		self.treeview = gtk.TreeView(self.model)	# TREE VIEW
		self.treeview.set_rules_hint(True)
		self.add_columns()				# FILL COLUMNS
		# -> TREE VIEW BUTTONS
		button_add1 = gtk.Button('Add row')		# ADD 1 ROW
		button_add10 = gtk.Button('Add 10 rows')	# ADD 10 ROWS
		button_load = gtk.Button("Load data")		# LOAD FILE
		button_save = gtk.Button("Save data")		# LOAD FILE
		hbox_buttons = gtk.HBox(False,5)		# layout packaging
		hbox_buttons2 = gtk.HBox(False,5)		# layout packaging
		hbox_buttons.pack_start(button_add1, True, True)
		hbox_buttons.pack_start(button_add10, True, True)
		hbox_buttons2.pack_start(button_load, True, True)
		hbox_buttons2.pack_start(button_save, True, True)
		vbox2.pack_start(hbox_buttons2, False, False)
		vbox2.pack_end(hbox_buttons, False, False)
		button_add1.connect('clicked',self.add_rows,1)	# SIGNALS HANDLING
		button_add10.connect('clicked',self.add_rows,10)
		button_load.connect('clicked',self.on_load_file)
		button_save.connect('clicked',self.on_save_file)
		# -> INTO SCROLABLE WINDOW
		self.sw = gtk.ScrolledWindow()
		self.sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
		self.sw.set_policy(gtk.POLICY_NEVER,gtk.POLICY_AUTOMATIC)
		self.sw.add(self.treeview)			# ADD TO SW
		vbox2.pack_start(self.sw, True, True)
		#__________________________________________________________________

		# TEXT SCREEN______________________________________________________
		self.text = gtk.TextView()				# TEXT VIEW
		self.text.set_wrap_mode(gtk.WRAP_WORD)		# wrap words
		self.scroll_text = gtk.ScrolledWindow()		# into scrollable env
		self.scroll_text.set_shadow_type(gtk.SHADOW_ETCHED_IN)
		self.scroll_text.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
		self.scroll_text.add(self.text)
		text_view_box = gtk.VBox(False,5)
		text_view_box.pack_start(self.scroll_text,True,True)
		#__________________________________________________________________

		# ESTIMATOR________________________________________________________
		estimator_box = gtk.HBox(False,5)
		self.estxt = gtk.TextView()
		self.estxt.set_wrap_mode(gtk.WRAP_WORD)
		self.scroll_estxt = gtk.ScrolledWindow()
		self.scroll_estxt.set_shadow_type(gtk.SHADOW_ETCHED_IN)
		self.scroll_estxt.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
		self.scroll_estxt.add(self.estxt)
		label = gtk.Label(self.yvariable+' = ')
		entry = gtk.Entry()
		entry.set_text("0.00")
		button = gtk.Button('Estimate '+self.xvariable)
		button.connect('clicked',self.y_estimate,entry)
		combo = gtk.combo_box_new_text()
		combo.append_text("Method A")
		combo.append_text("Method B")
		combo.append_text("Method C-original")
		combo.append_text("Method C-simplified")
		self.method="Method C-simplified"
		combo.set_active(3)
		combo.connect('changed', self.on_method_changed)
		ruler = gtk.HSeparator()
		grid = gtk.Table(2,4)
		grid.attach(label, 0,1,0,1)
		grid.attach(entry, 1,2,0,1)
		grid.attach(button, 0,2,1,2)
		grid.attach(ruler,0,2,2,3)
		grid.attach(combo,0,2,3,4)
		estimator_box.pack_start(grid,False,False)
		estimator_box.pack_start(self.scroll_estxt,True,True)
		#__________________________________________________________________

		# FUNCTION TAB_____________________________________________________
		function_box = gtk.HBox(False,5)
		self.ftxt = gtk.TextView()
		self.ftxt.set_wrap_mode(gtk.WRAP_WORD)
		self.scroll_ftxt = gtk.ScrolledWindow()
		self.scroll_ftxt.set_shadow_type(gtk.SHADOW_ETCHED_IN)
		self.scroll_ftxt.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
		self.scroll_ftxt.add(self.ftxt)
		label_Y = gtk.Label()
		label_Y.set_use_markup(True)
		label_Y.set_markup('Y = c + &#945;D + &#946;D<sup>2</sup>') 
		self.entry_c = gtk.Entry()
		self.entry_c.set_width_chars(5)
		label_c = gtk.Label('c: ')
		self.entry_alpha = gtk.Entry()
		self.entry_alpha.set_width_chars(5)
		label_alpha = gtk.Label()
		label_alpha.set_use_markup(True)
		label_alpha.set_markup('&#945;: ') 
		self.entry_beta = gtk.Entry()
		self.entry_beta.set_width_chars(5)
		label_beta = gtk.Label()
		label_beta.set_use_markup(True)
		label_beta.set_markup('&#946;: ') 
		self.entry_sc = gtk.Entry()
		self.entry_sc.set_width_chars(5)
		label_sc = gtk.Label()
		label_sc.set_use_markup(True)
		label_sc.set_markup('&#963;(c): ') 
		self.entry_salpha = gtk.Entry()
		self.entry_salpha.set_width_chars(5)
		label_salpha = gtk.Label()
		label_salpha.set_use_markup(True)
		label_salpha.set_markup('&#963;(&#945;): ') 
		self.entry_sbeta = gtk.Entry()
		self.entry_sbeta.set_width_chars(5)
		label_sbeta = gtk.Label()
		label_sbeta.set_use_markup(True)
		label_sbeta.set_markup('&#963;(&#946;): ') 
		table_f = gtk.Table(6,3)
		#table_f.attach(label_Y, False, False)
		table_f.attach(label_c,0,1,0,1)
		table_f.attach(self.entry_c,1,2,0,1)
		table_f.attach(label_alpha,0,1,1,2)
		table_f.attach(self.entry_alpha,1,2,1,2)
		table_f.attach(label_beta,0,1,2,3)
		table_f.attach(self.entry_beta,1,2,2,3)
		table_f.attach(label_sc,4,5,0,1)
		table_f.attach(self.entry_sc,5,6,0,1)
		table_f.attach(label_salpha,4,5,1,2)
		table_f.attach(self.entry_salpha,5,6,1,2)
		table_f.attach(label_sbeta,4,5,2,3)
		table_f.attach(self.entry_sbeta,5,6,2,3)
		vruler = gtk.VSeparator()
		table_f.attach(vruler,3,4,0,3,xpadding=10)
		check_function = gtk.CheckButton("Plot function")
		check_points = gtk.CheckButton("Plot data points")
		check_err = gtk.CheckButton("Plot uncertainty band")
		check_ci_curve = gtk.CheckButton("Plot CI95% band (curve)")
		check_ci_points = gtk.CheckButton("Plot CI95% band (points)")
		check_function.set_active(True)
		check_points.set_active(True)
		check_err.set_active(True)
		check_ci_curve.set_active(True)
		check_ci_points.set_active(True)
		vbox_checks = gtk.VBox(False, 5)
		vbox_checks.pack_start(check_function, False, False)
		vbox_checks.pack_start(check_points, False, False)
		vbox_checks.pack_start(check_err, False, False)
		vbox_checks.pack_start(check_ci_curve, False, False)
		vbox_checks.pack_start(check_ci_points, False, False)
		check_function.connect('toggled',self.on_toggled, 'function')
		check_points.connect('toggled',self.on_toggled, 'points')
		check_err.connect('toggled',self.on_toggled, 'err')
		check_ci_curve.connect('toggled',self.on_toggled, 'ci_curve')
		check_ci_points.connect('toggled',self.on_toggled, 'ci_points')
		hbox_buttons = gtk.HBox(True,5)
		button_save_f = gtk.Button("Save Funtion")
		button_load_f = gtk.Button("Load Funtion")
		hbox_buttons.pack_start(button_save_f,True,True)
		hbox_buttons.pack_start(button_load_f,True,True)
		button_save_f.connect('clicked',self.save_function)
		button_load_f.connect('clicked',self.load_function)
		left_box = gtk.VBox(False,5)
		ruler_f1 = gtk.HSeparator()
		ruler_f2 = gtk.HSeparator()
		left_box.pack_start(label_Y, False, False)
		left_box.pack_start(table_f, False, False)
		left_box.pack_start(ruler_f1, False, True, 5)
		left_box.pack_start(vbox_checks, False, False)
		left_box.pack_start(ruler_f2, False, True, 5)
		left_box.pack_start(hbox_buttons, False, True)
		function_box.pack_start(left_box, False, False)
		function_box.pack_start(self.scroll_ftxt, True, True)
		#__________________________________________________________________

		# NOTEBOOK WRAP____________________________________________________
		self.notebook = gtk.Notebook()
		self.notebook.append_page(text_view_box, gtk.Label('Log console'))
		self.notebook.append_page(estimator_box, gtk.Label('Estimator'))
		self.notebook.append_page(function_box, gtk.Label('Calibration function'))
		vbox1.pack_end(self.notebook,True,True)
		#__________________________________________________________________

		# MAT-PLOT-LIB_____________________________________________________
		self.fig = Figure(figsize=(6, 4))		# create fig
		self.canvas = FigureCanvas(self.fig)		# a gtk.DrawingArea
		self.canvas.set_size_request(600,400)		# set min size
		self.markers = ['.',',','+','x','|','_','o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd']
		self.colors = ['black','blue','green','red','cyan','magenta','yellow','purple','white']
		self.pstyle = ['bmh','s','6','red','0.8','black','2','black','0.3','','25','','','20','15','','','20','15']

		self.styledict = {}
		self.styledict["style"]='bmh'
		self.styledict["point_style"]='s'
		self.styledict["point_size"]='6'
		self.styledict["point_color"]='red'
		self.styledict["point_alpha"]='0.8'
		self.styledict["line_color"]='black'
		self.styledict["line_width"]='2'
		self.styledict["band_color"]='black'
		self.styledict["band_alpha"]='0.3'
		self.styledict["title_size"]='25'
		self.styledict["xtitle_size"]='20'
		self.styledict["xlabel_size"]='15'
		self.styledict["ytitle_size"]='20'
		self.styledict["ylabel_size"]='15'

		self.nselec = [1,12,5,3,-1,0,-1,0,-1,-1,-1,-1,-1,-1]
		self.plot_labels = ["Foci per cell vs Dose", "Dose", "Foci per cell", " [Gy]", " []"]
		#print plt.style.available
		self.mode='quadratic'
		self.function = None
		if self.mode=='linear' :
			self.function = self.linear
		elif self.mode=='quadratic' :
			self.function = self.quadratic
		self.fit_toggle='active'
		self.points_toggle=1
		self.function_toggle=1
		self.err_toggle=1
		self.ci_func_toggle=1
		self.ci_points_toggle=1
		self.plotting()					# --- CORE plotting function ---
		self.canvas.mpl_connect('pick_event', self.on_pick)
		toolbar = NavigationToolbar(self.canvas, self)
		toolbarbox = gtk.HBox()
		image = gtk.Image()
		image.set_from_stock(gtk.STOCK_PROPERTIES, gtk.ICON_SIZE_LARGE_TOOLBAR)
		options_button = gtk.Button()
		options_button.add(image)
		options_button.connect('clicked',self.mpl_options)
		image2 = gtk.Image()
		image2.set_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_LARGE_TOOLBAR)
		refresh_button = gtk.Button()
		refresh_button.add(image2)
		refresh_button.connect('clicked',self.on_refresh_clicked)
		toolbarbox.pack_start(toolbar, True, True)
		toolbarbox.pack_end(options_button, False, True)
		toolbarbox.pack_end(refresh_button, False, True)
		vbox1.pack_start(toolbarbox, False, False)
		vbox1.pack_start(self.canvas, True, True)	# into box layout
		#__________________________________________________________________

		
	def plotting(self):
		plt.style.use(self.pstyle[0])

		self.xdata=self.data[0]
		self.ydata=self.data[3]

		self.ax1 = self.fig.add_subplot(111)
		self.ax1.clear()

		if self.points_toggle==1:
			self.ax1.plot(self.xdata,self.ydata, color=self.pstyle[3], label=labels[3], marker=self.pstyle[1], alpha=float(self.pstyle[4]), linestyle='None', markersize=float(self.pstyle[2]), picker=float(self.pstyle[2]))

		self.ax1.set_title(self.plot_labels[0], fontsize=self.pstyle[10])
		self.ax1.set_xlabel(self.plot_labels[1]+self.plot_labels[3], fontsize=int(self.pstyle[13]))
		self.ax1.set_ylabel(self.plot_labels[2]+self.plot_labels[4], fontsize=int(self.pstyle[17]))
		self.ax1.tick_params(axis='x', which='both', labelsize=int(self.pstyle[14]))
		self.ax1.tick_params(axis='y', which='both', labelsize=int(self.pstyle[18]))

		x = np.arange(-0.1, max(20,max(self.xdata))*1.1, 0.05)

		if (self.fit_toggle=='active'):
			self.params, self.rmse, self.p_value, self.std_err, self.dof, self.rss, self.cov_mtx = self.fit_function(self.xdata,self.ydata)
			self.function_changed()

		if self.function_toggle==1:
			y = self.function(x,self.params)
			self.ax1.plot(x,y, color=self.pstyle[5], marker='.', linestyle='None', markersize=float(self.pstyle[6]))

		if self.ci_func_toggle==1 and self.fit_toggle=='active':
			conf = self.confidence(x,self.xdata,len(x),np.mean(self.xdata),self.dof,self.rmse)
			upper =  self.function(x,self.params) + conf
			lower =  self.function(x,self.params) - conf
			self.ax1.fill_between(x, lower, upper, facecolor=self.pstyle[7], alpha=float(self.pstyle[8]))

		if self.ci_points_toggle==1:
			upper =  self.function(x,self.params) + self.confidence_points(x,self.std_err)
			lower =  self.function(x,self.params) - self.confidence_points(x,self.std_err)
			self.ax1.fill_between(x, lower, upper, facecolor='blue', alpha=float(self.pstyle[8]))

		if self.err_toggle==1:
			upper =  self.function(x,self.params) + self.uncertainty(x,self.std_err)
			lower =  self.function(x,self.params) - self.uncertainty(x,self.std_err)
			self.ax1.fill_between(x, lower, upper, facecolor='green', alpha=float(self.pstyle[8]))

		self.canvas.draw()

	def on_refresh_clicked(self,button) :
		self.plotting()

	def on_pick(self,event):
		artist = event.artist
		xmouse, ymouse = event.mouseevent.xdata, event.mouseevent.ydata
		x, y = artist.get_xdata(), artist.get_ydata()
		ind = event.ind
		print 'Artist picked:', event.artist
		print '{} vertices picked'.format(len(ind))
		print 'Pick between vertices {} and {}'.format(min(ind), max(ind))
		print 'x, y of mouse: {:.2f},{:.2f}'.format(xmouse, ymouse)
		print 'Data point:', x[ind[0]], y[ind[0]]
		print
		self.log('Data point:\t  ' + str(x[ind[0]]) + '\t' + str(y[ind[0]]))
		self.treeview.set_cursor(min(ind))
		self.treeview.grab_focus()

	def log(self,txt):
		end_iter = self.text.get_buffer().get_end_iter()
		self.text.get_buffer().insert(end_iter, txt+'\n')
		adj = self.scroll_text.get_vadjustment()
		adj.set_value( adj.upper - adj.page_size )
		self.notebook.set_current_page(0)

	def loges(self,txt):
		end_iter = self.estxt.get_buffer().get_end_iter()
		self.estxt.get_buffer().insert(end_iter, txt+'\n')
		adj = self.scroll_estxt.get_vadjustment()
		adj.set_value( adj.upper - adj.page_size )
		self.notebook.set_current_page(1)

	def logf(self,txt):
		end_iter = self.ftxt.get_buffer().get_end_iter()
		self.ftxt.get_buffer().insert(end_iter, txt+'\n')
		adj = self.scroll_ftxt.get_vadjustment()
		adj.set_value( adj.upper - adj.page_size )
		self.notebook.set_current_page(2)

	def add_columns(self):
		for i in range(self.numCols):
			renderer = gtk.CellRendererText()
			renderer.props.wrap_width = 100

			if i==0 or i==1 or i==2:
				renderer.set_property('editable', True)
				renderer.connect('edited',self.edited_cb, i)
			else :
				renderer.set_property('editable', False)
			column = gtk.TreeViewColumn(labels[i], renderer, text=i)
			column.set_resizable(True)
			column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
			column.set_min_width(50)
			column.set_fixed_width(100)
			column.set_expand(False)
			self.treeview.append_column(column)


	def edited_cb(self, cell, path, new_content, user_data):
		column = user_data
		liststore=self.model
		print 'edited_cb', self.model
		print 'edited_cb', len(self.model)
		print path, int(path)
		if isfloat(new_content) and float(new_content)>=0.0 :
			liststore[path][column] = float(new_content)
			self.data[int(column)][int(path)] = float(new_content)
			if liststore[path][1] != 0:
				liststore[path][3] = liststore[path][2] / liststore[path][1]
				self.data[3][int(path)] = self.data[2][int(path)] / self.data[1][int(path)]
			else:
				liststore[path][3]=0.0
				self.data[3][int(path)]=0.0
			print "data[", column, "][", path, "]  = ", self.data[int(column)][int(path)]
			self.plotting()
		else :
			self.log("___Wrong input format!___")

	def add_rows(self,button,n):
		self.log('n of rows to add: ' + str(n))
		print 'add_rows', self.model
		print 'add_rows', len(self.model)
		for i in range(0,n) :
			self.model.append([0,0,0,0,0])
			self.data = np.insert( self.data, len(self.xdata), values=0, axis=1 )
		adj = self.sw.get_vadjustment()
		adj.set_value( adj.upper - adj.page_size )
		print 'add_rows', self.model
		print 'add_rows', len(self.model)

	def create_model(self):
		types = [float]*self.numCols
		store = None
		store = gtk.ListStore(*types)

		temp=zip(*self.data)
		for row in temp:
			store.append(row)
		return store

	def linear(self, x, params):
		return params[0]*x + params[1]

	def quadratic(self, x, params):
		return params[0]*x*x + params[1]*x + params[2]

	def fit_linear(self, x, a, b):
		return a*x + b

	def fit_quadratic(self, x, a, b, c):
		return a*x*x + b*x + c

	def confidence(self, x, xdata, n, mean_x, dof, RMSE):
		alpha=0.05
		t = stats.t.isf(alpha/2., df=dof)
		#conf = t * np.sqrt((RSS/(n-2))*(1.0/n + ( (x-mean_x)**2 / ((np.sum(x**2)) - n*(mean_x**2)))))
		Sxx = np.sum(xdata**2) - np.sum(xdata)**2/n
		se_a = RMSE / np.sqrt(Sxx)
		se_b = RMSE * np.sqrt(np.sum(xdata**2)/(n*Sxx))
		
		conf = t * RMSE * np.sqrt(  1./n + (x-mean_x)**2/Sxx)
		#pred = t * RMSE * np.sqrt(1+1./n + (x-mean_x)**2/Sxx)
		return conf

	def uncertainty(self, x, std_err) :
		return std_err[2] + x*std_err[1] + x*x*std_err[0]

	def confidence_points(self, x, std_err) :
		return 1.96*self.uncertainty(x, std_err)

	def fit_function(self,x,y):
		# fit the model
		if self.mode=='linear' :
			popt, pcov = curve_fit(self.fit_linear, x, y)
		elif self.mode=='quadratic' :
			popt, pcov = curve_fit(self.fit_quadratic, x, y)
		# parameters standard error
		std_err = np.sqrt(np.diag(pcov))
		# degrees of freedom
		ndata = len(y)
		npar = len(popt)
		dof = max(0, ndata - npar)
		# root mean squared error
		residuals = y - self.function(x,popt)
		RSS = sum(residuals**2)
		MSE = RSS/dof
		RMSE = np.sqrt(MSE)
		# t-value
		t_value = popt/std_err
		# p-value P(>|t|)
		p_value=(1 - stats.t.cdf( abs(t_value), dof))*2

		return popt, RMSE, p_value, std_err, dof, RSS, pcov

	def function_changed(self):
		if self.mode=='quadratic' :
			self.entry_c.set_text('%.3f' % self.params[2])
			self.entry_alpha.set_text('%.3f' % self.params[1])
			self.entry_beta.set_text('%.3f' % self.params[0])
			self.entry_sc.set_text('%.3f' % self.std_err[2])
			self.entry_salpha.set_text('%.3f' % self.std_err[1])
			self.entry_sbeta.set_text('%.3f' % self.std_err[0])

			self.logf("params:\t[beta\talpha\tc ]")
			self.logf("values\t\t" + str(self.params))
			self.logf("std_err\t" + str(self.std_err))
			self.logf("p-value\t" + str(self.p_value))
			self.logf("RSS\t" + str(self.rss))
			self.logf("RMSE\t" + str(self.rmse))
			self.logf("---------------------------------------------------------------------------")


	def on_load_file(self, button) :
		file_chooser = gtk.FileChooserDialog("Open...", self, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
		response = file_chooser.run()
		path=''
		if response == gtk.RESPONSE_OK :
			path = file_chooser.get_filename()
			self.log('Loaded data file:   ' + path)
			if ".csv" in path:
				read_data_csv(path)
				self.data=data
				self.model = self.create_model()
				self.treeview.set_model(self.model)
				self.fit_toggle = 'active'
				self.points_toggle=True
				self.plotting()
			else : 
				self.log("___Wrong file format!___")
			file_chooser.destroy()

	def on_save_file(self, button) :
		file_chooser = gtk.FileChooserDialog("Open...", self, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
		response = file_chooser.run()
		path=''
		if response == gtk.RESPONSE_OK :
			path = file_chooser.get_filename()
			self.log('Data saved in file:   ' + path)
			if ".csv" not in path:
				path = path + '.csv'
			ofile = open(path,"wb")
			writer = csv.writer(ofile, delimiter=',')
			writer.writerow(labels)
			for row in zip(*self.data):
				print row
				writer.writerow(row)
			ofile.close()
			file_chooser.destroy()
		else :
			file_chooser.destroy()

	def y_estimate(self, button, entry):
		if not isfloat(entry.get_text()):
			self.loges("___Not a number!___")
			return
		Y = float(entry.get_text())
		plist = self.get_fit_params()
		u = uncer.UCER(Y=Y,par_list=plist)
		D = u.D
		if self.method=="Method A":
			DL, DU = u.method_a()
		elif self.method=="Method B":
			DL, DU = u.method_b()
		elif self.method=="Method C-original":
			DL, DU = u.method_c1()
		elif self.method=="Method C-simplified":
			DL, DU = u.method_c2()

		xlab=self.xvar
		ylab=self.yvar
		self.loges( xlab + " estimation for   " + ylab + " = " + str(Y) + " using " + self.method + ":")
		self.loges( "D = " + str(D) + ";   DL = " + str(DL) + ";   DU = " + str(DU))
		self.loges("-----------------------------------------------------------------")

		self.ax1.axhline(y=Y,linewidth=1,linestyle='-',color='red')
		self.ax1.axvline(x=D,linewidth=1,linestyle='-',color='blue')
		self.ax1.axvline(x=DL,linewidth=1,linestyle='--',color='green')
		self.ax1.axvline(x=DU,linewidth=1,linestyle='--',color='green')
		self.canvas.draw()

	def mpl_options(self,button) :
		dialog = gtk.Dialog("My Dialog",self,0,(gtk.STOCK_OK, gtk.RESPONSE_OK))
		box = dialog.get_content_area()
		table = gtk.Table(2,18)
		table.set_row_spacings(5)
		table.set_col_spacings(5)
		l=[]
		l.append(gtk.Label("Canvas Style"))
		l.append(gtk.Label("Marker Style"))
		l.append(gtk.Label("Marker Size"))
		l.append(gtk.Label("Marker Color"))
		l.append(gtk.Label("Marker Alpha"))
		l.append(gtk.Label("Line Color"))
		l.append(gtk.Label("Line Width"))
		l.append(gtk.Label("CI Band Color"))
		l.append(gtk.Label("CI Band Alpha"))
		l.append(gtk.Label("Title"))
		l.append(gtk.Label("Title size"))
		l.append(gtk.Label("X-axis title"))
		l.append(gtk.Label("X-axis unit"))
		l.append(gtk.Label("X-axis title size"))
		l.append(gtk.Label("X-axis labels size"))
		l.append(gtk.Label("Y-axis title"))
		l.append(gtk.Label("Y-axis unit"))
		l.append(gtk.Label("Y-axis title size"))
		l.append(gtk.Label("Y-axis labels size"))
		hbox=[]
		hlines=[]
		for i in range(0,len(l)) :
			l[i].set_alignment(xalign=0,yalign=0.5) 
			hbox.append(gtk.HBox(False,5))
			hlines.append(gtk.HSeparator())
			table.attach(l[i],0,1,2*i,2*i+1)
			table.attach(hbox[i],1,2,2*i,2*i+1)
			table.attach(hlines[i],0,2,2*i+1,2*i+2)
		
		combo_cs = self.create_combobox(plt.style.available,hbox,0)
		combo_mst = self.create_combobox(self.markers,hbox,1)
		spin_msz = self.create_spinbutton(hbox,float(self.pstyle[2]), 1.0,20.0,1.0,2, 2)
		combo_mc = self.create_combobox(self.colors,hbox,3)
		spin_ma = self.create_spinbutton(hbox,float(self.pstyle[4]), 0.0,1.0,0.05,2, 4)
		combo_lc = self.create_combobox(self.colors,hbox,5)
		spin_lw = self.create_spinbutton(hbox,float(self.pstyle[6]), 0.0,10.0,0.5,2, 6)
		combo_bc = self.create_combobox(self.colors,hbox,7)
		spin_ba = self.create_spinbutton(hbox,float(self.pstyle[8]), 0.0,1.0,0.05,2, 8)

		entry_title = self.create_entry(hbox,0, 9)
		entry_xaxis = self.create_entry(hbox,1, 11)
		entry_xunit = self.create_entry(hbox,3, 12)
		entry_yaxis = self.create_entry(hbox,2, 15)
		entry_yunit = self.create_entry(hbox,4, 16)

		spin_title_size = self.create_spinbutton(hbox,float(self.pstyle[10]), 10.0,40.0,1.0,1 , 10)
		spin_xtile_size = self.create_spinbutton(hbox,float(self.pstyle[13]), 10.0,40.0,1.0,1 , 13)
		spin_xlabels_size = self.create_spinbutton(hbox,float(self.pstyle[14]), 10.0,40.0,1.0,1 , 14)
		spin_ytile_size = self.create_spinbutton(hbox,float(self.pstyle[17]), 10.0,40.0,1.0,1 , 17)
		spin_ylabels_size = self.create_spinbutton(hbox,float(self.pstyle[18]), 10.0,40.0,1.0,1 , 18)

		box.add(table)
		dialog.show_all()
		response = dialog.run()
		if response == gtk.RESPONSE_OK :
			dialog.destroy()
		else :
			dialog.destroy()

	def create_combobox(self,slist,whereto,n) :
		combo = gtk.combo_box_new_text()
		whereto[n].pack_start(combo)
		for style in slist :
			combo.append_text(str(style))
		combo.set_active(self.nselec[n])
		combo.connect('changed', self.on_combo_changed, n)

	def create_spinbutton(self,whereto,val,mini,maxi,step,digits,n) :
		adj = gtk.Adjustment(val,mini,maxi,step,0.5,0.0)
		spin = gtk.SpinButton(adj,step,digits)
		whereto[n].pack_start(spin)
		spin.connect('changed',self.on_spin_changed,n)

	def create_entry(self,whereto,m,n) :
		entry_title = gtk.Entry()
		entry_title.set_text(self.plot_labels[m])
		whereto[n].pack_start(entry_title)
		entry_title.connect("activate",self.on_entry_changed,m)

	def on_combo_changed(self,cb,n):
		model = cb.get_model()
		index = cb.get_active()
		cb.set_active(index)
		self.pstyle[n] = model[index][0]
		self.nselec[n]=index
		self.plotting()

	def on_spin_changed(self,spin,n) :
		self.pstyle[n] = spin.get_value()
		self.plotting()

	def on_entry_changed(self,entry,n) :
		self.plot_labels[n] = entry.get_text()
		self.plotting()

	def on_toggled(self,button,s) :
		if(s=='ci_points'): self.ci_points_toggle*=-1
		elif(s=='ci_curve'): self.ci_func_toggle*=-1
		elif(s=='function'): self.function_toggle*=-1
		elif(s=='points'): self.points_toggle*=-1
		elif(s=='err'): self.err_toggle*=-1
		self.plotting()

	def save_function(self,button) : 

		file_chooser = gtk.FileChooserDialog("Open...", self, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
		response = file_chooser.run()
		path=''
		if response == gtk.RESPONSE_OK :
			path = file_chooser.get_filename()
			self.logf('Curve saved in file:   ' + path)
			self.logf("---------------------------------------------------------------------------")
			if ".csv" not in path:
				path = path + '.csv'
			file_chooser.destroy()

			ofile = open(path,"wb")
			writer = csv.writer(ofile, delimiter=',')
			writer.writerow(self.params)
			writer.writerow(self.std_err)
			writer.writerow(self.p_value)
			writer.writerow(self.cov_mtx[0])
			writer.writerow(self.cov_mtx[1])
			writer.writerow(self.cov_mtx[2])
			writer.writerow((self.rss, self.rmse, 0.0))
			ofile.close()
		else :
			file_chooser.destroy()

	def get_fit_params(self):
		l=[self.params,self.std_err,self.p_value,self.cov_mtx[0],self.cov_mtx[1],self.cov_mtx[2],[self.rss,self.rmse,0.0]]
		return l

	def load_function(self,button) : 
		file_chooser = gtk.FileChooserDialog("Open...", self, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
		response = file_chooser.run()
		path=''
		if response == gtk.RESPONSE_OK :
			path = file_chooser.get_filename()
			self.logf('Loaded curve from file:   ' + path)
			self.logf("---------------------------------------------------------------------------")
			f = open(path, 'rt')
			try:
				reader = csv.reader(f)
				l=list(reader)
				print l
				self.params=[float(i) for i in l[0]]
				self.std_err=[float(i) for i in l[1]]
				self.p_value=[float(i) for i in l[2]]
				self.cov_mtx=[[float(i) for i in l[3]],[float(i) for i in l[4]],[float(i) for i in l[5]]]
				self.rss=float(l[6][0])
				self.rmse=float(l[6][1])
				self.function_changed()
				self.fit_toggle='inactive'
				self.points_toggle=False
				read_data_csv('zeros.csv')
				self.data=data
				self.model = self.create_model()
				self.treeview.set_model(self.model)
				self.plotting()
			finally:
				f.close()
			#self.plotting()
			file_chooser.destroy()
		else : 
			file_chooser.destroy()

	def on_method_changed(self,cb):
		model = cb.get_model()
		index = cb.get_active()
		cb.set_active(index)
		self.method = model[index][0]
    def __init__(self, cube, parent_window):
        """
        A Dendrogram Plot Widget. Designed as a companion to an 
        astrocube.cubeview.CubeViewWidget which should be passed as cube_view
        """
        gtk.VBox.__init__(self, False)

        # Main data structures:         
        self.cube = cube # The cube that this widget's dendrogram represents
        self._data = cube.data # Save a reference to the cube's original data, as we may replace it...
        self.dendrogram = None # The Dendrogram for the cube. To be built later

        # The plot:
        self.fig = matplotlib.figure.Figure()
        self.axes = self.fig.add_subplot(111)
        self.dendro_plot = None # Gets set to a DendrogramPlot object
        self.highlighter_clicked = None # a Highlighter object to color the clicked item
        self.highlighter_hover = None # a Highlighter object to color an item on mouseover
        
        # UI structure:
        canvas = FigureCanvasGTKAgg(self.fig)  # a gtk.DrawingArea
        self.pack_start(canvas)
        self.pack_start(gtk.HSeparator(), False,False)
        
        # # The matplotlib plot toolbar:
        self._plot_toolbar = self._NavigationToolbar(self.cube, canvas, parent_window) # parent_window is needed for the "Save image..." file chooser dialog
        self._plot_toolbar.remove(self._plot_toolbar.get_nth_item(6)) # Remove the "Configure subplots" button which causes rendering issues if used
        self.pack_start(self._plot_toolbar, False, False)
        
        self.pack_start(gtk.HSeparator(), False,False)
        
        # # the dendrogram parameters toolbar:
        self._dendro_toolbar = gtk.HBox()
        
        # # # Minimum flux:
        self._dendro_toolbar.pack_start(gtk.Label("Min flux: "))
        self._min_flux_widget = gtk.SpinButton(digits=1)
        self._min_flux_widget.set_range(np.nanmin(self._data)-0.1,np.nanmax(self._data))
        self._min_flux_widget.set_increments(0.1,1)
        self._min_flux_widget.set_value(np.nanmin(self._data))
        self._dendro_toolbar.pack_start(self._min_flux_widget)
        
        # # # Minimum npix:
        self._dendro_toolbar.pack_start(gtk.Label("Min # pix: "))
        self._min_npix_widget = gtk.SpinButton()
        self._min_npix_widget.set_range(0,999)
        self._min_npix_widget.set_increments(1,5)
        self._min_npix_widget.set_value(0)
        self._dendro_toolbar.pack_start(self._min_npix_widget)
        
        # # # Minimum delta:
        self._dendro_toolbar.pack_start(gtk.Label("Min delta: "))
        self._min_delta_widget = gtk.SpinButton(digits=2)
        self._min_delta_widget.set_range(0,np.nanmax(self._data))
        self._min_delta_widget.set_increments(0.05,0.3)
        self._min_delta_widget.set_value(0)
        self._dendro_toolbar.pack_start(self._min_delta_widget)
        
        # # # Compute button:
        self._compute_button = gtk.Button("Compute")
        self._compute_button.connect("button-press-event", self._compute_btn_clicked)
        self._dendro_toolbar.pack_start(self._compute_button)
        
        # # # Plot style:
        self._dendro_toolbar.pack_start(gtk.Label("Plot style: "))
        self._plot_style_widget = gtk.combo_box_new_text()
        plot_styles = ['rfmax', 'x_mean', 'y_mean', 'z_mean']
        for s in plot_styles:
            self._plot_style_widget.append_text(s)
        self._plot_style_widget.set_active(0)
        self._plot_style_widget.connect("changed", self.setup_plot)
        self._dendro_toolbar.pack_start(self._plot_style_widget)
        
        self.pack_start(self._dendro_toolbar, False, False)
        
        
        # Set up event handling:
        self._is_mouse_down = False # is the mouse button currently pressed?
        self._redraw_all = False # Set this to True to trigger a complete re-draw of the canvas when idle
        self._redraw_highlights = False # Set this True to  re-draw only the highlighted (clicked or hovered) leaves
        canvas.mpl_connect('button_press_event', self._figure_mousedown)
        canvas.mpl_connect('button_release_event', self._figure_mouseup)
        canvas.mpl_connect('motion_notify_event', self._figure_mousemoved)
        canvas.mpl_connect('resize_event', self._figure_resized)
        gtk.idle_add(DendrogramViewWidget._check_redraw, self) # we only want to re re-drawing when the GUI is idle, for maximum interactivity
        
        self._click_notify = []
        self._compute_notify = []
Example #28
0
class GUI:
    #
    # Main Window
    #

    # menu item activation signals

    def on_imagemenuitem_file_save_as_activate(self, widget):
        self.fcdialog_save.set_current_folder(self.folder)
        self.fcdialog_save.show()

    def on_imagemenuitem_export_activate(self, widget):
        self.fcdialog_export.set_current_folder(self.folder)
        self.fcdialog_export.show()

    def on_imagemenuitem_quit_activate(self, widget):
        self._quit()

    # View menu

    def on_checkmenuitem_function_intersections_toggled(self,
                                                        widget):
        self.fg.point_type_enabled[1] = \
            self.checkmenuitem_function_intersections.\
            get_active()
        self.fg.update_xylimits()
        self.graph_update()

    def on_checkmenuitem_x_intercepts_toggled(self, widget):
        self.fg.point_type_enabled[2] = \
            self.checkmenuitem_x_intercepts.get_active()
        self.fg.update_xylimits()
        self.graph_update()

    def on_checkmenuitem_y_intercepts_toggled(self, widget):
        self.fg.point_type_enabled[3] = \
            self.checkmenuitem_y_intercepts.get_active()
        self.fg.update_xylimits()
        self.graph_update()

    def on_checkmenuitem_extrema_toggled(self, widget):
        self.fg.point_type_enabled[4] = \
            self.checkmenuitem_extrema.get_active()
        self.fg.update_xylimits()
        self.graph_update()

    def on_checkmenuitem_inflection_toggled(self, widget):
        self.fg.point_type_enabled[5] = \
            self.checkmenuitem_inflection.get_active()
        self.fg.update_xylimits()
        self.graph_update()

    def on_checkmenuitem_vertical_asym_toggled(self, widget):
        self.fg.point_type_enabled[6] = \
            self.checkmenuitem_vertical_asym.get_active()
        self.fg.update_xylimits()
        self.graph_update()

    def on_checkmenuitem_horizontal_asym_toggled(self, widget):
        self.fg.point_type_enabled[7] = \
            self.checkmenuitem_horizontal_asym.get_active()
        self.fg.update_xylimits()
        self.graph_update()

    def on_checkmenuitem_slope45_toggled(self, widget):
        self.fg.point_type_enabled[8] = \
            self.checkmenuitem_slope45.get_active()
        self.fg.update_xylimits()
        self.graph_update()

    def on_checkmenuitem_outliers_toggled(self, widget):
        self.fg.outliers = self.checkmenuitem_outliers.get_active()
        self.fg.update_xylimits()
        self.graph_update()

    def on_checkmenuitem_show_poi_toggled(self, widget):
        self.fg.show_poi = self.checkmenuitem_show_poi.get_active()
        self.graph_update()

    def on_checkmenuitem_grouped_toggled(self, widget):
        self.fg.grouped = self.checkmenuitem_grouped.get_active()
        self.graph_update()

    def on_checkmenuitem_legend_toggled(self, widget):
        self.fg.show_legend = self.checkmenuitem_legend.get_active()
        self.graph_update()

    def on_checkmenuitem_logscale_toggled(self, widget):
        self.fg.logscale = self.checkmenuitem_logscale.get_active()
        self.graph_update()

    def on_menuitem_legend_lower_right_toggled(self, widget):
        if widget.active:
            self.fg.legend_location = 4
            if self.fg.show_legend:
                self.graph_update()

    def on_menuitem_legend_upper_right_toggled(self, widget):
        if widget.active:
            self.fg.legend_location = 1
            if self.fg.show_legend:
                self.graph_update()

    def on_menuitem_legend_lower_left_toggled(self, widget):
        if widget.active:
            self.fg.legend_location = 3
            if self.fg.show_legend:
                self.graph_update()

    def on_menuitem_legend_upper_left_toggled(self, widget):
        if widget.active:
            self.fg.legend_location = 2
            if self.fg.show_legend:
                self.graph_update()

    # help menu
    def on_imagemenuitem_about_activate(self, widget):
        self.aboutdialog.show()

    # toolbar button activation signals
    def on_btn_new_clicked(self, widget):
        if self.changed:
            self.dialog_confirm_new.show()
        else:
            self.changed = False
            self.filename = None
            self.export_filename = None
            self.fg.new()
            self._restore_state()
            self.update_function_list()
            self.graph_update()

    def on_btn_open_clicked(self, widget):
        if self.changed:
            self.dialog_confirm_open.show()
        else:
            self.fcdialog_open.set_current_folder(self.folder)
            self.fcdialog_open.show()

    def on_btn_save_clicked(self, widget):
        if self.filename is None:
            self.fcdialog_save.set_current_folder(self.folder)
            self.fcdialog_save.show()
        else:
            self._save()
            self.changed = False

    def on_btn_add_clicked(self, widget):
        self.changed = True
        self.entry_function.set_text('')
        self.dialog_add_function.show()
        self.entry_function.grab_focus()

    def on_btn_remove_clicked(self, widget):
        selected_line = self.treeview_functions.get_selection()
        self.ls_functions, iter = selected_line.get_selected()
        if iter is not None:
            index = self.ls_functions.get_value(iter, 3)
            self.fg.functions.pop(index)
            self.fg.calc_intersections()
            self.update_function_list()
            self.graph_update()
            self.changed = True

    def on_btn_zoom_x_in_clicked(self, widget):
        self.changed = True
        self.fg.zoom_x_in()
        self.graph_update()

    def on_btn_zoom_x_out_clicked(self, widget):
        self.changed = True
        self.fg.zoom_x_out()
        self.graph_update()

    def on_btn_zoom_y_in_clicked(self, widget):
        self.changed = True
        self.fg.zoom_y_in()
        self.graph_update()

    def on_btn_zoom_y_out_clicked(self, widget):
        self.changed = True
        self.fg.zoom_y_out()
        self.graph_update()

    def on_btn_zoomin_clicked(self, widget):
        self.changed = True
        self.fg.zoom_in()
        self.graph_update()

    def on_btn_zoomout_clicked(self, widget):
        self.changed = True
        self.fg.zoom_out()
        self.graph_update()

    def on_btn_auto_toggled(self, widget):
        self.changed = True
        self.fg.auto = self.btn_auto.get_active()
        if self.fg.auto:
            self.fg.zoom_default()
            self.graph_update()

    # toggle visibility in function list
    def on_cr_toggle_visible_toggled(self, widget, event):
        self.changed = True
        i = int(event)
        visible = self.fg.functions[i].visible
        if visible:
            self.fg.functions[i].visible = False
        else:
            self.fg.functions[i].visible = True
        self.update_function_list()
        self.graph_update()

    # about dialog close
    def on_aboutdialog_response(self, widget, event):
        self.aboutdialog.hide()

    def on_aboutdialog_delete_event(self, widget, event):
        self.aboutdialog.hide()
        return True

    # zoom in/out with the mouse wheel
    def wheel_zoom(self, event):
        self.changed = True
        if event.button == 'down':
            self.fg.zoom_out()
        elif event.button == 'up':
            self.fg.zoom_in()
        self.graph_update()
    # pan handling
    # when pressing down the mouse button on the graph, record
    # the current mouse coordinates

    def pan_press(self, event):
        self.changed = True
        if event.inaxes != self.ax:
            return
        self.mousebutton_press = event.xdata, event.ydata

    # when releasing the mouse button, stop recording the
    # mouse coordinates and redraw
    def pan_release(self, event):
        self.mousebutton_press = None
        self.graph_update()

    # when moving the mouse, while holding down the mouse button (any
    # mouse button - that makes nice middle-click pan and zoom
    # possible) calculate how much the mouse has travelled and adjust
    # the graph accordingly
    def pan_motion(self, event):
        if self.mousebutton_press is None:
            return
        if event.inaxes != self.ax:
            return
        self.fg.auto = False
        old_x, old_y = self.mousebutton_press
        dx = event.xdata - old_x
        dy = event.ydata - old_y
        self.fg.x_min -= dx
        self.fg.x_max -= dx
        self.fg.y_min -= dy
        self.fg.y_max -= dy
        self.fg.update_graph_points()
        self.graph_update()

    # update the graph
    def graph_update(self):
        self.ax.clear()

        if self.fg.auto:
            self.fg.update_xylimits()
        x_min, x_max = self.fg.x_min, self.fg.x_max
        y_min, y_max = self.fg.y_min, self.fg.y_max

        self.ax.grid(True)
        if self.fg.logscale:
            self.ax.set_xscale('log')
            self.ax.set_yscale('log')
        else:
            self.ax.set_xscale('linear')
            self.ax.set_yscale('linear')
            # put axes in center instead of the sides
            # when axes are off screen, put them on the edges
            if x_min < 0 and x_max > 0:
                self.ax.spines['left'].set_color('black')
                self.ax.spines['left'].set_position(('data', 0))
                self.ax.spines['left'].set_smart_bounds(False)
                self.ax.spines['right'].set_color('none')
                self.ax.yaxis.set_ticks_position('left')
            elif x_min >= 0:
                self.ax.spines['left'].set_color('black')
                self.ax.spines['left'].set_position(('data', x_min))
                self.ax.spines['left'].set_smart_bounds(False)
                self.ax.spines['right'].set_color('none')
                self.ax.yaxis.set_ticks_position('left')
            else:
                self.ax.spines['right'].set_color('black')
                self.ax.spines['right'].set_position(('data', x_max))
                self.ax.spines['right'].set_smart_bounds(False)
                self.ax.spines['left'].set_color('none')
                self.ax.yaxis.set_ticks_position('right')
            if y_min < 0 and y_max > 0:
                self.ax.spines['bottom'].set_color('black')
                self.ax.spines['bottom'].set_position(('data', 0))
                self.ax.spines['bottom'].set_smart_bounds(False)
                self.ax.spines['top'].set_color('none')
                self.ax.xaxis.set_ticks_position('bottom')
            elif y_min >= 0:
                self.ax.spines['bottom'].set_color('black')
                self.ax.spines['bottom'].set_position(('data',
                                                       y_min))
                self.ax.spines['bottom'].set_smart_bounds(False)
                self.ax.spines['top'].set_color('none')
                self.ax.xaxis.set_ticks_position('bottom')
            else:
                self.ax.spines['top'].set_color('black')
                self.ax.spines['top'].set_position(('data', y_max))
                self.ax.spines['top'].set_smart_bounds(False)
                self.ax.spines['bottom'].set_color('none')
                self.ax.xaxis.set_ticks_position('top')

            # we don't need the origin annotated in both axes
            if x_min < 0 and x_max > 0 and y_min < 0 and y_max > 0:
                formatter = CenteredFormatter(useMathText=True)
                formatter.center = 0
                self.ax.xaxis.set_major_formatter(formatter)
                self.ax.yaxis.set_major_formatter(formatter)
                self.ax.annotate('(0,0)', (0, 0), xytext=(-4, -4),
                                 textcoords='offset points', ha='right',
                                 va='top')
        self.ax.set_xlim(float(x_min), float(x_max))
        self.ax.set_ylim(float(y_min), float(y_max))
        legend = []

        # draw the functions
        for f in self.fg.functions:
            x, y = f.graph_points
            if f.visible:
                color = self.color[len(legend) % len(self.color)]
                self.ax.plot(x, y, linewidth=2, color=color)
                # add function to legend
                legend.append(f.mathtex_expr)
        # create a list of ungrouped POI
        color_index = 0
        ungrouped_poi = []
        for f in self.fg.functions:
            if f.visible:
                color = self.color[color_index % len(self.color)]
                # function POI
                for p in f.poi:
                    if self.fg.point_type_enabled[p.point_type]:
                        p.color = color
                        ungrouped_poi.append(p)
                color_index += 1
        # add function intercepts POI to ungrouped list
        for p in self.fg.poi:
            if self.fg.point_type_enabled[p.point_type]:
                p.color = 'black'
                ungrouped_poi.append(p)
        # group POI
        if self.fg.show_poi:
            if self.fg.grouped:
                grouped_poi = self.fg.grouped_poi(ungrouped_poi)
            else:
                grouped_poi = ungrouped_poi
        # draw POI
            for p in grouped_poi:
                if p.point_type > 1 and p.point_type < 9:
                    if p.function.visible:
                        # don't plot vertical or horizontal
                        # asymptotes here. We'll do it later
                        if p.point_type < 6 or p.point_type > 7:
                            if self.fg.point_type_enabled\
                                    [p.point_type]:
                                self.ax.scatter([p.x], [p.y], s=80,
                                                c=p.color, linewidths=0)
                        # plot asymptotes now
                        elif p.point_type == 6:
                            if self.fg.point_type_enabled\
                                    [p.point_type]:
                                # vertical asymptotes are plotted
                                # as 'x'
                                self.ax.scatter([p.x], [0], s=80,
                                                marker='x', c=p.color,
                                                linewidths=2)
                        elif p.point_type == 7:
                            if self.fg.point_type_enabled\
                                    [p.point_type]:
                                # horizontal asymptotes are plotted
                                # as '+'
                                self.ax.scatter([0], [p.y], s=80,
                                                marker='+', c=p.color,
                                                linewidths=2)
                elif p.point_type == 1:
                    if p.function[0].visible \
                            and p.function[1].visible \
                            and self.fg.point_type_enabled[p.point_type]:
                        # plot function intercepts
                        self.ax.scatter([p.x], [p.y], s=80,
                                        alpha=0.5,
                                        c='black', linewidths=0)
                elif p.point_type == 9:
                    if self.fg.point_type_enabled[p.point_type]:
                        # plot grouped poi
                        self.ax.scatter([p.x], [p.y], s=p.size * 80,
                                        alpha=0.8,
                                        c='orange', linewidths=0)
        # show legend
        if self.fg.show_legend:
            if self.fg.legend_location == 1:
                anchor = (1, 1)
            elif self.fg.legend_location == 2:
                anchor = (0, 1)
            elif self.fg.legend_location == 3:
                anchor = (0, 0)
            else:
                anchor = (1, 0)
            self.ax.legend(legend, loc=self.fg.legend_location,
                           bbox_to_anchor=anchor, fontsize=18)
        # show canvas
        self.ax.figure.canvas.draw()
        # check/uncheck the toolbutton for auto-adjustment
        self.btn_auto.set_active(self.fg.auto)

    def update_function_list(self):
        self.ls_functions.clear()
        visible_functions = 0
        index = 0
        for f in self.fg.functions:
            if f.visible:
                color = self.color[visible_functions %
                                   len(self.color)]
                visible_functions += 1
            else:
                color = '#999999'
            self.ls_functions.append([f.visible, f.expr.lower() + '',
                                      gtk.gdk.Color(color), index])
            index += 1

    def gtk_main_quit(self, widget, data=None):
        self._quit()

    def _quit(self):
        if self.changed:
            self.dialog_confirm_quit.show()
        else:
            gtk.main_quit()

    #
    # Add function dialog
    #
    def on_dialog_add_function_delete_event(self, widget, event):
        self.dialog_add_function.hide()
        return True

    def _entry_function_append_text(self, text):
        t = self.entry_function.get_text()
        t = t + text
        l = len(t)
        self.entry_function.set_text(t)
        self.entry_function.grab_focus()
        self.entry_function.set_position(l)

    def on_button_1_clicked(self, widget):
        self._entry_function_append_text('1')

    def on_button_2_clicked(self, widget):
        self._entry_function_append_text('2')

    def on_button_3_clicked(self, widget):
        self._entry_function_append_text('3')

    def on_button_4_clicked(self, widget):
        self._entry_function_append_text('4')

    def on_button_5_clicked(self, widget):
        self._entry_function_append_text('5')

    def on_button_6_clicked(self, widget):
        self._entry_function_append_text('6')

    def on_button_7_clicked(self, widget):
        self._entry_function_append_text('7')

    def on_button_8_clicked(self, widget):
        self._entry_function_append_text('8')

    def on_button_9_clicked(self, widget):
        self._entry_function_append_text('9')

    def on_button_0_clicked(self, widget):
        self._entry_function_append_text('0')

    def on_button_left_paren_clicked(self, widget):
        self._entry_function_append_text('(')

    def on_button_right_paren_clicked(self, widget):
        self._entry_function_append_text(')')

    def on_button_x_clicked(self, widget):
        self._entry_function_append_text('x')

    def on_button_plus_clicked(self, widget):
        self._entry_function_append_text('+')

    def on_button_minus_clicked(self, widget):
        self._entry_function_append_text('-')

    def on_button_times_clicked(self, widget):
        self._entry_function_append_text('*')

    def on_button_div_clicked(self, widget):
        self._entry_function_append_text('/')

    def on_button_sin_clicked(self, widget):
        self._entry_function_append_text('sin(x)')

    def on_button_cos_clicked(self, widget):
        self._entry_function_append_text('cos(x)')

    def on_button_tan_clicked(self, widget):
        self._entry_function_append_text('tan(x)')

    def on_button_cot_clicked(self, widget):
        self._entry_function_append_text('cot(x)')

    def on_button_sec_clicked(self, widget):
        self._entry_function_append_text('sec(x)')

    def on_button_csc_clicked(self, widget):
        self._entry_function_append_text('csc(x)')

    def on_button_log_clicked(self, widget):
        self._entry_function_append_text('log(x)')

    def on_button_ln_clicked(self, widget):
        self._entry_function_append_text('ln(x)')

    def on_button_10p_x_clicked(self, widget):
        self._entry_function_append_text('10^x')

    def on_button_ep_x_clicked(self, widget):
        self._entry_function_append_text('exp(x)')

    def on_button_sqrt_clicked(self, widget):
        self._entry_function_append_text('sqrt(x)')

    def on_button_abs_clicked(self, widget):
        self._entry_function_append_text('abs(x)')

    def on_button_power2_clicked(self, widget):
        self._entry_function_append_text('x^2')

    def on_button_power3_clicked(self, widget):
        self._entry_function_append_text('x^3')

    def on_button_pi_clicked(self, widget):
        self._entry_function_append_text('pi')

    def on_button_e_clicked(self, widget):
        self._entry_function_append_text('e')

    def on_button_addf_cancel_clicked(self, widget):
        self.dialog_add_function.hide()

    @threaded
    def on_button_addf_ok_clicked(self, widget):
        gobject.idle_add(self.window_calculating.show)
        expr = self.entry_function.get_text()
        f = self.fg.add_function(expr)
        if f:
            gobject.idle_add(self.dialog_add_function.hide)
            gobject.idle_add(self.window_calculating.hide)
            gobject.idle_add(self.update_function_list)
            gobject.idle_add(self.graph_update)
        else:
            gobject.idle_add(self.window_calculating.hide)
            gobject.idle_add(self.dialog_add_error.show)

    # Error while adding function dialog
    def on_dialog_add_error_delete_event(self, widget, event):
        self.dialog_add_error.hide()
        return True

    def on_button_add_error_close_clicked(self, widget):
        self.dialog_add_error.hide()

    #
    # file new/open/save dialogs
    #
    def on_button_confirm_new_yes_clicked(self, widget):
        self.dialog_confirm_new.hide()
        self.changed = False
        self.filename = None
        self.fg.new()
        self.update_function_list()
        self.graph_update()

    def on_button_confirm_new_cancel_clicked(self, widget):
        self.dialog_confirm_new.hide()

    def on_dialog_confirm_new_delete_event(self, widget, event):
        self.dialog_confirm_new.hide()
        return True

    def on_button_fileopen_open_clicked(self, widget):
        filename = self.fcdialog_open.get_filename()
        filename = filename.encode(sys.getfilesystemencoding())
        folder = self.fcdialog_open.get_current_folder()
        logging.debug('Loading file: ' + filename)
        try:
            filehandler = open(filename, "rb")
            try:
                self.fg = pickle.load(filehandler)
                filehandler.close()
                self.folder = folder
                self.fg.update_xylimits()
                self._restore_state()
                self.update_function_list()
                self.graph_update()
                self.fcdialog_open.hide()
                self.changed = False
                self.filename = filename
            except:
                self.label_open_error.\
                    set_text(
                        _("File doesn't look like a FunctionPlot file."))
                self.dialog_file_open_error.show()
        except:
            self.label_open_error.set_text(_('Error reading file.'))
            self.dialog_file_open_error.show()

    def on_button_fileopen_cancel_clicked(self, widget):
        self.fcdialog_open.hide()

    def on_filechooserdialog_open_delete_event(self, widget, event):
        self.fcdialog_open.hide()
        return True

    def on_button_file_open_error_close_clicked(self, widget):
        self.dialog_file_open_error.hide()

    def on_dialog_file_open_error_delete_event(self, widget, event):
        self.dialog_file_open_error.hide()
        return True

    def on_button_filesave_save_clicked(self, widget):
        filename = self.fcdialog_save.get_filename()
        filename = filename.encode(sys.getfilesystemencoding())
        try:
            if os.path.isdir(filename):
                self.fcdialog_save.set_current_folder(filename)
                self.folder = filename
            else:
                if not filename.lower().endswith('.functionplot'):
                    filename = filename + '.functionplot'
                folder = self.fcdialog_save.get_current_folder()
                self.filename = filename
                self.folder = folder
                if os.path.isfile(filename):
                    logging.debug('File already exists: ' + filename)
                    self.dialog_overwrite.show()
                else:
                    saved = self._save()
        # TypeError is raised if the filename is empty, or only
        # spaces, or has invalid characters.
        except TypeError:
            pass

    def on_button_filesave_cancel_clicked(self, widget):
        self.fcdialog_save.hide()

    def on_filechooserdialog_save_delete_event(self, widget, event):
        self.fcdialog_save.hide()
        return True

    def on_button_save_error_close_clicked(self, widget):
        self.dialog_file_save_error.hide()

    def on_dialog_file_save_error_delete_event(self, widget, event):
        self.dialog_file_save_error.hide()
        return True

    def on_button_overwrite_yes_clicked(self, widget):
        self.dialog_overwrite.hide()
        self._save()

    def on_button_overwrite_cancel_clicked(self, widget):
        self.dialog_overwrite.hide()
        self.fcdialog_save.hide()

    def on_button_overwrite_no_clicked(self, widget):
        self.dialog_overwrite.hide()

    def on_dialog_overwrite_delete_event(self, widget, event):
        self.dialog_overwrite.hide()
        return True

    def on_button_confirm_open_yes_clicked(self, widget):
        self.fcdialog_open.set_current_folder(self.folder)
        self.dialog_confirm_open.hide()
        self.fcdialog_open.show()

    def on_button_confirm_open_cancel_clicked(self, widget):
        self.dialog_confirm_open.hide()

    def on_dialog_confirm_open_delete_event(self, widget, event):
        self.dialog_confirm_open.hide()
        return True

    def on_button_export_yes_clicked(self, widget):
        filename = self.fcdialog_export.get_filename()
        filename = filename.encode(sys.getfilesystemencoding())
        try:
            if os.path.isdir(filename):
                self.fcdialog_export.set_current_folder(filename)
                self.folder = filename
            else:
                if not filename.lower().endswith('.png'):
                    filename = filename + '.png'
                self.export_filename = filename
                folder = self.fcdialog_export.get_current_folder()
                self.folder = folder
                if os.path.isfile(filename):
                    logging.debug('File already exists: ' + filename)
                    self.dialog_export_overwrite.show()
                else:
                    saved = self._export()
        # TypeError is raised if the filename is empty, or only
        # spaces, or has invalid characters.
        except TypeError:
            pass

    def on_button_export_cancel_clicked(self, widget):
        self.fcdialog_export.hide()

    def on_button_confirm_quit_yes_clicked(self, widget):
        gtk.main_quit()

    def on_button_confirm_quit_cancel_clicked(self, widget):
        self.dialog_confirm_quit.hide()

    def on_dialog_confirm_quit_delete_event(self, widget, event):
        self.dialog_confirm_quit.hide()
        return True

    def on_filechooserdialog_export_delete_event(self, widget,
                                                 event):
        self.fcdialog_export.hide()
        return True

    def on_button_export_overwrite_yes_clicked(self, widget):
        self.dialog_export_overwrite.hide()
        self._export()

    def on_button_export_overwrite_cancel_clicked(self, widget):
        self.dialog_export_overwrite.hide()
        self.fcdialog_export.hide()

    def on_button_export_overwrite_no_clicked(self, widget):
        self.dialog_export_overwrite.hide()

    def on_dialog_export_overwrite_delete_event(self, widget, event):
        self.dialog_export_overwrite.hide()
        return True

    def on_button_export_error_close_clicked(self, widget):
        self.dialog_file_export_error.hide()

    def on_dialog_file_export_error_delete_event(self, widget,
                                                 event):
        self.dialog_file_export_error.hide()
        return True

    def on_functionplot_delete_event(self, widget, event):
        self._quit()
        return True

    # example functions
    @threaded
    def _add_example_function(self, expr):
        self.changed = True
        gobject.idle_add(self.window_calculating.show)
        f = self.fg.add_function(expr)
        gobject.idle_add(self.window_calculating.hide)
        gobject.idle_add(self.update_function_list)
        gobject.idle_add(self.graph_update)

    def on_button_add_2_clicked(self, widget):
        self._add_example_function('2')

    def on_button_abs_xp2_m1_clicked(self, widget):
        self._add_example_function('abs(x+2)-1')

    def on_button_abs_x_p2_clicked(self, widget):
        self._add_example_function('abs(x)+2')

    def on_button_add_x_clicked(self, widget):
        self._add_example_function('x')

    def on_button_add_2x_clicked(self, widget):
        self._add_example_function('2x')

    def on_button_add_mx_clicked(self, widget):
        self._add_example_function('-x')

    def on_button_add_xm1_clicked(self, widget):
        self._add_example_function('x-1')

    def on_button_add_mxp3_clicked(self, widget):
        self._add_example_function('-x+3')

    def on_button_add_abs_x_clicked(self, widget):
        self._add_example_function('abs(x)')

    def on_button_abs_xp2_clicked(self, widget):
        self._add_example_function('abs(x+2)')

    def on_button_add_x_square_clicked(self, widget):
        self._add_example_function('x^2')

    def on_button_add_quad1_clicked(self, widget):
        self._add_example_function('2x^2')

    def on_button_add_quad2_clicked(self, widget):
        self._add_example_function('-x^2')

    def on_button_add_quad3_clicked(self, widget):
        self._add_example_function('3x^2+2x-4')

    def on_button_add_quad4_clicked(self, widget):
        self._add_example_function('(x-1)^2')

    def on_button_add_quad5_clicked(self, widget):
        self._add_example_function('(x+2)(x-1)')

    def on_button_add_quad6_clicked(self, widget):
        self._add_example_function('(x-2)^2')

    def on_button_add_x_cube_clicked(self, widget):
        self._add_example_function('x^3')

    def on_button_add_poly1_clicked(self, widget):
        self._add_example_function('2x^3')

    def on_button_add_poly2_clicked(self, widget):
        self._add_example_function('-x^3')

    def on_button_add_poly3_clicked(self, widget):
        self._add_example_function('3x^3-8x^2+2x-1')

    def on_button_add_poly4_clicked(self, widget):
        self._add_example_function('-(x-2)^3')

    def on_button_add_poly5_clicked(self, widget):
        self._add_example_function('(x+2)(x-1)(x-3)')

    def on_button_add_poly6_clicked(self, widget):
        self._add_example_function('x^4')

    def on_button_add_poly7_clicked(self, widget):
        self._add_example_function('x^4-3x^2+5x-3')

    def on_button_add_poly8_clicked(self, widget):
        self._add_example_function('x^5')

    def on_button_add_poly9_clicked(self, widget):
        self._add_example_function('-(x-5)^3 x^2')

    def on_button_add_poly10_clicked(self, widget):
        self._add_example_function('(x-1)^12')

    def on_button_add_poly11_clicked(self, widget):
        self._add_example_function('-(x+3)^13')

    def on_button_add_poly12_clicked(self, widget):
        self._add_example_function('abs(x^3)')

    def on_button_add_rat1_clicked(self, widget):
        self._add_example_function('1/x')

    def on_button_add_rat2_clicked(self, widget):
        self._add_example_function('-1/x')

    def on_button_add_rat3_clicked(self, widget):
        self._add_example_function('1/(x+2)')

    def on_button_add_rat4_clicked(self, widget):
        self._add_example_function('2/x')

    def on_button_add_rat5_clicked(self, widget):
        self._add_example_function('x/(2x+3)')

    def on_button_add_rat6_clicked(self, widget):
        self._add_example_function('(2x+1)/(x+1)')

    def on_button_add_rat7_clicked(self, widget):
        self._add_example_function('(x^2+1)/(x-1)')

    def on_button_add_rat8_clicked(self, widget):
        self._add_example_function('(x-1)/(x^2+1)')

    def on_button_add_rat9_clicked(self, widget):
        self._add_example_function('1/x^2')

    def on_button_add_rat10_clicked(self, widget):
        self._add_example_function('4/(x^2+1)')

    def on_button_add_pow1_clicked(self, widget):
        self._add_example_function('2^x')

    def on_button_add_pow2_clicked(self, widget):
        self._add_example_function('2^(-x)')

    def on_button_add_pow3_clicked(self, widget):
        self._add_example_function('-2^x')

    def on_button_add_pow4_clicked(self, widget):
        self._add_example_function('-2^(-x)')

    def on_button_add_pow5_clicked(self, widget):
        self._add_example_function('2^(x-1)')

    def on_button_add_pow6_clicked(self, widget):
        self._add_example_function('2^(x+1)')

    def on_button_add_pow7_clicked(self, widget):
        self._add_example_function('exp(x)')

    def on_button_add_pow8_clicked(self, widget):
        self._add_example_function('3^x')

    def on_button_add_pow9_clicked(self, widget):
        self._add_example_function('10^x')

    def on_button_add_pow10_clicked(self, widget):
        self._add_example_function('x^x')

    def on_button_add_log1_clicked(self, widget):
        self._add_example_function('log(x)')

    def on_button_add_log2_clicked(self, widget):
        self._add_example_function('log(x-1)')

    def on_button_add_log3_clicked(self, widget):
        self._add_example_function('log(x+1)')

    def on_button_add_log4_clicked(self, widget):
        self._add_example_function('log(2x)')

    def on_button_add_log5_clicked(self, widget):
        self._add_example_function('log(x)-2')

    def on_button_add_log6_clicked(self, widget):
        self._add_example_function('xlog(x)')

    def on_button_add_log7_clicked(self, widget):
        self._add_example_function('ln(x)')

    def on_button_add_log8_clicked(self, widget):
        self._add_example_function('log(x)ln(x)')

    def on_button_add_log9_clicked(self, widget):
        self._add_example_function('log(abs(x))')

    def on_button_add_trig1_clicked(self, widget):
        self._add_example_function('sin(x)')

    def on_button_add_trig2_clicked(self, widget):
        self._add_example_function('sin(2x)')

    def on_button_add_trig3_clicked(self, widget):
        self._add_example_function('-sin(x)')

    def on_button_add_trig4_clicked(self, widget):
        self._add_example_function('sin(x-1)')

    def on_button_add_trig5_clicked(self, widget):
        self._add_example_function('sin(x+1)')

    def on_button_add_trig6_clicked(self, widget):
        self._add_example_function('cos(x)')

    def on_button_add_trig7_clicked(self, widget):
        self._add_example_function('tan(x)')

    def on_button_add_trig8_clicked(self, widget):
        self._add_example_function('cot(x)')

    def on_button_add_trig9_clicked(self, widget):
        self._add_example_function('sec(x)')

    def on_button_add_trig10_clicked(self, widget):
        self._add_example_function('csc(x)')

    def on_button_add_root1_clicked(self, widget):
        self._add_example_function('sqrt(x)')

    def on_button_add_root2_clicked(self, widget):
        self._add_example_function('sqrt(2x)')

    def on_button_add_root3_clicked(self, widget):
        self._add_example_function('-sqrt(x)')

    def on_button_add_root4_clicked(self, widget):
        self._add_example_function('sqrt(-x)')

    def on_button_add_root5_clicked(self, widget):
        self._add_example_function('sqrt(x-1)')

    def on_button_add_root6_clicked(self, widget):
        self._add_example_function('sqrt(x^2+3)')

    def on_button_add_root7_clicked(self, widget):
        self._add_example_function('sqrt(1-x^2)')

    def on_button_add_root8_clicked(self, widget):
        self._add_example_function('xsqrt(x^2-4)')

    def on_button_add_comb1_clicked(self, widget):
        self._add_example_function('x-cos(x)')

    def on_button_add_comb2_clicked(self, widget):
        self._add_example_function('x^2/log(x)')

    def on_button_add_comb3_clicked(self, widget):
        self._add_example_function('x^3/abs(x(x-1))')

    def on_button_add_comb4_clicked(self, widget):
        self._add_example_function('x2^x')

    def on_button_add_comb5_clicked(self, widget):
        self._add_example_function('-4^x+x^4')

    def on_button_add_comb6_clicked(self, widget):
        self._add_example_function('(x^2+3)/sqrt(x-2)')

    def on_button_add_comb7_clicked(self, widget):
        self._add_example_function('sin(log(x))')

    # save the graph
    def _save(self):
        try:
            filehandler = open(self.filename, "wb")
            pickle.dump(self.fg, filehandler)
            filehandler.close()
            logging.debug('File saved: ' + self.filename)
            self.changed = False
            self.fcdialog_save.hide()
            return True
        except:
            self.dialog_file_save_error.show()
            return False

    # export the graph to png
    def _export(self):
        try:
            filename = self.export_filename
            self.fig.savefig(filename, dpi=300)
            self.fcdialog_export.hide()
        except:
            self.dialog_file_export_error.show()

    # restores the status of checkboxes when loading a graph
    # from a file or creating a new graph
    def _restore_state(self):
        self.checkmenuitem_function_intersections.\
            set_active(self.fg.point_type_enabled[1])
        self.checkmenuitem_x_intercepts.\
            set_active(self.fg.point_type_enabled[2])
        self.checkmenuitem_y_intercepts.\
            set_active(self.fg.point_type_enabled[3])
        self.checkmenuitem_extrema.\
            set_active(self.fg.point_type_enabled[4])
        self.checkmenuitem_inflection.\
            set_active(self.fg.point_type_enabled[5])
        self.checkmenuitem_vertical_asym.\
            set_active(self.fg.point_type_enabled[6])
        self.checkmenuitem_horizontal_asym.\
            set_active(self.fg.point_type_enabled[7])
        self.checkmenuitem_slope45.\
            set_active(self.fg.point_type_enabled[8])
        self.checkmenuitem_outliers.set_active(self.fg.outliers)
        self.checkmenuitem_show_poi.set_active(self.fg.show_poi)
        self.checkmenuitem_grouped.set_active(self.fg.grouped)
        self.checkmenuitem_legend.set_active(self.fg.show_legend)
        self.menuitem_legend_upper_right.set_active(False)
        self.menuitem_legend_upper_left.set_active(False)
        self.menuitem_legend_lower_right.set_active(False)
        self.menuitem_legend_lower_left.set_active(False)
        if self.fg.legend_location == 2:
            self.menuitem_legend_upper_left.set_active(True)
        elif self.fg.legend_location == 3:
            self.menuitem_legend_lower_left.set_active(True)
        elif self.fg.legend_location == 4:
            self.menuitem_legend_lower_right.set_active(True)
        else:
            self.menuitem_legend_upper_right.set_active(True)
        self.checkmenuitem_logscale.set_active(self.fg.logscale)
        self.btn_auto.set_active(self.fg.auto)

    def __init__(self):
        # Only a few colors defined. Hard to find more that will
        # stand out. If there are more functions, colors will cycle
        # from the start.
        # colors were taken mostly from http://latexcolor.com/
        self.color = ['#4F81BD',  # blue
                      '#C0504D',  # red
                      '#9BBB59',  # green
                      '#8064A2',  # purple
                      '#F79646',  # orange
                      '#00B7EB',  # cyan
                      '#3B444B',  # charcoal
                      '#F0E130',  # yellow
                      '#DE5D83',  # pink (blush)
                      '#B87333',  # copper
                      '#0047AB',  # cobalt
                      '#614051',  # eggplant
                      ]
        # filenames to save to/open from and export to
        self.filename = None
        self.export_filename = None
        # create a FunctionGraph object
        self.fg = FunctionGraph()
        # we need this to keep track if the file has changed since
        # last save
        self.changed = False
        # we'll need this for panning
        self.mousebutton_press = None

        # Load GUI from glade file
        builder = gtk.Builder()
        builder.add_from_file(os.path.join(here,
                                           'functionplot.glade'))

        #
        # Main Window
        #
        self.window = builder.get_object('functionplot')
        # on win32 just maximize the window. _NetWORKAREA
        # doesn't work anyway
        if win32:
            self.window.maximize()
        else:
            # on non-win32 systems, get the size of the
            # working area (if supported by the window
            # manager) and set the window dimensions to
            # 80% of that
            try:
                w = gtk.gdk.get_default_root_window()
                p = gtk.gdk.atom_intern('_NET_WORKAREA')
                workarea_width, workarea_height = \
                    w.property_get(p)[2][2:4]
                width = int(workarea_width * 0.8)
                height = int(workarea_height * 0.8)
            except TypeError:
                width = 700
                height = 500
            self.window.set_default_size(width, height)
        # menus
        self.imagemenuitem_quit = \
            builder.get_object('imagemenuitem_quit')

        self.checkmenuitem_function_intersections = builder.\
            get_object('checkmenuitem_function_intersections')
        self.checkmenuitem_x_intercepts = \
            builder.get_object('checkmenuitem_x_intercepts')
        self.checkmenuitem_y_intercepts = \
            builder.get_object('checkmenuitem_y_intercepts')
        self.checkmenuitem_extrema = \
            builder.get_object('checkmenuitem_extrema')
        self.checkmenuitem_inflection = \
            builder.get_object('checkmenuitem_inflection')
        self.checkmenuitem_vertical_asym = \
            builder.get_object('checkmenuitem_vertical_asym')
        self.checkmenuitem_horizontal_asym = \
            builder.get_object('checkmenuitem_horizontal_asym')
        self.checkmenuitem_slope45 = \
            builder.get_object('checkmenuitem_slope45')
        self.checkmenuitem_outliers = \
            builder.get_object('checkmenuitem_outliers')
        self.checkmenuitem_show_poi = \
            builder.get_object('checkmenuitem_show_poi')
        self.checkmenuitem_grouped = \
            builder.get_object('checkmenuitem_grouped')
        self.checkmenuitem_legend = \
            builder.get_object('checkmenuitem_legend')
        self.menuitem_legend_upper_left = \
            builder.get_object('menuitem_legend_upper_left')
        self.menuitem_legend_upper_right = \
            builder.get_object('menuitem_legend_upper_right')
        self.menuitem_legend_lower_left = \
            builder.get_object('menuitem_legend_lower_left')
        self.menuitem_legend_lower_right = \
            builder.get_object('menuitem_legend_lower_right')
        self.checkmenuitem_logscale = \
            builder.get_object('checkmenuitem_logscale')

        # main toolbar
        self.btn_auto = builder.get_object('btn_auto')

        # restore state of GUI widgets
        self._restore_state()

        # graph in main window
        self.table = builder.get_object('table_graph')
        self.fig = Figure(facecolor='w', tight_layout=True)
        self.ax = self.fig.add_subplot(111)
        self.canvas = FigureCanvas(self.fig)
        self.table.attach(self.canvas, 0, 1, 0, 1)
        # function list
        self.ls_functions = \
            builder.get_object('liststore_functions')
        self.ls_functions.clear()
        self.treeview_functions = \
            builder.get_object('treeview_functions')
        self.cr_toggle_visible = \
            builder.get_object('cr_toggle_visible')
        # catch mouse wheel scroll
        self.canvas.mpl_connect('scroll_event', self.wheel_zoom)
        # catch click and pan
        self.canvas.mpl_connect('button_press_event',
                                self.pan_press)
        self.canvas.mpl_connect('button_release_event',
                                self.pan_release)
        self.canvas.mpl_connect('motion_notify_event',
                                self.pan_motion)
        self.graph_update()

        #
        # file open/save dialogs
        #
        self.fcdialog_open = \
            builder.get_object('filechooserdialog_open')
        self.fcdialog_save = \
            builder.get_object('filechooserdialog_save')
        filefilter = gtk.FileFilter()
        filefilter.set_name(_('FunctionPlot files'))
        filefilter.add_pattern('*.functionplot')
        filefilter.add_pattern('*.FUNCTIONPLOT')
        self.fcdialog_open.add_filter(filefilter)
        self.fcdialog_save.add_filter(filefilter)
        self.dialog_file_open_error = \
            builder.get_object('dialog_file_open_error')
        self.label_open_error = \
            builder.get_object('label_open_error')
        self.dialog_file_save_error = \
            builder.get_object('dialog_file_save_error')
        # use the "My documents" dir in windows
        if win32:
            self.folder = winshell.my_documents()
        else:
            self.folder = os.path.expanduser("~")
        # overwrite dialog
        self.dialog_overwrite = \
            builder.get_object('dialog_overwrite')
        self.label_overwrite = builder.get_object('label_overwrite')
        # confirm open dialog
        self.dialog_confirm_open = \
            builder.get_object('dialog_confirm_open')
        # confirm new dialog
        self.dialog_confirm_new = \
            builder.get_object('dialog_confirm_new')
        # confirm quit dialog
        self.dialog_confirm_quit = \
            builder.get_object('dialog_confirm_quit')
        # export dialogs
        self.fcdialog_export = \
            builder.get_object('filechooserdialog_export')
        exportfilter = gtk.FileFilter()
        exportfilter.set_name(_('PNG image files'))
        exportfilter.add_pattern('*.png')
        exportfilter.add_pattern('*.PNG')
        self.fcdialog_export.add_filter(exportfilter)
        self.dialog_export_overwrite = \
            builder.get_object('dialog_export_overwrite')
        self.dialog_file_export_error = \
            builder.get_object('dialog_file_export_error')
        #
        # Add function dialog
        #
        self.dialog_add_function = \
            builder.get_object('dialog_add_function')
        self.entry_function = builder.get_object('entry_function')
        self.dialog_add_error = \
            builder.get_object('dialog_add_error')
        # Calculating... window
        self.window_calculating = \
            builder.get_object('window_calculating')
        # About dialog
        self.aboutdialog = \
            builder.get_object('aboutdialog')
        self.logo = gtk.gdk.pixbuf_new_from_file('img/functionplot.png')
        self.aboutdialog.set_logo(self.logo)

        # Connect all signals
        builder.connect_signals(self)
        self.window.show_all()
Example #29
0
win = gtk.Window()
win.connect("destroy", lambda x: gtk.main_quit())
win.set_default_size(400,300)
win.set_title("Embedding in GTK")

vbox = gtk.VBox()
win.add(vbox)

fig = Figure(figsize=(5,4), dpi=100)
ax = fig.add_subplot(111)
t = arange(0.0,3.0,0.01)
s = sin(2*pi*t)

ax.plot(t,s)


canvas = FigureCanvas(fig)  # a gtk.DrawingArea
vbox.pack_start(canvas)
toolbar = NavigationToolbar(canvas, win)
vbox.pack_start(toolbar, False, False)


def on_key_event(event):
    print('you pressed %s'%event.key)
    key_press_handler(event, canvas, toolbar)

canvas.mpl_connect('key_press_event', on_key_event)

win.show_all()
gtk.main()
Example #30
0
class Figure(gtk.VBox):
    def __init__(self):
        print "Starting up SamFigure!"
        gtk.VBox.__init__(self)
        self.figure = MPLFigure()
        self.canvas = FigureCanvas(self.figure)
        self.canvas.mpl_connect("button_press_event", self.on_click)
        self.ax = self.figure.add_subplot(111)
        self.ax2 = None
        self.mode = TWODPLOT
        self.new_data()
        self.xlabel = ''
        self.y1label = ''
        self.y2label = ''
        self.xsize = 0
        self.ysize = 0
        self.packed = False
        self.count_since_replot = 0

        self.set_colors()

    def on_click(self, event):
        # If left button,
        if event.button == 1:
            # screen coordinates of click
            xclick, yclick = event.x, event.y
            top_ax = event.inaxes
            if top_ax is None: return

            # display coordinates of nearest point in ax
            data1=self.ax.transData.transform(\
                zip(self.listing.getX(),self.listing.getY(1)))
            distances1=\
                [(x-xclick)**2+(y-yclick)**2 \
                for (x,y) in data1]
            ind_sel1 = numpy.argmin(distances1)
            dist1 = distances1[ind_sel1]
            xsel, ysel = data1[ind_sel1]
            label_ax = self.ax
            label_color = 'b'

            # if DUAL, then also check ax2 for nearer points
            if self.mode == DUALTWODPLOT:
                data2=self.ax2.transData.transform(\
                    zip(self.listing.getX(),self.listing.getY(2)))
                distances2=\
                    [(x-xclick)**2+(y-yclick)**2 \
                    for (x,y) in data2]
                ind_sel2 = numpy.argmin(distances2)
                dist2 = distances2[ind_sel2]
                if dist2 < dist1:
                    xsel, ysel = data2[ind_sel2]
                    label_color = 'g'
                    label_ax = self.ax2

            # Clear off old labels
            if hasattr(self, "label_text"):
                self.label_text.remove()
                self.label_point.remove()
                del (self.label_text)

            # Coordinates to show ( data coordinates of the selected axes)
            xlabel, ylabel = label_ax.transData.inverted().transform(
                (xsel, ysel))

            # Coordinates to place label (on top set of axes)
            xloc, yloc = top_ax.transData.inverted().transform((xsel, ysel))

            # Label the point
            if (xloc > sum(self.ax.get_xlim()) / 2): h_align = 'right'
            else: h_align = 'left'
            self.label_text=\
                top_ax.text(xloc,yloc,'({0:.3g},{1:.3g})'\
                    .format(xlabel,ylabel),\
                    backgroundcolor='white', color=label_color,\
                    verticalalignment='bottom', horizontalalignment=h_align,\
                    bbox={'facecolor': 'white', 'boxstyle':
                          'round'},zorder=100 )
            self.label_point,=\
                    top_ax.plot(xloc,yloc,'ro',\
                    zorder=self.label_text.get_zorder()+1)
            self.repaint()

        # Otherwise, just clear off old labels
        else:
            self.label_text.remove()
            self.label_point.remove()
            del (self.label_text)
            self.repaint()

    def replot(self):
        if self.mode == TWODPLOT:
            self.ax.clear()
            self.ax.plot(self.listing.getX(), self.listing.getY(1),
                         self.color1 + '.-')
            self.count_since_replot = 0
        elif self.mode == DUALTWODPLOT:
            self.ax.clear()
            self.ax2.clear()
            self.ax.plot(self.listing.getX(), self.listing.getY(1),
                         self.color1 + '.-')
            self.ax2.plot(self.listing.getX(), self.listing.getY(2),
                          self.color2 + '.-')
            self.count_since_replot = 0

    def show(self):
        try:
            if not self.packed:
                self.pack_start(self.canvas, expand=True)
                toolbar = NavigationToolbar(self.canvas,
                                            self.get_parent_window())

                next = 8
                button = gtk.Button('Lin y')
                button.show()
                button2 = gtk.Button('Lin x')
                button2.show()

                # linear/log
                def clicked(button):
                    self.adjust_axis_margins()
                    self.set_axis_labels()
                    self.color_labels()
                    self.canvas.draw_idle()
                    self.canvas.show()
                    if self.ax.get_yscale() == 'log':
                        button.set_label('Lin y')
                        self.ax.set_yscale('linear')
                    else:
                        button.set_label('Log y')
                        self.ax.set_yscale('log')
                    self.show()

                def clicked2(button):
                    self.adjust_axis_margins()
                    self.set_axis_labels()
                    self.color_labels()
                    self.canvas.draw_idle()
                    self.canvas.show()
                    if self.ax.get_xscale() == 'log':
                        button.set_label('Lin x')
                        self.ax.set_xscale('linear')
                    else:
                        button.set_label('Log x')
                        self.ax.set_xscale('log')
                    self.show()

                button.connect('clicked', clicked)
                button2.connect('clicked', clicked2)

                toolitem = gtk.ToolItem()
                toolitem.show()
                toolitem.add(button)
                toolbar.insert(toolitem, next)
                next += 1
                toolitem2 = gtk.ToolItem()
                toolitem2.show()
                toolitem2.add(button2)
                toolbar.insert(toolitem2, next)

                self.pack_start(toolbar, expand=False)
                self.packed = True
            super(Figure, self).show()
        except Exception, e:
            print 'Exception: ', e
            raise
Example #31
0
win = gtk.Window()
win.connect("destroy", lambda x: gtk.main_quit())
win.set_default_size(400, 300)
win.set_title("Embedding in GTK")

vbox = gtk.VBox()
win.add(vbox)

fig = Figure(figsize=(5, 4), dpi=100)
ax = fig.add_subplot(111)
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)

ax.plot(t, s)

canvas = FigureCanvas(fig)  # a gtk.DrawingArea
vbox.pack_start(canvas)
toolbar = NavigationToolbar(canvas, win)
vbox.pack_start(toolbar, False, False)


def on_key_event(event):
    print('you pressed %s' % event.key)
    key_press_handler(event, canvas, toolbar)


canvas.mpl_connect('key_press_event', on_key_event)

win.show_all()
gtk.main()
Example #32
0
class XratersWindow(gtk.Window):
    __gtype_name__ = "XratersWindow"

    def __init__(self):
        """__init__ - This function is typically not called directly.
        Creation a XratersWindow requires redeading the associated ui
        file and parsing the ui definition extrenally,
        and then calling XratersWindow.finish_initializing().

        Use the convenience function NewXratersWindow to create
        XratersWindow object.

        """
        self._acc_cal = ((128, 128, 128), (255, 255, 255))
        self._acc = [0, 0, 0]
        self._connected = False
        self._wiiMote = None
        self._resetData()
        self._dataLock = threading.Lock()

    isConnected = property(lambda self: self._connected)

    def callback(funct):
        """A decorator used to require connection to the Wii Remote
        
        This decorator is used to implement the precondition that 
        the Wii Remote must be connected. 
        """
        def _callback(cls, *args, **kwds):
            if cls.isConnected:
                funct(cls, *args, **kwds)
                return True
            else:
                return False

        return _callback

    def _connectCallback(self, connectionMaker):
        """Callback function called upon successful connection to the Wiimote
        """
        if connectionMaker.connected:
            self._connected = True
            self._wiiMote = connectionMaker.wiiMote
            self._resetData()
            gobject.timeout_add(45, self._drawAcc)
            self.widget('actionDisconnect').set_sensitive(True)
            self.widget('actionSave').set_sensitive(True)
            self.widget('actionReset').set_sensitive(True)
            self.widget('actionPause').set_sensitive(True)
            self.widget('toolbutton1').set_related_action(
                self.widget('actionDisconnect'))
            self._acc_cal = connectionMaker.acc_cal
            self._wiiMote.mesg_callback = self._getAcc
            self._updBatteryLevel()
            gobject.timeout_add_seconds(60, self._updBatteryLevel)
        else:
            self.widget('actionWiiConnect').set_sensitive(True)

    @callback
    def _upd_background(self, event):
        """Keep a copy of the figure background
        """
        self.__background = self._accCanvas.copy_from_bbox(self._accAxis.bbox)

    def _getAcc(self, messages, theTime=0):
        """Process acceleration messages from the Wiimote
        
        This function is intended to be set as cwiid.mesg_callback
        """
        if self._Paused:
            return
        for msg in messages:
            if msg[0] == cwiid.MESG_ACC:
                # Normalize data using calibration info
                for i, axisAcc in enumerate(msg[1]):
                    self._acc[i] = float(axisAcc - self._acc_cal[0][i])
                    self._acc[i] /=(self._acc_cal[1][i]\
                                    -self._acc_cal[0][i])
                with self._dataLock:
                    # Store time and acceleration in the respective arrays
                    self._time.append(theTime - self._startTime)
                    [self._accData[i].append(self._acc[i]) for i in threeAxes]
                # We only keep about 6 seconds worth of data
                if (self._time[-1] - self._time[0] > 6):
                    with self._dataLock:
                        self._time.pop(0)
                        [self._accData[i].pop(0) for i in threeAxes]

    @callback
    def _drawAcc(self):
        """Update the acceleration graph
        
        """
        # Do nothing while paused or there's no data available
        if self._Paused or len(self._time) == 0:
            return
        draw_flag = False
        # Update axes limits if the data fall out of range
        lims = self._accAxis.get_xlim()
        if self._time[-1] > lims[1]:
            self._accAxis.set_xlim(lims[0], lims[1] + 2)
            lims = self._accAxis.get_xlim()
            draw_flag = True
        if (self._time[-1] - lims[0] > 6):
            self._accAxis.set_xlim(lims[0] + 2, lims[1])
            draw_flag = True
        if draw_flag:
            gobject.idle_add(self._accCanvas.draw)
        # Do the actual update of the background
        if self.__background != None:
            self._accCanvas.restore_region(self.__background)
        # Do the actual update of the lines
        with self._dataLock:
            [
                self._lines[i].set_data(self._time, self._accData[i])
                for i in threeAxes
            ]
        [self._accAxis.draw_artist(self._lines[i]) for i in threeAxes]
        self._accCanvas.blit(self._accAxis.bbox)

    @callback
    def _updBatteryLevel(self):
        """Callback to update the battery indicator in the status bar
        
        """
        self._wiiMote.request_status()
        self._setBatteryIndicator(
            float(self._wiiMote.state['battery']) / cwiid.BATTERY_MAX)

    def _setBatteryIndicator(self, level):
        """Actually update the battery indicator in the status bar
        
        """
        progressBar = self.widget("progressbarBattery")
        progressBar.set_fraction(level)
        progressBar.set_text("Battery: %.0f%%" % (level * 100))

    def _resetData(self):
        """Reset stored data and status flags to their defaults
        
        """
        self._accData = [list(), list(), list()]
        self._time = list()
        self._startTime = time.time()
        self._moveTime = self._startTime
        self._Paused = False

    def widget(self, name):
        """Helper function to retrieve widget handlers
        
        """
        return self.builder.get_object(name)

    def finish_initializing(self, builder):
        """finish_initalizing should be called after parsing the ui definition
        and creating a XratersWindow object with it in order to finish
        initializing the start of the new XratersWindow instance.

        """
        #get a reference to the builder and set up the signals
        self.builder = builder
        self.builder.connect_signals(self)

        #uncomment the following code to read in preferences at start up
        dlg = PreferencesXratersDialog.NewPreferencesXratersDialog()
        self.preferences = dlg.get_preferences()

        #code for other initialization actions should be added here
        self._accFigure = Figure(figsize=(8, 6), dpi=72)
        self._accAxis = self._accFigure.add_subplot(111)
        self._accAxis.set_xlabel("time (s)")
        self._accAxis.set_ylabel("acceleration (g)")
        self._lines = self._accAxis.plot(self._time,
                                         self._accData[X],
                                         self._time,
                                         self._accData[Y],
                                         self._time,
                                         self._accData[Z],
                                         animated=True)
        self._accFigure.legend(self._lines, ("X", "Y", "Z"),
                               'upper center',
                               ncol=3)
        self._accAxis.set_xlim(0, 2)
        self._accAxis.set_ylim(-3, 3)
        self._accCanvas = FigureCanvas(self._accFigure)
        self._accCanvas.mpl_connect("draw_event", self._upd_background)
        self.__background = self._accCanvas.copy_from_bbox(self._accAxis.bbox)
        self._accCanvas.show()
        self._accCanvas.set_size_request(600, 400)
        vbMain = self.widget("vboxMain")
        vbMain.pack_start(self._accCanvas, True, True)
        vbMain.show()
        vbMain.reorder_child(self._accCanvas, 2)
        self._setBatteryIndicator(0)

    def about(self, widget, data=None):
        """about - display the about box for xraters """
        about = AboutXratersDialog.NewAboutXratersDialog()
        response = about.run()
        about.destroy()

    def preferences(self, widget, data=None):
        """preferences - display the preferences window for xraters """
        prefs = PreferencesXratersDialog.NewPreferencesXratersDialog()
        response = prefs.run()
        if response == gtk.RESPONSE_OK:
            #make any updates based on changed preferences here
            self.preferences = prefs.get_preferences()
        prefs.destroy()

    def quit(self, widget, data=None):
        """quit - signal handler for closing the XratersWindow"""
        self.destroy()

    def on_destroy(self, widget, data=None):
        """on_destroy - called when the XratersWindow is close. """
        #clean up code for saving application state should be added here
        if self.isConnected:
            self.on_wiiDisconnect(widget, data)
        gtk.main_quit()

    def on_wiiConnect(self, widget, data=None):
        """Signal handler for the WiiConnect action
        
        """
        self.widget('actionWiiConnect').set_sensitive(False)
        connectionMaker = WiiConnectionMaker(self.preferences['wiiAddress'],
                                             self.widget("statusbar"),
                                             self._connectCallback)
        self._accAxis.set_xlim(0, 2)
        gobject.idle_add(self._accCanvas.draw)
        connectionMaker.start()

    def on_wiiDisconnect(self, widget, data=None):
        """Signal handler for the WiiDisconnect action
        
        """
        self._wiiMote.close()
        self._connected = False
        self.widget('actionDisconnect').set_sensitive(False)
        self.widget('actionWiiConnect').set_sensitive(True)
        self.widget('actionReset').set_sensitive(False)
        self.widget('actionPause').set_sensitive(False)
        self.widget('toolbutton1').set_related_action(
            self.widget('actionWiiConnect'))
        self.widget('actionSave').set_sensitive(True)
        self.widget('statusbar').pop(
            self.widget("statusbar").get_context_id(''))
        self._setBatteryIndicator(0)

    def on_Reset(self, widget, data=None):
        """Signal handler for the reset action
        
        """
        self._resetData()
        self._accAxis.set_xlim(0, 2)
        gobject.idle_add(self._accCanvas.draw)

    def on_Pause(self, widge, data=None):
        """Signal handler for the pause action
        
        """
        if not self._Paused:
            self.widget('actionPause').set_short_label("Un_pause")
        else:
            self.widget('actionPause').set_short_label("_Pause")
        self._Paused = not (self._Paused)

    def save(self, widget, data=None):
        """Signal handler for the save action
        
        """
        fileName = os.sep.join([
            self.preferences['outputDir'],
            "acceleration_" + time.strftime("%Y-%m-%d_%H-%M-%S") + ".dat"
        ])
        try:
            with open(fileName, 'wb') as outFile:
                writer = csv.writer(outFile, 'excel-tab')
                outFile.write(
                    writer.dialect.delimiter.join(("#time", "Ax", "Ay", "Az")))
                outFile.write(writer.dialect.lineterminator)
                outFile.write(
                    writer.dialect.delimiter.join(("#s", "g", "g", "g")))
                outFile.write(writer.dialect.lineterminator)
                with self._dataLock:
                    writer.writerows(zip(self._time, *self._accData))
        except IOError as error:
            dialog = gtk.MessageDialog(parent=None,
                                       flags=gtk.DIALOG_DESTROY_WITH_PARENT,
                                       type=gtk.MESSAGE_ERROR,
                                       buttons=gtk.BUTTONS_OK,
                                       message_format=str(error))
            dialog.set_title(error[1])
            dialog.connect('response',
                           lambda dialog, response: dialog.destroy())
            dialog.show()
Example #33
0
class DataMatrixGUI(gtk.Window):
    """
    2009-3-13
        migrated from QCVisualize.py. now become a standalone program and
            able to read data from a file and plot ...
        QCVisualize.py inherits from here
    2008-02-05
        embed it into a bigger gnome app, add more buttons, and change the __init__()
    2008-01-01
        class to visualize the results from QualityControl.py
    """
    def __init__(self, plot_title='', id_is_strain=1, header=None,
        strain_acc_list=None, category_list=None, data_matrix=None):
        """
        2008-01-10
            use a paned window to wrap the scrolledwindow and the canvas
            so that the relative size of canvas to the scrolledwindow could be adjusted by the user.
        """
        prog = gnome.program_init('DataMatrixGUI', '0.1')
        #this must be called before any initialization for gnome app
        
        program_path = os.path.dirname(__init__.__file__)
        xml = gtk.glade.XML(os.path.join(program_path, 'DataMatrixGUI.glade'))
        xml.signal_autoconnect(self)
        self.app1 = xml.get_widget("app1")
        self.app1.connect("delete_event", gtk.main_quit)
        self.app1.set_default_size(800, 1000)
        self.app1.set_title(plot_title)
        
        self.plot_title = plot_title
        self.id_is_strain = id_is_strain
        self.header = header
        self.strain_acc_list = strain_acc_list
        self.category_list = category_list
        self.data_matrix = data_matrix
        
        self.inputDataHeaders = None
        
        self.columnTypes = None
        self.columnHeaders = None
        self.columnEditableFlagList = None
        self.list2D = None
        
        self.vbox1 = xml.get_widget("vbox1")
        self.treeview_matrix = xml.get_widget("treeview_matrix")
        
        # matplotlib stuff
        fig = Figure(figsize=(8,8))
        
        self.canvas = FigureCanvas(fig)  # a gtk.DrawingArea
        self._idClick = self.canvas.mpl_connect('button_press_event', self.onUserClickCanvas)
        self.vpaned1 = xml.get_widget("vpaned1")
        self.vpaned1.add2(self.canvas)
        
        #self.vbox1.pack_start(self.canvas, True, True)
        self.ax = fig.add_subplot(111)

        self.treeview_matrix.connect('row-activated', self.plot_row)
        
        toolbar = NavigationToolbar(self.canvas, self.app1)
        self.vbox1.pack_start(toolbar, False, False)
        
        self.checkbutton_label_dot = xml.get_widget('checkbutton_label_dot')
        self.entry_dot_label_column = xml.get_widget('entry_dot_label_column')
        self.dataLabelColumnIndexAndSeparatorList = None
        self.dataLabelNumericItemIndexList = None 
        
        self.entry_x_na = xml.get_widget('entry_x_na')
        self.entry_y_na = xml.get_widget('entry_y_na')
        
        self.entry_multiply_x = xml.get_widget('entry_multiply_x')
        self.entry_multiply_y = xml.get_widget('entry_multiply_y')
        self.entry_add_x = xml.get_widget('entry_add_x')
        self.entry_add_y = xml.get_widget('entry_add_y')

        self.entry_x_error = xml.get_widget("entry_x_error")
        self.entry_y_error = xml.get_widget("entry_y_error")
        self.checkbutton_logX = xml.get_widget('checkbutton_logX')
        self.checkbutton_logY = xml.get_widget('checkbutton_logY')
        self.checkButtonPlotOnlySelected = xml.get_widget('checkButtonPlotOnlySelected')
        self.entry_x_column = xml.get_widget('entry_x_column')
        self.entry_y_column = xml.get_widget('entry_y_column')
        
        self.entry_filters = xml.get_widget("entry_filters")
        #self.checkbutton_histLogX = xml.get_widget('checkbutton_histLogX')
        #self.checkbutton_histLogY = xml.get_widget('checkbutton_histLogY')
        
        self.entry_hist_column = xml.get_widget('entry_hist_column')
        self.entry_no_of_bins = xml.get_widget('entry_no_of_bins')
        self.entry_plot_title = xml.get_widget('entry_plot_title')
        self.entry_plot_title.set_text(self.plot_title)
        
        self.filechooserdialog_save = xml.get_widget("filechooserdialog_save")
        self.filechooserdialog_save.connect("delete_event", yh_gnome.subwindow_hide)
        
        self.entry_sampling_probability = xml.get_widget("entry_sampling_probability")
        self.filechooserdialog_open = xml.get_widget("filechooserdialog_open")
        self.filechooserdialog_open.connect("delete_event", yh_gnome.subwindow_hide)
        
        self.app1_appbar1 = xml.get_widget('app1_appbar1')
        self.app1_appbar1.push('Status Message.')	#import gnome.ui has to be executed.
        
        self.treeview_matrix.connect('cursor-changed', self.update_no_of_selected, self.app1_appbar1)
        self.app1.show_all()
        
        self.xValuePreProcessor = None
        self.yValuePreProcessor = None
        
        self.x_error_column_index = None
        self.y_error_column_index = None
        
        self.typeName2PythonType = {
                "str": str,
                "string": str,
                "numeric":float,
                "number":float,
                "double":float,
                "float":float,
                "integer":int,
                "int":int}
        
        #self.add_events(gdk.BUTTON_PRESS_MASK|gdk.KEY_PRESS_MASK|gdk.KEY_RELEASE_MASK)
    
    def parseDataLabelColumns(self, inputText):
        """
        2015.04.16
        """
        splitP= re.compile(r'([,/|\.\-_=\?:;"\'^%$@+])')
        #any single character included could be used as splitter
        self.dataLabelColumnIndexAndSeparatorList = splitP.split(inputText)
        self.dataLabelNumericItemIndexList = []
        for i in range(len(self.dataLabelColumnIndexAndSeparatorList)):
            if not splitP.match(self.dataLabelColumnIndexAndSeparatorList[i]):
                #it's a column index
                self.dataLabelColumnIndexAndSeparatorList[i] = int(self.dataLabelColumnIndexAndSeparatorList[i])
                self.dataLabelNumericItemIndexList.append(i)
        return self.dataLabelColumnIndexAndSeparatorList, self.dataLabelNumericItemIndexList 
    
    def getDataPointLabel(self, dataRow):
        """
        2015.04.16
        """
        dataLabelInList = copy.deepcopy(self.dataLabelColumnIndexAndSeparatorList)
        for i in self.dataLabelNumericItemIndexList:
            dataLabelInList[i] = str(dataRow[self.dataLabelColumnIndexAndSeparatorList[i]])
        return ''.join(dataLabelInList)
    
    def onUserClickCanvas(self, event):
        """
        2016.06.07 bugfix. zero(0) generates false condition while only empty string or None should generate false.
        2009-3-13
            use (x_lim[1]-x_lim[0])/200. as the resolution for a dot to be called identical to a data point.
            similar for the y_data
        2009-3-13
            deal with checkbutton_label_dot, entry_dot_label_column, entry_x_column, entry_y_column
        2008-01-01
            derived from on_click_row() of QualityControl.py
            reaction when user clicked in the plot
        """
        # get the x and y coords, flip y from top to bottom
        x, y = event.x, event.y
        toLabelDataPoint = self.checkbutton_label_dot.get_active()
        
        self.parseDataLabelColumns(self.entry_dot_label_column.get_text())
        
        x_column = int(self.entry_x_column.get_text())
        y_column = int(self.entry_y_column.get_text())
        x_lim = self.ax.get_xlim()
        x_grain_size = abs(x_lim[1]-x_lim[0])/200.
        y_lim = self.ax.get_ylim()
        y_grain_size = abs(y_lim[1]-y_lim[0])/200.
        if event.button==1:
            if event.inaxes is not None:
                sys.stderr.write("x_grain_size: %s, y_grain_size: %s\n"%(x_grain_size, y_grain_size))
                sys.stderr.write("data coords: %s, %s\n"%(event.xdata, event.ydata))
                if self.list2D is None:
                    return
                for row in self.list2D:
                    if row[x_column] is not None and row[x_column]!="" and \
                        row[y_column] is not None and row[y_column]!="" :	#not empty
                        #2016.06.07
                        try:
                            x_data = float(row[x_column])
                            y_data = float(row[y_column])
                            x = self.processDataValue(x_data, self.xValuePreProcessor)
                            if x is None:
                                continue
                            y = self.processDataValue(y_data, self.yValuePreProcessor)
                            if y is None:
                                continue
                            if abs(x-event.xdata)<x_grain_size and abs(y-event.ydata)<y_grain_size:
                                dataLabel = self.getDataPointLabel(row)
                                if toLabelDataPoint:
                                    self.ax.text(event.xdata, event.ydata, dataLabel, size=8)
                                    self.canvas.draw()
                                sys.stderr.write("%s: %s, %s: %s, raw xy=(%s, %s), scaled xy=(%s,%s), dataLabel: %s.\n"%\
                                    (self.columnHeaders[0], row[0], self.columnHeaders[1], row[1], 
                                    row[x_column], row[y_column], x,y, dataLabel))
                        except:
                            sys.stderr.write("Column %s, %s of row (%s), could not be converted to float. skip.\n"%\
                                (x_column, y_column, repr(row)))
    
    def setUserDataPreprocessingFlags(self):
        """
        2014.07.25
        """
        
        self.xValuePreProcessor = ValuePreProcessor(na = self.entry_x_na.get_text())
        self.yValuePreProcessor = ValuePreProcessor(na = self.entry_y_na.get_text())
        
        if self.entry_multiply_x.get_text():
            self.xValuePreProcessor.scalar = float(self.entry_multiply_x.get_text())
        if self.entry_multiply_y.get_text():
            self.yValuePreProcessor.scalar = float(self.entry_multiply_y.get_text())

        if self.entry_add_x.get_text():
            self.xValuePreProcessor.addition = float(self.entry_add_x.get_text())
        if self.entry_add_y.get_text():
            self.yValuePreProcessor.addition = float(self.entry_add_y.get_text())
        
        if self.entry_x_error.get_text():
            self.xValuePreProcessor.errorColumnIndex = int(self.entry_x_error.get_text())
        if self.entry_y_error.get_text():
            self.yValuePreProcessor.errorColumnIndex = int(self.entry_y_error.get_text())
        
        if self.checkbutton_logX.get_active():
            self.xValuePreProcessor.logScale = True
        if self.checkbutton_logY.get_active():
            self.yValuePreProcessor.logScale = True
    
    def processDataValue(self, value=None, valuePreProcessor=None):
        """
        2014.07.31
        """
        
        if valuePreProcessor.na is not None and (value==valuePreProcessor.na or \
            float(value)==float(valuePreProcessor.na)):
            return None
        value = float(value)
        if valuePreProcessor.scalar is not None:
            value = value*valuePreProcessor.scalar
        if valuePreProcessor.addition is not None:
            value = value + valuePreProcessor.addition
        return value
    
    def decorateAxisLabel(self, label=None, valuePreProcessor=None):
        """
        2014.07.31
        """
        if valuePreProcessor.scalar is not None:
            label = "%s*%s"%(valuePreProcessor.scalar, label)
        if valuePreProcessor.addition:
            label = "%s+%s"%(label, valuePreProcessor.addition)
        return label
    
    def filterDataRow(self, dataRow):
        """
        2015.4.16
            unfinished
        """
        logicSplitP= re.compile(r'(AND|OR)')
        equationSplitP = re.compile(r'>=|>|=|<|<=')
        filtersText = self.entry_filters.get_text()
        logicSplitP.split(filtersText)
        
        self.dataLabelColumnIndexAndSeparatorList = splitP.split(inputText)
        self.dataLabelNumericItemIndexList = []
        for i in range(len(self.dataLabelColumnIndexAndSeparatorList)):
            if not splitP.match(self.dataLabelColumnIndexAndSeparatorList[i]):	#it's a column index
                self.dataLabelColumnIndexAndSeparatorList[i] = \
                    int(self.dataLabelColumnIndexAndSeparatorList[i])
                self.dataLabelNumericItemIndexList.append(i)

    
    def plotXY(self, ax, canvas, liststore, plot_title='', 
            chosen_index_ls=[]):
        """
        2015.01.28 add summary stats to title
        2014.04.29 add error bars
        2009-3-13
            rename plot_NA_mismatch_rate to plotXY()
        2008-02-05
            chosen_index => chosen_index_ls
        2007-12-14
        """
        x_column = int(self.entry_x_column.get_text())
        y_column = int(self.entry_y_column.get_text())
        self.setUserDataPreprocessingFlags()   
        
        plot_title = self.entry_plot_title.get_text()
        
        min_x = 1
        min_y = 1
        max_x = 0
        max_y = 0
        
        x_ls = []
        x_error_ls = []
        y_ls = []
        y_error_ls = []
        
        x_chosen_ls = []
        x_chosen_error_ls = []
        y_chosen_ls = []
        y_chosen_error_ls = []
        
        noOfValuesDiscarded = 0
        chosen_index_set = set(chosen_index_ls)
        for i in range(len(liststore)):
            row = liststore[i]
            x = row[x_column]
            y = row[y_column]
            if x=='' or y=='':
                continue
                noOfValuesDiscarded += 1
            x = self.processDataValue(x, self.xValuePreProcessor)
            if x is None:
                continue
                noOfValuesDiscarded += 1
            y = self.processDataValue(y, self.yValuePreProcessor)
            if y is None:
                continue
                noOfValuesDiscarded += 1
            #self.filterDataRow()
            if self.xValuePreProcessor.errorColumnIndex is not None:
                x_error = row[self.xValuePreProcessor.errorColumnIndex]
            else:
                x_error = 0
            if self.yValuePreProcessor.errorColumnIndex is not None:
                y_error = row[self.yValuePreProcessor.errorColumnIndex]
            else:
                y_error = 0

            if x<min_x:
                min_x = x
            if x>max_x:
                max_x = x
            if y<min_y:
                min_y = y
            if y>max_y:
                max_y = y
            
            if i in chosen_index_set:
                x_chosen_ls.append(x)
                y_chosen_ls.append(y)
                x_chosen_error_ls.append(x_error)
                y_chosen_error_ls.append(y_error)
            else:
                x_ls.append(x)
                y_ls.append(y)
                x_error_ls.append(x_error)
                y_error_ls.append(y_error)
        
        sys.stderr.write("WARNING: %s values were discarded.\n"%(noOfValuesDiscarded))
        ax.clear()
        if self.xValuePreProcessor.logScale:
            ax.set_xscale('log')
        if self.yValuePreProcessor.logScale:
            ax.set_yscale('log')
        
        #plot unselected data only if 
        if not self.checkButtonPlotOnlySelected.get_active():
            if self.x_error_column_index is not None and self.y_error_column_index is not None:
                ax.errorbar(x_ls, y_ls, xerr=x_error_ls, yerr=y_error_ls, ecolor='g', fmt='o')
            else:
                ax.plot(x_ls, y_ls, 'o', alpha=0.7, linewidth=0, linestyle="None")
        
        
        """
        #diagonal line give a rough feeling about the notion, more NA, worse calling
        diagonal_start = min(min_x, min_y)-0.1
        diagonal_end = max(max_x, max_x)+0.1
        ax.plot([diagonal_start, diagonal_end],[diagonal_start, diagonal_end])
        """
        if x_chosen_ls and y_chosen_ls:	#highlight
            titleWithStats = "Highlighted data\n" + \
                yh_matplotlib.constructTitleFromTwoDataSummaryStat(x_chosen_ls, y_chosen_ls)
            
            ax.plot(x_chosen_ls, y_chosen_ls, 'o', alpha=0.6,  c='r')
            if self.x_error_column_index is not None and self.y_error_column_index is not None:
                ax.errorbar(x_chosen_ls, y_chosen_ls, xerr=x_chosen_error_ls,
                    yerr=y_chosen_error_ls, ecolor='r', color='r', fmt='o')
        else:	#take all data
            titleWithStats = yh_matplotlib.\
                constructTitleFromTwoDataSummaryStat(x_ls+x_chosen_ls, y_ls+y_chosen_ls)
        if plot_title:
            ax.set_title("%s %s"%(plot_title, titleWithStats))
        else:
            ax.set_title(titleWithStats)
        
        xlabel = "(%s)"%self.columnHeaders[x_column]
        xlabel = self.decorateAxisLabel(xlabel, self.xValuePreProcessor)
        ax.set_xlabel(xlabel)
        ylabel = "(%s)"%self.columnHeaders[y_column]
        ylabel = self.decorateAxisLabel(ylabel, self.yValuePreProcessor)
        ax.set_ylabel(ylabel)
        canvas.draw()
    
    def plot_row(self, treeview, path, view_column):
        if self._idClick==None:
            self._idClick = self.canvas.mpl_connect('button_press_event', self.onUserClickCanvas)
        self.plotXY(self.ax, self.canvas, self.liststore, self.plot_title, path)
    
    def setupColumns(self, treeview):
        """
        2009-3-13
        """
        if not getattr(self, 'columnHeaders', None):
            sys.stderr.write("Nothing in columns yet.\n")
            return
        self.liststore = gtk.ListStore(*self.columnTypes)
        #self.add_columns(self.treeview_matrix)
        yh_gnome.create_columns(self.treeview_matrix, self.columnHeaders,
            self.columnEditableFlagList, self.liststore)
        yh_gnome.fill_treeview(self.treeview_matrix, self.liststore, self.list2D, reorderable=True)
        self.treeselection = self.treeview_matrix.get_selection()
    
    def on_button_PlotXY_clicked(self, widget, data=None):
        """
        2008-02-12
        to update the no_of_selected rows
        (have to double click a row to change a cursor if it's multiple selection)
        """
        if self._idClick==None:
            self._idClick = self.canvas.mpl_connect('button_press_event', self.onUserClickCanvas)
        pathlist_strains1 = []
        self.treeselection.selected_foreach(yh_gnome.foreach_cb, pathlist_strains1)
        index_ls = []
        for path in pathlist_strains1:
            index_ls.append(path[0])
        self.app1_appbar1.push("%s rows selected."%len(pathlist_strains1))
        self.plotXY(self.ax, self.canvas, self.liststore, self.plot_title, index_ls)
    
    def on_button_UnSelectAll_clicked(self, widget, data=None):
        """
        2015.04.16
        """
        self.treeselection = self.treeview_matrix.get_selection()
        self.treeselection.unselect_all()

        
    def on_button_save_clicked(self, widget, data=None):
        """
        2008-02-05
        """
        self.filechooserdialog_save.show_all()
    
    def on_button_filechooserdialog_cancel_ok_clicked(self, widget, data=None):
        """
        2008-02-05
        """
        self.filechooserdialog_save.hide()
    
    def on_button_filechooserdialog_save_ok_clicked(self, widget, data=None):
        """
        2008-02-12
        to update the no_of_selected rows (have to double click a row to change a cursor if it's multiple selection)
        2008-02-05
        """
        output_fname = self.filechooserdialog_save.get_filename()
        self.filechooserdialog_save.hide()
        pathlist_strains1 = []
        self.treeselection.selected_foreach(yh_gnome.foreach_cb, pathlist_strains1)
        self.app1_appbar1.push("%s rows selected."%len(pathlist_strains1))
        if self.header and self.strain_acc_list and self.category_list and self.data_matrix:
            selected_index_set = set()
            for path in pathlist_strains1:
                row = self.liststore[path[0]]
                id = row[0]
                index_in_data_matrix = row[-1]
                selected_index_set.add(index_in_data_matrix)
                if self.id_is_strain:
                    id = id[1:-1].split(',')	#id is a tuple of (ecotypeid,duplicate)
                    self.strain_acc_list[index_in_data_matrix] = id[0].strip()
                    self.category_list[index_in_data_matrix] = id[1].strip()
                #else:
                #	self.header[index_in_data_matrix+2] = id
            if self.id_is_strain:
                rows_to_be_tossed_out = set(range(len(self.strain_acc_list))) - selected_index_set
                write_data_matrix(self.data_matrix, output_fname, self.header,
                    self.strain_acc_list, self.category_list,\
                    rows_to_be_tossed_out, cols_to_be_tossed_out=set(), nt_alphabet=0)
            else:
                cols_to_be_tossed_out = set(range(len(self.header)-2)) - selected_index_set
                write_data_matrix(self.data_matrix, output_fname, self.header,
                    self.strain_acc_list, self.category_list,
                    rows_to_be_tossed_out=set(),
                    cols_to_be_tossed_out=cols_to_be_tossed_out, nt_alphabet=0)
    
    def show_all(self):
        """
        2008-02-05
            preserve the old interface. in order not to change anything in 
            plot_col_NA_mismatch_rate() and plot_row_NA_mismatch_rate() of QualityControl.py
        """
        self.app1.show_all()
    
    def on_button_PlotHistogram_clicked(self, widget, data=None):
        """
        2016.04.14 bugfix: skip "" /empty cells
        2015.01.28 add summary stats to title
        2009-5-20
            get the number of bins from entry_no_of_bins 
        2009-3-13
            draw histogram of specific hist_column
        2008-02-06
        """
        if not getattr(self, 'columnHeaders', None):
            sys.stderr.write("Nothing in columns yet.\n")
            return
        self.setUserDataPreprocessingFlags()
        
        self.ax.clear()
        self.canvas.mpl_disconnect(self._idClick)	#drop the signal handler
        self._idClick = None	#reset the _idClick
        hist_ls = []
        hist_column = int(self.entry_hist_column.get_text())
        noOfValuesDiscarded = 0
        for i in range(len(self.liststore)):
            x = self.liststore[i][hist_column]
            if x=='':	#2016.04.14 bugfix skip if empty cells  #if not x:
                noOfValuesDiscarded += 1
                continue
            x = self.processDataValue(x, self.xValuePreProcessor)
            if x is None:
                continue
                noOfValuesDiscarded += 1
            if self.xValuePreProcessor.logScale:
                if x>0:
                    x = math.log10(x)
                else:
                    sys.stderr.write("x value %s, not good for log10.\n"%(x))
                    continue
                    noOfValuesDiscarded += 1
            hist_ls.append(x)
        sys.stderr.write("WARNING: %s values were discarded.\n"%(noOfValuesDiscarded))
        
        title = "%s %s %s"%(self.plot_title, self.columnHeaders[hist_column],
                yh_matplotlib.constructTitleFromDataSummaryStat(hist_ls))
        self.ax.set_title(title);
        #"Histogram of %s %s"%(self.plot_title, self.columnHeaders[hist_column]))
        no_of_bins = int(self.entry_no_of_bins.get_text())
        
        #if self.x_logScale:
        #	self.ax.set_xscale('log')
        if self.yValuePreProcessor.logScale:
            self.ax.set_yscale('log')
        
        xlabel = "(%s)"%self.columnHeaders[hist_column]
        xlabel = self.decorateAxisLabel(xlabel, self.xValuePreProcessor)
        if self.xValuePreProcessor.logScale:
            xlabel = "log10(%s)"%(xlabel)
        self.ax.set_xlabel(xlabel)
        self.ax.hist(hist_ls, no_of_bins)
        self.canvas.draw()
    
    def update_no_of_selected(self, treeview, app1_appbar1):
        """
        2008-02-12
            to update the no_of_selected rows
            (have to double click a row to change a cursor if it's multiple selection)
        """
        pathlist_strains1 = []
        self.treeselection.selected_foreach(yh_gnome.foreach_cb, pathlist_strains1)
        app1_appbar1.push("%s rows selected."%len(pathlist_strains1))
        return True
    
    def parseDataHeader(self, dataHeaders=None):
        """
        2016.04.15 inserted a first column to denote order of data
        """
        no_of_cols = len(dataHeaders)
        self.columnHeaders = ['']*(no_of_cols+1)
        self.columnHeaders[0] = "0 Order"
        self.columnTypes = [str]*(no_of_cols+1)
        self.columnTypes[0] = int
        self.columnEditableFlagList = [False]*(no_of_cols+1)
        print("columnHeaders: ", self.columnHeaders)
        print("columnTypes: ", self.columnTypes)
        print("columnEditableFlagList: ", self.columnEditableFlagList)
        
        for i in range(no_of_cols):
            header = dataHeaders[i]
            tmp_ls = header.split('|')
            columnHeader = tmp_ls[0]
            if len(tmp_ls)>1:
                columnTypeName = tmp_ls[1]
            elif i<2:	#by default first two columns are of string type
                columnTypeName = "string"
            else:	#by default columns after first two are of numeric type
                columnTypeName = 'number'
            column_type = self.typeName2PythonType.get(columnTypeName, str)
            self.columnHeaders[i+1] = '%s %s'%(i+1, columnHeader)
            self.columnTypes[i+1] = column_type
            if column_type==str:
                self.columnEditableFlagList[i+1] = True
        print("columnHeaders: ", self.columnHeaders)
        print("columnTypes: ", self.columnTypes)
        print("columnEditableFlagList: ", self.columnEditableFlagList)
        
    
    def readInDataToPlot(self, input_fname, sampling_probability=1.0):
        """
        2016.04.15 report summary of data and inserted a first column to denote order of data
        2015.04.16 use parseDataHeader()
            convert each column data according to self.columnTypes
        2015.01.23 added argument sampling_probability to sub-sample data
        2013.07.11 use MatrixFile to read in the file
        2009-5-20
            add the column index into the column header for easy picking
        2009-3-13
            wrap the float conversion part into try...except to report what goes wrong
        2009-3-13
        """
        if sampling_probability>1 or sampling_probability<0:
            sampling_probability=1.0
        reader = MatrixFile(path=input_fname)
        self.inputDataHeaders = reader.__next__()
        print("delimiter: ", reader.delimiter)
        print("inputDataHeaders: ", self.inputDataHeaders)
        self.parseDataHeader(self.inputDataHeaders)
        
        self.list2D = []
        dimOfRawData = [0,0]
        dimOfList2D = [0,0]
        
        for row in reader:
            dimOfRawData[0] += 1
            dimOfRawData[1] = len(row)
            
            if sampling_probability>0 and sampling_probability<1:
                if random.random()>sampling_probability:	#skip
                    continue
            new_row = ['']*(len(row)+1)	#first column is the order of data
            for i in range(len(row)):
                try:
                    new_row[i+1] = self.columnTypes[i+1](row[i])
                except:
                    sys.stderr.write("Error in converting column %s data %s (row=%s) to type %s.\n"%\
                        (i, row[i], repr(row), self.columnTypes[i+1]))
                    sys.stderr.write('Except type: %s\n'%repr(sys.exc_info()))
                    traceback.print_exc()
            
            dimOfList2D[0] += 1
            dimOfList2D[1] = len(new_row)
            new_row[0] = dimOfList2D[0]	#order of this data
            self.list2D.append(new_row)
            
        reader.close()
        sys.stderr.write("Dimension of raw data: %s. Dimension of displayed data: %s."%\
            (dimOfRawData, dimOfList2D))
        self.setupColumns(self.treeview_matrix)
        #update status to reflect the input filename
        self.app1.set_title(os.path.basename(input_fname))
        self.app1_appbar1.push(input_fname)
        self.plotXY(self.ax, self.canvas, self.liststore, self.plot_title)
        
    
    def readInRawMatrixData(self, input_fname):
        """
        2009-3-13
        """
        delimiter = figureOutDelimiter(input_fname)
        self.header, self.strain_acc_list, self.category_list, \
            self.data_matrix = read_data(input_fname, delimiter=delimiter)
        
    def on_imagemenuitem_open_activate(self, widget, data=None):
        """
        2009-3-13
        """
        self.filechooserdialog_open.show_all()
    
    def on_button_fileopen_cancel_clicked(self, widget, data=None):
        """
        2015.01.23
        """
        self.filechooserdialog_open.hide()
        
    
    def on_button_fileopen_ok_clicked(self, widget, data=None):
        """
        2009-3-13
        """
        input_fname = self.filechooserdialog_open.get_filename()
        sampling_probability = float(self.entry_sampling_probability.get_text())
        self.filechooserdialog_open.hide()
        self.readInDataToPlot(input_fname, sampling_probability)
    
    def on_entry_plot_title_change(self, widget, data=None):
        """
        2009-3-13
            upon any change in the entry_plot_title
        """
        self.plot_title = self.entry_plot_title.get_text()
Example #34
0
class Graph_viewer:
    def __init__(self, graph, actions=['nothing'], callback=None):
        """
            weights : dictionary mapping name to weight
                      kmers will be colored in rank order of weight
        
        """
        
        self.graph = graph
        self.callback = callback
        
        self.window = gtk.Window()
        self.window.connect('destroy', lambda x: gtk.main_quit())
        self.window.set_default_size(800,600)
        self.window.set_title('Graph viewer')
        
        vbox = gtk.VBox()
        self.window.add(vbox)
        
        self.figure = Figure(figsize=(8,6), dpi=50)
        self.axes = self.figure.add_subplot(111)
        
        
        colors = numpy.empty((len(graph.names), 3))
        sizes = numpy.empty(len(graph.names))
        
        sizes[:] = 2.0
        
        #if weights is None:
        #    #self.axes.plot(graph.positions[:,0], graph.positions[:,1], ',')
        #    
        #    colors[:,:] = [[0.0,0.0,0.0]] 
        #
        #else:
        
        #names = weights.keys()
        #values = weights.values()
        ##names.sort(key=lambda x: weights[x])
        #idents = numpy.array([ graph.name_to_ident[name] for name in names ])
        
        #x = numpy.array(values, dtype='float64')
        x = numpy.array(graph.weights, dtype='float64')
        
        x = numpy.log(x)
        
        x -= numpy.minimum.reduce(x)
        x /= numpy.average(x) * 2.0
        #x /= numpy.sum(x*x)*2.0/numpy.sum(x)
        
        xx = numpy.minimum(x,1.0)
        #x = numpy.arange(len(graph.names)) / float(len(graph.names))
        
        colors[:,0] = 0.5-xx*0.5
        colors[:,1] = 0.75-xx*0.5
        colors[:,2] = 1.0-xx*0.5
        
        sizes[:] = numpy.maximum(x,1.0)**2 #*2.0
            
            #n = 20
            #for i in xrange(n):
            #    start = i*len(names)//n
            #    end = (i+1)*len(names)//n
            #    if start == end: continue
            #    
            #    x = (1.0-float(i)/(n-1)) 
            #    position_block = graph.positions[idents[start:end]]
            #    self.axes.scatter(position_block[:,0],
            #               position_block[:,1],
            #               linewidths=0, 
            #               marker='s',
            #               s=10.0,
            #               c=(0.0,x,x*0.5+0.5),
            #               zorder=i)

        dots = Dots(graph.positions[:,1], graph.positions[:,0], colors, sizes)
        self.axes.add_artist(dots)
        
        #if len(graph.links) < 1000:
        #    for i, (other, other_sign, other_travel) in enumerate(graph.links):
        #        for j in other:
        #            if j > i:
        #                self.axes.plot([graph.positions[i,0],graph.positions[j,0]],
        #                           [graph.positions[i,1],graph.positions[j,1]],
        #                           'k-') 
        
        self.axes.axis('scaled')
        self.axes.set_xlim(0.0, numpy.maximum.reduce(graph.positions[:,0]) * 1.1)
        self.axes.set_ylim(0.0, numpy.maximum.reduce(graph.positions[:,1]) * 1.1)
        
        self.figure.subplots_adjust(top=0.99,bottom=0.05,right=0.99,left=0.05)
        
        #pylab.connect('button_press_event', self._on_click) 
        
        self.annotation_pylab = [ ]
        self.clear_annotation()


        self.canvas = FigureCanvas(self.figure)  # a gtk.DrawingArea
        self.canvas.mpl_connect('button_press_event', self._on_down)
        self.canvas.mpl_connect('button_release_event', self._on_up)
        
        vbox.pack_start(self.canvas)
        
        hbox = gtk.HBox()
        vbox.pack_start(hbox, False, False, 10)
        
        label = gtk.Label('Middle click:')
        hbox.pack_start(label, False, False, 5)
        
        self.radios = { }
        last = None
        for action in actions:
            radio = gtk.RadioButton(group=last, label=action)
            last = radio
            self.radios[action] = radio
            hbox.pack_start(radio, False, False, 5)

        label = gtk.Label('Right click: clear')
        hbox.pack_end(label, False, False, 5)
            
        self.radios[actions[0]].set_active(True)


        toolbar = NavigationToolbar(self.canvas, self.window)
        vbox.pack_start(toolbar, False, False)
        
    def run(self):     
        self.window.show_all()
        gtk.main()        

    def clear_annotation(self):
        self.annotation = { }
      
    def label(self, name, label):
        ident = self.graph.name_to_ident[name]
        self.axes.text(
            self.graph.positions[ident,0],
            self.graph.positions[ident,1],
            label,
            horizontalalignment='center',
            verticalalignment='bottom',
            zorder=100000)

    def arrow(self, names, label):
        positions = [ self.graph.positions[self.graph.name_to_ident[name]] 
                      for name in names if self.graph.has(name) ]
        
        if not positions: return #Error?
        
        max_positions = max(4, (len(positions)+29)//30) #20
        if len(positions) > max_positions:
            positions = [ positions[i*(len(positions)-1)//(max_positions-1)] for i in xrange(max_positions) ]
                
        arrow = Arrow(positions, label, True)
        
        #names = [ name for name in names if self.graph.has(name) ]
        #
        #if len(names) < 2: return #Error?
        #
        #ident1 = self.graph.name_to_ident[names[0]]
        #ident2 = self.graph.name_to_ident[names[-1]]
        #
        #arrow = Arrow(self.graph.positions[ident1],
        #              self.graph.positions[ident2],
        #              label,
        #              True)
        self.axes.add_artist(arrow)                            
        
    def annotate(self, name, mass,r,g,b):
        r *= mass
        g *= mass
        b *= mass
        old_mass, old_r, old_g, old_b = self.annotation.get(name,(0.0,0.0,0.0,0.0))
        self.annotation[name] = (old_mass+mass,old_r+r,old_g+g,old_b+b)

    def refresh_annotation(self):
        while self.annotation_pylab:
            item = self.annotation_pylab.pop(-1)
            item.remove()

        xs = [ ]
        ys = [ ]
        colors = [ ]
        sizes = [ ]
        for name in self.annotation:
            mass,r,g,b = self.annotation[name]
            if not mass: continue
            
            ident = self.graph.name_to_ident[name]
            xs.append(self.graph.positions[ident,0])
            ys.append(self.graph.positions[ident,1])
            colors.append((r/mass,g/mass,b/mass))
            sizes.append(mass)
        
        if xs:
            #thing = self.axes.scatter(
            #    xs,
            #    ys,
            #    s=sizes,
            #    c=colors, 
            #    linewidths=0, 
            #    marker='s',
            #    zorder=10000)
            thing = Dots(numpy.array(ys), numpy.array(xs), numpy.array(colors), numpy.array(sizes), zorder=2)            
            self.axes.add_artist(thing)
            self.annotation_pylab.append(thing)
        
        self.canvas.draw()
    
    def name_from_position(self, x,y):
        xoff = self.graph.positions[:,0] - x
        yoff = self.graph.positions[:,1] - y
        dist2 = xoff*xoff+yoff*yoff
        best = numpy.argmin(dist2)
        
        return self.graph.names[best]
    
    def _on_down(self, event):
        self.down_name = self.name_from_position(event.xdata, event.ydata)
    
    def _on_up(self, event):
        if event.inaxes and event.button == 3:
            self.clear_annotation()
            self.refresh_annotation()
            
        elif event.inaxes and event.button == 2:
            name = self.name_from_position(event.xdata, event.ydata)
            
            if self.callback:
                action = None
                for item in self.radios:
                    if self.radios[item].get_active():
                        action = item

                self.callback(self, action, self.down_name, name)
                self.refresh_annotation()
            
            del self.down_name