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

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