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

Last change on this file since 466 was 466, checked in by ajj, 14 years ago

Add Clear Plot button and reload data when plot is checked so that current data can be updated.

Also apparently adding test data

  • Property svn:executable set to *
File size: 11.5 KB
Line 
1#!/usr/bin/env python
2
3import sys
4import os
5import matplotlib
6import numpy
7matplotlib.use('GTK')
8
9from matplotlib.figure import Figure
10from matplotlib.axes import Subplot
11from matplotlib.backends.backend_gtk import FigureCanvasGTK, NavigationToolbar
12
13import usans
14
15try:
16    import pygtk
17    pygtk.require("2.0")
18   
19except:
20    pass
21
22try:
23    import gtk
24    import gtk.glade
25except:
26    sys.exit(1)
27
28
29
30class appGui:
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)
39
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,
45                     "on_plot_type_activate" : self.handle_plot_type_change,
46                     "on_btn_ClearPlot_clicked" : self.handle_clearplot}
47    #                 "on_tv_plotlist_key_press_event" : self.handle_plotlist_keypress}
48
49        #This is a bit clunky, but never mind.
50        #Set default plottype to rate. Glade definition sets that as default active button in menu
51        self.plottype = 'rate'
52       
53        self.wTree.signal_autoconnect(event_dic)
54
55        # Set up file list
56        self.filelistview = self.wTree.get_widget("tv_filelist")
57       
58        self.filelist = gtk.ListStore(str, 'gboolean', object, object, object)
59        self.filelist.set_sort_column_id(0, gtk.SORT_ASCENDING)
60        self.filelistview.set_model(self.filelist)
61
62        self.cellrenderertoggle = gtk.CellRendererToggle()
63        self.cellrenderertoggle.set_property('activatable', True)
64        self.cellrenderertoggle.connect("toggled", self.handle_plot_toggle, self.filelist)
65   
66        self.AddFileListColumns()
67
68        #fill the file list
69        self.FillFileList(self.GetDirList())
70
71        # Set up graphing widget to display xpeek data
72        self.figure = Figure(figsize=(4, 4), dpi=72)
73        self.axis = self.figure.add_subplot(111)
74        self.axis.set_yscale('log')
75        self.axis.set_aspect('auto')
76        self.axis.set_autoscale_on('True')
77        self.axis.set_xlabel('Motor position')
78        self.axis.set_ylabel('Counts')
79        self.axis.grid(True)
80       
81        self.canvas = FigureCanvasGTK(self.figure)
82        self.figure.canvas.mpl_connect('pick_event',self.handle_plot_click)
83        self.canvas.show()
84       
85        self.plotView = self.wTree.get_widget("vbox4")
86        self.plotView.pack_start(self.canvas, True, True)   
87       
88        self.metadataView = self.wTree.get_widget("tv_metadata")
89        self.mdlist = gtk.ListStore(str,str)
90       
91       
92        #self.filelistview.enable_model_drag_source( gtk.gdk.BUTTON1_MASK,
93                #                                  self.TARGETS,
94                #                                   gtk.gdk.ACTION_COPY)
95
96        #self.filelistview.connect("drag_data_get", self.dnd_data_getdata)
97       
98       
99    def AddFileListColumns(self):
100        """This function adds a column to the list view.
101        First it create the gtk.TreeViewColumn and then set
102        some needed properties"""
103                       
104        column = gtk.TreeViewColumn('Filename', gtk.CellRendererText()
105            , text=0)
106        column.set_resizable(True)       
107        column.set_sort_column_id(0)
108        self.filelistview.append_column(column)
109
110        column = gtk.TreeViewColumn('', self.cellrenderertoggle, active=1)
111        self.filelistview.append_column(column)
112        return
113       
114    def GetDirList(self):
115        dirlist = os.listdir(os.getcwd())
116       
117        bt5list = [ x for x in dirlist if x.find('.bt5') > 0]
118       
119        return bt5list
120       
121   
122    def FillFileList(self, filenames):
123        self.filelist.clear()
124        for filename in filenames:
125            if usans.isBT5Data(filename):
126                self.filelist.append([filename, 0, 0, 0, 0])
127        return
128           
129    def RefreshFileList(self):
130       
131        for path in self.filelist:
132            print self.filelist[path][0]
133
134    def setdatadir(self, widget):
135        chooser = gtk.FileChooserDialog(title="Select Data Directory", action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
136                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
137        chooser.set_default_response(gtk.RESPONSE_OK)
138        chooser.set_current_folder(os.getcwd())
139        response = chooser.run()
140        if response == gtk.RESPONSE_OK:
141            os.chdir(chooser.get_filename())
142            self.FillFileList(self.GetDirList())
143        chooser.destroy()
144
145    def handle_plot_toggle(self, cell, path, model):
146        model[path][1] = not model[path][1]
147
148        if model[path][1]:
149            #load data
150            data,metadata = usans.getBT5DataFromFile(model[path][0])
151            model[path][2] = (data,metadata)
152            #add plot
153            self.add_plot(model, path)
154        else:
155            #remove plot
156            self.remove_plot(model, path)
157        return
158
159    def add_plot(self, model, path):
160       
161        self.make_plottable_dataset(model, path, self.plottype)
162
163        if self.plottype == 'split':
164                model[path][4] = self.axis.plot(model[path][3][0],model[path][3][1], 'o',
165                                                                                         model[path][3][0],model[path][3][2], 'o',
166                                                                                         model[path][3][0],model[path][3][3], 'o',
167                                                                                         model[path][3][0],model[path][3][4], 'o',
168                                                                                         model[path][3][0],model[path][3][5], 'o')
169        else:
170            model[path][4] = self.axis.plot(model[path][3][0],model[path][3][1], 'bo', picker=5)
171       
172        self.rescale_and_redraw()
173        #self.canvas.draw()
174        return
175
176    def make_plottable_dataset(self, model, path, type):
177         
178         data,metadata = model[path][2]
179                 
180         if type == 'total':
181             #generate totals
182             xdata = []
183             ydata = []     
184             
185             mvals = data.keys()
186             mvals.sort(usans.numeric_compare)
187             for mval in mvals:
188                 xdata.append(mval)
189                 ydata.append(data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6])
190             
191             model[path][3] = [xdata, ydata]
192             
193         elif type == 'rate':
194             # generate countrate
195             xdata = []
196             ydata = []
197             
198             mvals = data.keys()
199             mvals.sort(usans.numeric_compare)
200             for mval in mvals:
201                 xdata.append(mval)
202             
203             if metadata['base'] == 'TIME':
204                #Counting in TIME base, so normalize by seconds
205                cnttime = metadata['mon']
206                for mval in mvals:
207                     ydata.append((data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6])/cnttime)
208             else:
209                #Must be counting in monitor base so normalize by monitor
210                moncts = metadata['mon']
211                for mval in mvals:
212                    ydata.append((data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6])/cnttime)
213             
214             model[path][3] = [xdata, ydata]
215             
216         elif type == 'trans':
217             xdata = []
218             ydata = []
219             
220             mvals = data.keys()
221             mvals.sort(usans.numeric_compare)
222             for mval in mvals:
223                 xdata.append(mval)
224                 ydata.append(data[mval][3])
225             
226             model[path][3] = [xdata, ydata]             
227         
228         elif type == 'mon':
229             xdata = []
230             ydata = []
231             
232             mvals = data.keys()
233             mvals.sort(usans.numeric_compare)
234             for mval in mvals:
235                 xdata.append(mval)
236                 ydata.append(data[mval][0])
237             
238             model[path][3] = [xdata, ydata]             
239             
240         elif type == 'split':
241             xdata = []
242             ydata1 = []
243             ydata2 = []
244             ydata3 = []
245             ydata4 = []
246             ydata5 = []
247             
248             mvals = data.keys()
249             mvals.sort(usans.numeric_compare)
250             for mval in mvals:
251                 xdata.append(mval)
252                 ydata1.append(data[mval][1])   
253                 ydata2.append(data[mval][2])   
254                 ydata3.append(data[mval][4])   
255                 ydata4.append(data[mval][5])   
256                 ydata5.append(data[mval][6])   
257
258             model[path][3] = [xdata,ydata1,ydata2,ydata3,ydata4,ydata5]
259         else:
260                pass
261             
262         return
263
264    def remove_plot(self, model, path):
265
266        for line in model[path][4]:
267                self.axis.lines.remove(line)
268       
269        if (len(self.axis.lines) > 0):
270                self.rescale_and_redraw()
271        else:
272            self.canvas.draw() 
273
274        return
275
276    def handle_xaxis_loglin(self, widget):
277
278
279        if (self.axis.get_xscale() == "log"):
280            self.axis.set_xscale('linear')
281        else:
282            self.axis.set_xscale('log')       
283
284
285        self.rescale_and_redraw()
286       
287        return   
288
289    def handle_yaxis_loglin(self, widget):
290
291
292        if (self.axis.get_yscale() == "log"):
293            self.axis.set_yscale('linear')
294        else:
295            self.axis.set_yscale('log')       
296
297        self.canvas.draw()
298        return
299       
300    def handle_plot_type_change(self,widget):
301               
302        if widget.get_active():
303                self.plottype = widget.get_name().split('_')[1]
304                #print self.plottype
305               
306        return
307       
308    def handle_clearplot(self,widget):
309   
310        model = self.filelistview.get_model()
311        iter = model.iter_children(None)
312        while iter:
313            path = model.get_path(iter)
314            if model[path][1] != 0:
315                for line in model[path][4]:
316                    self.axis.lines.remove(line)   
317                    model[path][1] = not model[path][1]         
318            iter = model.iter_next(iter)
319       
320        self.canvas.draw()
321        return 
322       
323    def rescale_and_redraw(self):
324
325        xdata = []
326        ydata = []
327
328        for line in self.axis.lines:
329                if self.axis.get_xscale() == 'log':
330                        xdata.extend([xval for xval in line.get_xdata() if xval > 0])
331                else:
332                        xdata.extend(line.get_xdata())
333                if self.axis.get_yscale() == 'log':
334                        ydata.extend([xval for xval in line.get_ydata() if xval > 0])
335                else:
336                        ydata.extend(line.get_ydata())
337     
338        #set limits
339        xmin = float(min(xdata))
340        xmax = float(max(xdata))
341        ymin = float(min(ydata))
342        ymax = float(max(ydata))       
343
344        #adjust for size of markers (sort of)
345        xmin = xmin - 0.1*abs(xmin)
346        xmax = xmax + 0.1*abs(xmax)
347        ymin = ymin - 0.1*abs(ymin)
348        ymax = ymax + 0.1*abs(ymax)
349               
350        self.axis.set_xlim(xmin,xmax)
351        self.axis.set_ylim(ymin,ymax)
352       
353        #self.axis.autoscale_view()
354        self.canvas.draw()
355
356        return
357
358    def handle_plot_click(self,event):
359        if isinstance(event.artist, matplotlib.lines.Line2D):
360            pickedline = event.artist
361            xdata = pickedline.get_xdata()
362            ydata = pickedline.get_ydata()
363            ind = event.ind
364            print 'Plot Click: ',zip(numpy.take(xdata,ind), numpy.take(ydata,ind))
365
366app = appGui()
367gtk.main()
Note: See TracBrowser for help on using the repository browser.