source: sans/utils/bt5/bt5plot2/bt5plot2 @ 657

Last change on this file since 657 was 657, checked in by ajj, 13 years ago

some changes

  • Property svn:executable set to *
File size: 11.7 KB
RevLine 
[471]1#!/usr/bin/env python
[439]2
3import sys
4import os
[469]5import re
[439]6import matplotlib
[462]7import numpy
[439]8matplotlib.use('GTK')
9
10from matplotlib.figure import Figure
11from matplotlib.axes import Subplot
12from matplotlib.backends.backend_gtk import FigureCanvasGTK, NavigationToolbar
13
14import usans
[471]15from BT5DataSet import BT5DataSet
[439]16
17try:
[441]18    import pygtk
19    pygtk.require("2.0")
20   
[439]21except:
[441]22    pass
[439]23
24try:
[441]25    import gtk
26    import gtk.glade
[439]27except:
[441]28    sys.exit(1)
[439]29
30class appGui:
[441]31   
32    TARGETS = [('STRING', gtk.TARGET_SAME_APP, 0)]
33   
34    def __init__(self):
35       
36        gladefile = "bt5plot2.glade"
37        self.windowname = "win_Main"
38        self.wTree = gtk.glade.XML(gladefile, self.windowname)
[439]39
[441]40        event_dic = {"on_win_Main_destroy" : gtk.main_quit,
41                     "on_quit1_activate" : gtk.main_quit,
42                     "on_set_data_dir1_activate" : self.setdatadir,
43                     "on_xaxis_loglin_activate" : self.handle_xaxis_loglin,
44                     "on_yaxis_loglin_activate" : self.handle_yaxis_loglin,
[580]45                     "on_yaxis_errorbars_activate" : self.handle_yaxis_errorbars,
[466]46                     "on_plot_type_activate" : self.handle_plot_type_change,
[468]47                     "on_btn_ClearPlot_clicked" : self.handle_clearplot,
[469]48                     "on_btn_Refresh_clicked" : self.handle_refreshlist,
49                     "on_btn_Filter_clicked" : self.handle_filter}
[441]50    #                 "on_tv_plotlist_key_press_event" : self.handle_plotlist_keypress}
[439]51
[441]52        #This is a bit clunky, but never mind.
53        #Set default plottype to rate. Glade definition sets that as default active button in menu
54        self.plottype = 'rate'
[580]55        self.yerrorbars = True
[441]56       
57        self.wTree.signal_autoconnect(event_dic)
[439]58
[441]59        # Set up file list
60        self.filelistview = self.wTree.get_widget("tv_filelist")
61       
[471]62        self.filelist = gtk.ListStore(str, 'gboolean', object)
[441]63        self.filelist.set_sort_column_id(0, gtk.SORT_ASCENDING)
[439]64
[469]65        # Set up filtering of file list
66        self.filter_entry = self.wTree.get_widget("ent_filter")
67        self.filter_string = []
68        self.filter_string.append(self.filter_entry.get_text())
69        self.filelistfilter = self.filelist.filter_new()
[580]70        self.filelistfilter.set_visible_func(self.filter_filelist, self.filter_string)
[469]71
72        self.filelistview.set_model(self.filelistfilter)
73
[441]74        self.cellrenderertoggle = gtk.CellRendererToggle()
75        self.cellrenderertoggle.set_property('activatable', True)
[469]76        self.cellrenderertoggle.connect("toggled", self.handle_plot_toggle, self.filelistfilter)
[441]77   
78        self.AddFileListColumns()
[439]79
[441]80        #fill the file list
[478]81        if (len(sys.argv) > 1):
82                os.chdir(sys.argv[1])
[471]83        self.FillFileList(usans.GetBT5DirList())
[439]84
[653]85        # Set up graphing widget to display data
[441]86        self.figure = Figure(figsize=(4, 4), dpi=72)
87        self.axis = self.figure.add_subplot(111)
88        self.axis.set_yscale('log')
89        self.axis.set_aspect('auto')
90        self.axis.set_autoscale_on('True')
91        self.axis.set_xlabel('Motor position')
92        self.axis.set_ylabel('Counts')
93        self.axis.grid(True)
94       
95        self.canvas = FigureCanvasGTK(self.figure)
[580]96        self.figure.canvas.mpl_connect('pick_event', self.handle_plot_click)
[441]97        self.canvas.show()
98       
[464]99        self.plotView = self.wTree.get_widget("vbox4")
[441]100        self.plotView.pack_start(self.canvas, True, True)   
101       
[447]102        self.metadataView = self.wTree.get_widget("tv_metadata")
[580]103        self.mdlist = gtk.ListStore(str, str)
[447]104       
[441]105       
106    def AddFileListColumns(self):
107        """This function adds a column to the list view.
108        First it create the gtk.TreeViewColumn and then set
109        some needed properties"""
110                       
[469]111        column = gtk.TreeViewColumn('Filename', gtk.CellRendererText(), text=0)
[441]112        column.set_resizable(True)       
113        column.set_sort_column_id(0)
114        self.filelistview.append_column(column)
[439]115
[441]116        column = gtk.TreeViewColumn('', self.cellrenderertoggle, active=1)
117        self.filelistview.append_column(column)
118        return
119       
120   
121    def FillFileList(self, filenames):
122        self.filelist.clear()
123        for filename in filenames:
[471]124                self.filelist.append([filename, 0, None])
[441]125        return
126           
[580]127    def RefreshFileList(self, filenames):       
[469]128        #print len(filenames)
[464]129       
[469]130        deletelist = []
[514]131        tempstr = self.filter_entry.get_text()
132        del self.filter_string[:]
133        self.filter_string.append("")
134        self.filelistfilter.refilter()
[469]135       
136        treestore = self.filelistview.get_model()
[580]137        treestore.foreach(self.filelist_match_filename, (filenames, deletelist))
[469]138         
139        for filename in filenames:
[471]140            self.filelist.append([filename, 0, None])
[469]141       
142        deletelist.reverse()
143        for path in deletelist:
144            treestore.remove(treestore.get_iter(path))
[514]145
146        del self.filter_string[:]
147        self.filter_string.append(tempstr)
148        self.filelistfilter.refilter()
[469]149        return
[439]150
[469]151    def filelist_match_filename(self, model, path, iter, data):
152       
[580]153        mval = model.get_value(iter, 0)
[469]154       
155        if mval in data[0]:
156            del data[0][data[0].index(mval)]
157        else:
158            data[1].append(path)
159           
160        return False
161   
[580]162    def handle_refreshlist(self, widget):
[469]163
[471]164        self.RefreshFileList(usans.GetBT5DirList())
[469]165       
166        return
167
168    def filter_filelist(self, model, iter, data):
169       
[580]170        if model.get_value(iter, 0):       
171            match = re.match(data[0], model.get_value(iter, 0))
[469]172        else:
173            match = None
174       
175        if match is None:
176            return False
177        else:
178            return True
179       
[580]180    def handle_filter(self, widget):
[469]181       
182        del self.filter_string[:]
183        self.filter_string.append(self.filter_entry.get_text())
[471]184        #print self.filter_string[0]
[469]185        self.filelistfilter.refilter()
186       
187        return
188
[441]189    def setdatadir(self, widget):
[469]190       
191        #Clear plot before selecting new folder
192        #This is a bit clunky, but it avoids a lot of pain for the moment
193       
194        self.clearplot()
195       
[441]196        chooser = gtk.FileChooserDialog(title="Select Data Directory", action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
197                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
198        chooser.set_default_response(gtk.RESPONSE_OK)
199        chooser.set_current_folder(os.getcwd())
200        response = chooser.run()
201        if response == gtk.RESPONSE_OK:
202            os.chdir(chooser.get_filename())
[471]203            self.FillFileList(usans.GetBT5DirList())
[441]204        chooser.destroy()
[439]205
[469]206    def handle_plot_toggle(self, filter_cell, filter_path, filter_model):
207        model = filter_model.get_model()
208        path = filter_model.convert_path_to_child_path(filter_path)
[441]209        model[path][1] = not model[path][1]
[439]210
[441]211        if model[path][1]:
[466]212            #load data
[471]213            model[path][2] = BT5DataSet(model[path][0])
[441]214            #add plot
[580]215            model[path][2].plot_dataset(self.axis, self.plottype, self.yerrorbars)
[471]216            self.rescale_and_redraw()
[441]217        else:
218            #remove plot
[471]219            model[path][2].remove_plot()
220            self.rescale_and_redraw()
[441]221        return
[439]222
[469]223 
[441]224    def handle_xaxis_loglin(self, widget):
[439]225
226
[441]227        if (self.axis.get_xscale() == "log"):
228            self.axis.set_xscale('linear')
229        else:
[657]230            self.axis.set_xscale('log',nonposx='mask', nonposy='mask')       
[439]231
232
[442]233        self.rescale_and_redraw()
[441]234       
235        return   
[439]236
[441]237    def handle_yaxis_loglin(self, widget):
[439]238
239
[441]240        if (self.axis.get_yscale() == "log"):
241            self.axis.set_yscale('linear')
242        else:
[657]243            self.axis.set_yscale('log',nonposx='mask', nonposy='mask')       
[439]244
[479]245        self.rescale_and_redraw()
[441]246        return
[580]247 
248    def handle_yaxis_errorbars(self, widget):
249       
250        if (self.yerrorbars == True):
251            self.yerrorbars = False
252        else:
253            self.yerrorbars = True
254
255        model = self.filelistview.get_model().get_model()
256        iter = model.iter_children(None)
257        while iter:
258            path = model.get_path(iter)
259            if model[path][1] != 0:
260                model[path][2].remove_plot()
261                model[path][2].plot_dataset(self.axis, self.plottype, self.yerrorbars)
262            iter = model.iter_next(iter)
263
264        self.rescale_and_redraw()
265        return
[441]266       
[580]267    def handle_plot_type_change(self, widget):
[441]268               
269        if widget.get_active():
270                self.plottype = widget.get_name().split('_')[1]
[479]271
[580]272        model = self.filelistview.get_model().get_model()
[479]273        iter = model.iter_children(None)
274        while iter:
275            path = model.get_path(iter)
276            if model[path][1] != 0:
277                model[path][2].remove_plot()
[580]278                model[path][2].plot_dataset(self.axis, self.plottype, self.yerrorbars)
[479]279            iter = model.iter_next(iter)
280
[580]281        self.rescale_and_redraw()
[441]282               
283        return
284       
[580]285    def handle_clearplot(self, widget):
[469]286       
287        self.clearplot()
288       
289        return
290       
[466]291   
[469]292    def clearplot(self):
293        model = self.filelistview.get_model().get_model()
[466]294        iter = model.iter_children(None)
295        while iter:
296            path = model.get_path(iter)
297            if model[path][1] != 0:
[471]298                model[path][2].remove_plot()
[580]299                model[path][1] = not model[path][1]
[466]300            iter = model.iter_next(iter)
301       
302        self.canvas.draw()
303        return 
304       
[442]305    def rescale_and_redraw(self):
[441]306
[442]307        xdata = []
308        ydata = []
309
[471]310        if len(self.axis.lines) > 0:
[442]311
[471]312            for line in self.axis.lines:
313                if self.axis.get_xscale() == 'log':
314                        xdata.extend([xval for xval in line.get_xdata() if xval > 0])
315                else:
316                        xdata.extend(line.get_xdata())
317                if self.axis.get_yscale() == 'log':
318                        ydata.extend([xval for xval in line.get_ydata() if xval > 0])
319                else:
320                        ydata.extend(line.get_ydata())
321         
322            #set limits
323            xmin = float(min(xdata))
324            xmax = float(max(xdata))
325            ymin = float(min(ydata))
326            ymax = float(max(ydata))   
327   
328            #adjust for size of markers (sort of)
[580]329            xmin = xmin - 0.1 * abs(xmin)
330            xmax = xmax + 0.1 * abs(xmax)
331            ymin = ymin - 0.1 * abs(ymin)
332            ymax = ymax + 0.1 * abs(ymax)
[471]333                   
[580]334            self.axis.set_xlim(xmin, xmax)
335            self.axis.set_ylim(ymin, ymax)
[442]336       
[443]337        #self.axis.autoscale_view()
[442]338        self.canvas.draw()
339
340        return
341
[580]342    def handle_plot_click(self, event):
[471]343
[655]344        if event.mouseevent.button == 1:
345            """ Report data about point """
346            model = self.filelistview.get_model().get_model()
347            iter = model.iter_children(None)
348   
349   
350            if isinstance(event.artist, matplotlib.lines.Line2D):
351                #print "Clicked..."
352                pickedline = event.artist
353                ind = event.ind
354                xdata = pickedline.get_xdata()
355   
356                while iter:
357                    path = model.get_path(iter)
358                    if model[path][1] != 0:
359                        for line in model[path][2].plot:
360                            if line == pickedline:
361                                model[path][2].calcAlignVals(xdata[ind])
362                                label = self.wTree.get_widget("lbl_alignvals")
363                                label.set_text(model[path][2].alignvalstring)
364                                break
365                    iter = model.iter_next(iter)
366        elif event.mouseevent.button == 3:
367            """ Do fit stuff """
[657]368            #print "Right button pressed"
[471]369           
370
[439]371app = appGui()
372gtk.main()
Note: See TracBrowser for help on using the repository browser.