Exemplo n.º 1
0
class VisualizerWindow:
    root = []
    dataMgr = []
    
    #graphs
    fig = []
    ax1 = []
    ax2 = []
    ax3 = []
    ax4 = []
    
    ylim_ax1 = []
    ylim_ax2 = []
    ylim_ax3 = []
    
    #data
    x = []
    usage_manual = []   
    
    #debug
    show_debug_msg = False
    
    #autosave (-1 for disable)
    autosave_period = 30
    load_autosave_file = False

    
    def __init__(self, filename):        
        self.root = Tk.Tk()
        self.root.wm_title("EMG-Visualization-Tool")
        self.root.protocol("WM_DELETE_WINDOW", self._quit)
     
        if not filename:
             filename = askopenfilename()
             if not filename:
                 sys.exit(0)
    
        while not os.path.isfile(filename):
             showerror("File not found", "Sorry, file '{}' was not found, try again".format(filename))
             filename = askopenfilename()
             if not filename:
                 sys.exit(0)
        
        if filename[-19:] == '_usage_autosave.pkl':
            self.autosave_file = filename
            print('Input file is an Auto-Save file "{}"'.format(self.autosave_file))
            filename = filename[:-19] + '.csv'
            if not os.path.isfile(filename):
                showerror('Could not find file "{}" (matching to provided auto-save file "{}")'.format(filename, self.autosave_file))
                print('Error: matching file not found (expected "{}")'.format(filename))
                print('EXIT')
                sys.exit(0)
            else:
                self.load_autosave_file = True
        else:
            self.autosave_file = filename.rsplit(".", 1)[0] + "_usage_autosave.pkl"
            if os.path.isfile(self.autosave_file):
                print('Auto-Save file "{}" already exists'.format(self.autosave_file))
                if askyesno('Auto-Save file found', 'Auto-Save file "{}" found. Load it instead? ("No" will result in automatical overwriting of the file when auto-saving)'.format(self.autosave_file)):
                    self.load_autosave_file = True
        
        
        self.root.wm_title("EMG-Visualization-Tool: {}".format(filename))
        self.dataMgr = DataManager(filename)
                
        
        self.csv_out_file = filename.rsplit(".", 1)[0] + "_usage.csv"
        
        while os.path.isfile(self.csv_out_file):
            print('File "{}" already exists'.format(self.csv_out_file))
            if askyesno('Overwrite File?', 'File "{}" already exists. Overwrite?'.format(self.csv_out_file)):
                print('overwriting "{}"'.format(self.csv_out_file))
                break
            else:
                new_out_file = asksaveasfilename(initialfile=self.csv_out_file)
                if new_out_file:
                    self.csv_out_file = new_out_file
                    print('New Output file "{}"'.format(self.csv_out_file))
                else:
                    sys.exit(0)
                    
        print("csv-out-file: {}".format(self.csv_out_file))
        
        self.configFrame = Tk.Frame(self.root, height=500, width=400)

        Tk.Label(self.configFrame, text="\r\nPlot 1").pack()
        self.plot1_select = ttk.Combobox(self.configFrame, values=self.dataMgr.plot_columns, state="readonly")
        self.plot1_select.pack()
        
        if '"f"' in self.dataMgr.plot_columns:
            self.plot1_select.current(self.dataMgr.plot_columns.index('"f"'))
        else:
            self.plot1_select.current(0)
        

        Tk.Label(self.configFrame, text="Plot 2").pack()
        self.plot2_select = ttk.Combobox(self.configFrame, values=self.dataMgr.plot_columns, state="readonly")
        self.plot2_select.pack()

        if '"rmsd"' in self.dataMgr.plot_columns:
            self.plot2_select.current(self.dataMgr.plot_columns.index('"rmsd"'))
        else:
            self.plot2_select.current(0)

        
        Tk.Label(self.configFrame, text="Plot 3").pack()
        self.plot3_select = ttk.Combobox(self.configFrame, values=self.dataMgr.plot_columns, state="readonly")
        self.plot3_select.pack()

        if '"beat"' in self.dataMgr.plot_columns:
            self.plot3_select.current(self.dataMgr.plot_columns.index('"beat"'))
        else:
            self.plot3_select.current(0)
        
        
        Tk.Label(self.configFrame, text="\r\nUsage Plot").pack()

        self.usage_plots = {}

        for usg in self.dataMgr.usage_columns:
            if not usg == '"usage_manual"':
                chkbx_var = Tk.IntVar()
                chkbx_var.set(1)
                usg_check = ttk.Checkbutton(self.configFrame, text=usg, variable=chkbx_var)
                usg_check.pack()
                self.usage_plots[usg] = chkbx_var

        Tk.Label(self.configFrame, text="\r\nLoad/copy \"usage_manual\" from").pack()
        if self.load_autosave_file:
            Tk.Label(self.configFrame, text="provided Auto-Save file").pack()
        else:
            self.usg_man_select = ttk.Combobox(self.configFrame, values=self.dataMgr.usage_columns, state="readonly")
            self.usg_man_select.pack()
            
            if '"usage_manual"' in self.dataMgr.usage_columns:
                self.usg_man_select.current(self.dataMgr.usage_columns.index('"usage_manual"'))
            elif '"usage_total"' in self.dataMgr.usage_columns:
                self.usg_man_select.current(self.dataMgr.usage_columns.index('"usage_total"'))
            else:
                if len(self.dataMgr.usage_columns) > 0:
                    self.usg_man_select.current(0)


        Tk.Label(self.configFrame, text="\r\nJump Column").pack()

        if len(self.dataMgr.jump_columns) == 0:
            self.jmp_select = ttk.Combobox(self.configFrame, values=['--none--'], state="readonly")
            self.jmp_select.current(0)
        else: 
            self.jmp_select = ttk.Combobox(self.configFrame, values=self.dataMgr.jump_columns, state="readonly")
            if '"jump_ibi"' in self.dataMgr.jump_columns:
                self.jmp_select.current(self.dataMgr.jump_columns.index('"jump_ibi"'))
            else:
                self.jmp_select.current(0)        
        self.jmp_select.pack()

        
        Tk.Label(self.configFrame, text="").pack()

        button_continue = Tk.Button(self.configFrame, text='Continue', command=self._CfgContinue)
        button_continue.pack()
        
        Tk.Label(self.configFrame, text="").pack()
        self.loading_label = Tk.Label(self.configFrame, text="")
        self.loading_label.pack()
        
        self.configFrame.pack()

        self.visualizerFrame = Tk.Frame(self.root)
        
        
        # Figure with Subplots
        self.fig = plt.figure(figsize=(17,8), dpi=80, tight_layout=True)
        gs = gridspec.GridSpec(4,1, height_ratios=[3,2,2,1])
        self.ax1 = plt.subplot(gs[0])
        self.ax2 = plt.subplot(gs[1], sharex=self.ax1)
        self.ax3 = plt.subplot(gs[2], sharex=self.ax1)
        self.ax4 = plt.subplot(gs[3], sharex=self.ax1)   
        
        canvas = FigureCanvasTkAgg(self.fig, master=self.visualizerFrame)
        canvas.show()
        canvas.mpl_connect('key_press_event', self.on_key_event)
        canvas.mpl_connect('button_press_event', self.on_button_event)
    
        # GUI Elements
        self.mode_label = Tk.Label(self.visualizerFrame, text="Mode: ADD", background="green")
    
        self.progress_label = Tk.Label(self.visualizerFrame, text="Page {}/{}".format(self.dataMgr.current_page, self.dataMgr.num_pages))
    
        button_prev = Tk.Button(master=self.visualizerFrame, text='Prev', command=self._prev)
        button_next = Tk.Button(master=self.visualizerFrame, text='Next', command=self._next)
    
        button_zoom_in = Tk.Button(master=self.visualizerFrame, text='Zoom In', command=self._zoom_in)
        button_zoom_out = Tk.Button(master=self.visualizerFrame, text='Zoom Out', command=self._zoom_out)    
    
        button_add = Tk.Button(master=self.visualizerFrame, text='Add', command=self._add)
        button_del = Tk.Button(master=self.visualizerFrame, text='Del', command=self._del)
        
        saveFrame = Tk.Frame(self.visualizerFrame)
        button_autosave = Tk.Button(master=saveFrame, text='Auto-Save', command=self._autosave)
        button_save = Tk.Button(master=saveFrame, text='Save', command=self._save)
        button_autosave.grid(column=0, row=0)
        button_save.grid(column=1, row=0)
        
        button_quit = Tk.Button(master=self.visualizerFrame, text='Quit', command=self._quit)
        
        # Selection
        self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='g', lw=1)
        self.span1 = SpanSelector(self.ax1, self.onselectAdd, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='green') )
        self.span2 = SpanSelector(self.ax2, self.onselectAdd, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='green') )
        self.span3 = SpanSelector(self.ax3, self.onselectAdd, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='green') )
        self.span4 = SpanSelector(self.ax4, self.onselectAdd, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='green') )

        # GUI Layout
        button_zoom_in.grid(column=0, row=0)
        button_zoom_out.grid(column=1, row=0)
        button_prev.grid(column=3, row=0)
        self.progress_label.grid(column=4, row=0)
        button_next.grid(column=5, row=0)
        canvas.get_tk_widget().grid(column=0, row=1, columnspan=6)
        canvas._tkcanvas.grid(column=0, row=1, columnspan=6)
        button_add.grid(column=0, row=2)
        button_del.grid(column=1, row=2)
        self.mode_label.grid(column=2, row=2, columnspan=2)
        saveFrame.grid(column=4, row=2)
        button_quit.grid(column=5, row=2)
    
        Tk.mainloop()       


    def _CfgContinue(self):
        self.loading_label['text'] = 'loading ...'
        self.loading_label.update()
        
        self.plot_names = [self.plot1_select.get(),
                      self.plot2_select.get(),
                      self.plot3_select.get()]
        
        self.plot_cols = []              
        for pn in self.plot_names:
            self.plot_cols.append(self.dataMgr.header_columns.index(pn))

        self.usage_names = []
        self.usage_cols = []
        for k,v in self.usage_plots.items():
            if v.get() == 1:
                self.usage_names.append(k)
                self.usage_cols.append(self.dataMgr.header_columns.index(k))
        
        if self.load_autosave_file:
            usg_manual_col = -1
        else:
            if self.usg_man_select.get() in self.dataMgr.header_columns:
                usg_manual_col = self.dataMgr.header_columns.index(self.usg_man_select.get())
            else:
                usg_manual_col = -1
            
        if self.jmp_select.get() in self.dataMgr.jump_columns:
            jmp_col = self.dataMgr.header_columns.index(self.jmp_select.get())
        else:
            jmp_col = -1
        
        [self.x, self.plot_data, self.usage_data, self.usage_manual, self.jump_positions] = self.dataMgr.readData(self.plot_cols,self.usage_cols,self.loading_label, usg_manual_col, jmp_col)

        if self.load_autosave_file:
            infile = open(self.autosave_file, 'rb')
            self.usage_manual = pickle.load(infile)
            infile.close()

        self.configFrame.pack_forget()
        self.visualizerFrame.pack()

        print("displaying plots")
        
        self.ylim_ax1 = self.calc_ylims(self.plot_data[0])
        self.ylim_ax2 = self.calc_ylims(self.plot_data[1])
        self.ylim_ax3 = self.calc_ylims(self.plot_data[2])
        
        self.loadPage(1)


    def HMS(seconds, pos):
        """Customized x-axis ticks 
            
        Keyword arguments:
        seconds -- input in secs
        pos -- somehow required argument (matplotlib)
        """
        seconds = int(seconds)
        hours = seconds / 3600
        seconds -= 3600 * hours
        minutes = seconds / 60
        seconds -= 60 * minutes
        if hours == 0:
            if minutes == 0:
                return "%ds" % (seconds)
            return "%dm%02ds" % (minutes, seconds)
        return "%dh%02dm" % (hours, minutes)
        
        
    def calc_ylims(self, data):
        [cnt, edge] = np.histogram(data, 25)
        s = len(data)
        thres = 0.975*s
        i = 0
        j = len(cnt)-1
        while True:
            if cnt[i] < cnt[j]:
                if s-cnt[i] < thres:
                    break
                else:
                    s -= cnt[i]
                    i += 1
            else:
                if s-cnt[j] < thres:
                    break
                else:
                    s -= cnt[j]
                    j -= 1
        
        return [min(0, edge[i]), max(1, edge[j+1])]


    def plotPage(self):
        index_low = self.dataMgr.low_Idx()
        index_high = self.dataMgr.high_Idx()
        
        if self.show_debug_msg:
            print("index_low: {} | index_high: {}".format(index_low, index_high))
    
        self.ax1.clear()
        self.ax1.xaxis.set_major_formatter(plt.FuncFormatter(self.HMS))
        self.ax1.plot(self.x[index_low:index_high], np.array(self.plot_data[0][index_low:index_high]))
        self.ax1.set_ylim(self.ylim_ax1)
        self.ax1.set_title(self.plot_names[0])
        
        self.ax2.clear()
        self.ax2.plot(self.x[index_low:index_high], self.plot_data[1][index_low:index_high])
        self.ax2.set_ylim(self.ylim_ax2)
        self.ax2.set_title(self.plot_names[1])
        
        self.ax3.clear()
        self.ax3.plot(self.x[index_low:index_high], self.plot_data[2][index_low:index_high])
        self.ax3.set_ylim(self.ylim_ax3)
        self.ax3.set_title(self.plot_names[2])
        
        self.plotUsages()
        
        self.fig.canvas.draw()
        
    
    def plotUsages(self):
        index_low = self.dataMgr.low_Idx()
        index_high = self.dataMgr.high_Idx()
        
        self.ax4.clear()
        self.ax4.set_ylim(0,len(self.usage_names)+2)
        self.ax4.set_yticks([], minor=False)     
        
        colors = ['#483D8B', '#228B22', '#B22222', '#8A2BE2', '#808000', '#FF4500', '#DA70D6', '#FFA500']
                
        self.ax4.fill_between(self.x[index_low:index_high], 0, (len(self.usage_names)+2)*np.array(self.usage_manual[index_low:index_high]), facecolor='#7fbf7f', edgecolor='None')
        
        self.ax4.plot(self.jump_positions, [len(self.usage_names)+1]*len(self.jump_positions), 'r*')        
        
        for u in range(0,len(self.usage_data)):
            self.ax4.fill_between(self.x[index_low:index_high], u, u+np.array(self.usage_data[u][index_low:index_high]), facecolor=colors[u], edgecolor='None')

        patches = [mpatches.Patch(color='green', alpha=0.5, label='usage_manual')]
        
        for i in range(0,len(self.usage_names)):
            patches.append(mpatches.Patch(color=colors[i], label=self.usage_names[i]))

        plt.legend(bbox_to_anchor=(0., 1.0, 1., .102), loc=3,
           ncol=5, mode="expand", borderaxespad=0., handles=patches)

        self.ax1.set_xlim(self.dataMgr.low_Xlimit(),self.dataMgr.high_Xlimit())

    
    def onselectAdd(self, xmin, xmax):
        minIdx = max(0, round(xmin*500))
        maxIdx = min(self.dataMgr.file_length-1, round(xmax*500))
        if self.show_debug_msg:
            print("ADD: xmin: {} | xmax: {}".format(xmin, xmax))
            print("ADD: minIdx: {} | maxIdx: {}".format(minIdx, maxIdx))

        self.usage_manual[minIdx:maxIdx] = 1
        self.plotUsages()
        self.fig.canvas.draw()


    def onselectDel(self, xmin, xmax):
        minIdx = max(0, round(xmin*500))
        maxIdx = min(self.dataMgr.file_length-1, round(xmax*500))
        if self.show_debug_msg:
            print("DEL: xmin: {} | xmax: {}".format(xmin, xmax))
            print("DEL: minIdx: {} | maxIdx: {}".format(minIdx, maxIdx))
        
        self.usage_manual[minIdx:maxIdx] = 0
        self.plotUsages()
        self.fig.canvas.draw()


    def onselectZoom(self, xmin, xmax):
        if self.show_debug_msg:
            print("ZOOM: xmin: {} | xmax: {}".format(xmin, xmax))
        
        self.plotUsages()
        self.ax1.set_xlim(xmin,xmax)
        self.fig.canvas.draw()
    
    
    def on_key_event(self, event):
        if self.show_debug_msg:
            print('you pressed %s'%event.key)
        if event.key == 'a':
            self._prev()
        elif event.key == 'd':
            self._next()
        elif event.key == 'w':
            self._add()
        elif event.key == 's':
            self._del()
        elif event.key == 'q':
            self._zoom_in()
        elif event.key == 'e':
            self._zoom_out()
        elif event.key == 'r':
            self._save()
        elif event.key == 'f':
            self._autosave()
        elif event.key == 'x':
            self._prevJump()
        elif event.key == 'c':
            self._nextJump()
        elif event.key == 'left':
            self._prev()
        elif event.key == 'right':
            self._next()
        elif event.key == 'up':
            self._add()
        elif event.key == 'down':
            self._del()
            

    def on_button_event(self, event):
        if self.show_debug_msg:
            print('you clicked %s'%event.button)
        if event.button == 3:   #right mouse button
            self._zoom_out()
        elif event.button == 2: #middle mouse button (scroll wheel)
            self._zoom_in()


    def _quit(self):
        self.root.quit()     # stops mainloop
        self.root.destroy()  # this is necessary on Windows to prevent
                        # Fatal Python Error: PyEval_RestoreThread: NULL tstate
    
    def _prev(self):
        if self.show_debug_msg:
            print('_prev()')
        if self.dataMgr.current_page > 1:
            self.loadPage(self.dataMgr.current_page-1)

    def _next(self):
        if self.show_debug_msg:
            print('next()')
        if self.dataMgr.current_page < self.dataMgr.num_pages:
            self.loadPage(self.dataMgr.current_page+1)


    def _prevJump(self):
        if self.show_debug_msg:
            print('_prevJump()')
        if self.dataMgr.current_page > 1:
            for p in reversed(self.jump_positions):
                num = self.dataMgr.getPageNumByX(p)
                if num < self.dataMgr.current_page:
                    self.loadPage(num)
                    break


    def _nextJump(self):
        if self.show_debug_msg:
            print('nextJump()')
        if self.dataMgr.current_page < self.dataMgr.num_pages:
            for p in self.jump_positions:
                num = self.dataMgr.getPageNumByX(p)
                if num > self.dataMgr.current_page:
                    self.loadPage(num)
                    break
            

    def loadPage(self, page_num):
        if self.autosave_period > -1 and page_num % self.autosave_period == 0:
            if self.show_debug_msg:
                print('autosaving on page {}'.format(page_num))
            self._autosave()
        self.dataMgr.current_page = min(max(1, page_num), self.dataMgr.num_pages)
        if self.show_debug_msg:
            print('loadPage(): {}'.format(self.dataMgr.current_page))
        self.plotPage()
        self.progress_label["text"] ="Page {}/{}".format(self.dataMgr.current_page, self.dataMgr.num_pages)


    def _add(self):
        if self.show_debug_msg:
            print('_add()')
        if float(matplotlib.__version__[0:3])>=1.4:
            self.multi_cursor.disconnect()
        self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='g', lw=1)
        self.span1.disconnect_events()
        self.span2.disconnect_events()
        self.span3.disconnect_events()
        self.span4.disconnect_events()
        self.span1 = SpanSelector(self.ax1, self.onselectAdd, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='green') )
        self.span2 = SpanSelector(self.ax2, self.onselectAdd, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='green') )
        self.span3 = SpanSelector(self.ax3, self.onselectAdd, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='green') )
        self.span4 = SpanSelector(self.ax4, self.onselectAdd, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='green') )

        self.mode_label['text'] = 'Mode: ADD'
        self.mode_label['bg'] = 'green'
        self.fig.canvas.draw()


    def _del(self):
        if self.show_debug_msg:
            print('_del()')
        if float(matplotlib.__version__[0:3])>=1.4:
            self.multi_cursor.disconnect()
        self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='r', lw=1)
        self.span1.disconnect_events()
        self.span1.disconnect_events()
        self.span2.disconnect_events()
        self.span3.disconnect_events()
        self.span4.disconnect_events()
        self.span1 = SpanSelector(self.ax1, self.onselectDel, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='red') )
        self.span2 = SpanSelector(self.ax2, self.onselectDel, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='red') )
        self.span3 = SpanSelector(self.ax3, self.onselectDel, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='red') )
        self.span4 = SpanSelector(self.ax4, self.onselectDel, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='red') )

        self.mode_label['text'] = 'Mode: DEL'
        self.mode_label['bg'] = 'red'
        self.fig.canvas.draw()

  
    def _zoom_in(self):
        if self.show_debug_msg:
            print('_zoom_in()')
        if float(matplotlib.__version__[0:3])>=1.4:
            self.multi_cursor.disconnect()
        self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='b', lw=1)
        self.span1.disconnect_events()
        self.span1.disconnect_events()
        self.span2.disconnect_events()
        self.span3.disconnect_events()
        self.span4.disconnect_events()
        self.span1 = SpanSelector(self.ax1, self.onselectZoom, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='blue') )
        self.span2 = SpanSelector(self.ax2, self.onselectZoom, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='blue') )
        self.span3 = SpanSelector(self.ax3, self.onselectZoom, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='blue') )
        self.span4 = SpanSelector(self.ax4, self.onselectZoom, 'horizontal', useblit=True,
                        rectprops=dict(alpha=0.5, facecolor='blue') )

        self.mode_label['text'] = 'Mode: ZOOM'
        self.mode_label['bg'] = 'blue'
        self.fig.canvas.draw()


    def _zoom_out(self):
        if self.show_debug_msg:
            print('_zoom_out()')

        self.plotUsages()
        self.fig.canvas.draw()


    def _save(self):
        if self.show_debug_msg:
            print('_save()')
        savetxt = plt.text(20, 20, 'saving...', fontsize=46, color='r', weight='bold', ha='center', va='top')
        self.fig.canvas.draw()
        self.dataMgr.writeCSV(self.csv_out_file, self.usage_manual)
        savetxt.remove()
        self.fig.canvas.draw()
        if os.path.isfile(self.autosave_file):
            archive_filename = self.autosave_file.rsplit(".", 1)[0] + "_old.pkl"
            print('renaming autosave file from "{}" to "{}"'.format(self.autosave_file, archive_filename))
            if os.path.isfile(archive_filename):            
                os.unlink(archive_filename)
            os.rename(self.autosave_file, archive_filename)
        
        
    def _autosave(self):
        if self.show_debug_msg:
            print('_autosave()')
        savetxt = plt.text(20, 20, 'autosaving...', fontsize=46, color='r', weight='bold', ha='center', va='top')
        self.fig.canvas.draw()
        self.dataMgr.writeAutoSave(self.autosave_file, self.usage_manual)
        savetxt.remove()
        self.fig.canvas.draw()
Exemplo n.º 2
0
class DisplayWindow(object):
        global CdMeOTPRef, MeOTPRef
        color_list = deque(['b','g','r','c','m','y','k'])
        current_checker = None
        

        def __init__(self, master,ax = None):
                
                self.rootref = master
                self.master = Toplevel()
                self.checker_frame=Tkinter.Frame(master = self.master)#,yscrollcommand=self.scroll.set)
                #self.scroll.config(command=self.checker_frame.yview) 

                        
                        
                self.frame = Frame(master = self.master)
                self.Plot = Figure(figsize=(6,3))               
                self.channel_list = []
                self.array_list = []
                self.Plot.a  = self.Plot.add_subplot(111)

                    
                    
                self.Plot.a.set_xlabel('Raman Shift (cm$^{-1}$)')
                self.Plot.a.set_ylabel('Intensity (a.u.)')
                self.Plot.a.legend([])
                self.Plot.a.get_legend().set_visible(False)
                self.checker_list = self.Plot.a.lines
                self.legend_var = IntVar()
                self.legend_var.set(1)
                self.legendbox = Checkbutton(self.frame,
                                       variable=self.legend_var,
                                       command=self.update_legend,text='Legend')
#                self.legend_label=Label(self.master, bd=1, anchor=W)
#                self.legend_label.config(text = "Legend")
                
                
                
                self.statusbar = Label(self.master, bd=1, relief=SUNKEN, anchor=W)
                self.statusbar.config(text = "Ready")
                

    
               
                
 
                self.canvas = FigureCanvasTkAgg(self.Plot,master = self.frame)
                self.canvas.show()
                
               
                
                self.master.protocol("WM_DELETE_WINDOW", self.quitproc)

               
                self.master.title(string = "RamanViewer")
                #self.scroll = Tkinter.Scrollbar(self.frame)
                #self.scroll.pack(side  = Tkinter.RIGHT, fill = Tkinter.BOTH)
               
                
                self.checker_frame=Tkinter.Frame(master = self.master)#,yscrollcommand=self.scroll.set)
                #self.scroll.config(command=self.checker_frame.yview)                
                
                self.menubar = Menu(self.master)
                
                self.filemenu = Menu(self.menubar, tearoff=0)
                self.filemenu.add_command(label="New window", command = lambda: DisplayWindow(self.rootref))
                self.filemenu.add_command(label="Open", command = self.DisplaySpectrum)
                self.filemenu.add_command(label="Save",command = self.SaveSpectrum)
                self.filemenu.add_command(label="SaveFig",command = self.SaveFigure)
                self.filemenu.add_command(label="ViewNotebook",command = self.ViewNotebook)
                self.filemenu.add_command(label="Exit", command = self.quitproc)
                self.menubar.add_cascade(label="File", menu=self.filemenu)
                # create more pulldown menus
                self.editmenu = Menu(self.menubar, tearoff=0)
                self.editmenu.add_command(label="Smooth", command = self.SmoothSpectrum)
                self.filemenu.add_command(label="Fitting window", command = lambda:FittingWindow(Toplevel(),ramanspectrum=self.current_checker.spectrum))#, kwargs = {'ramanspectrum':self.current_checker.channel.spec_array})
                self.editmenu.add_command(label="Calc Noise", command = self.start_calc_noise)
                self.editmenu.add_command(label="Calc Area", command = self.start_calc_area)
                self.editmenu.add_command(label="Basline", command = self.start_autobaseline)
                self.editmenu.add_command(label="disconnect", command = self.disconnect)
                self.editmenu.add_command(label='Quick Scan',command = self.open_next_spectrum_in_folder)
                self.editmenu.add_command(label='Normalize All',command = self.normalizeall)
                self.editmenu.add_command(label='Zero All',command = self.zeroall) 
                self.editmenu.add_command(label = 'FFT process', command=self.FFT)
                self.editmenu.add_command(label = 'Remove noise', command = self.removenoise)
                self.editmenu.add_command(label="Copy")
                self.editmenu.add_command(label="Paste")
                self.menubar.add_cascade(label="Edit", menu=self.editmenu)
                
                self.correctionmenu = Menu(self.menubar,tearoff=0)
                self.correctionmenu.add_command(label='SPID633', command = self.SPIDcorrect633)
                self.correctionmenu.add_command(label='SPID785', command = self.SPIDcorrect785)
                
                self.menubar.add_cascade(label = 'Corrections', menu = self.correctionmenu)
                
                self.notesmenu =Menu(self.menubar, tearoff=0)
                self.notesmenu.add_command(label = "Notes", command = self.ViewNotebook)
                self.notesmenu.add_command(label = "Spectrum Info", command = self.showinfo)
                self.menubar.add_cascade(label = 'Info', menu = self.notesmenu)
                
                self.refsmenu =Menu(self.menubar, tearoff=0)
                self.refsmenu.add_command(label = "chloroform", command = None)
              
                self.refsmenu.add_command(label = "CdMeOTP", command = lambda:self.AddChannel(CdMeOTPRef))
                self.refsmenu.add_command(label = "MeOTP", command = lambda:self.AddChannel(MeOTPRef))
                self.refsmenu.add_command(label = "ClTP", command = lambda:self.AddChannel(ClTPRef))
                self.refsmenu.add_command(label = "BrTP", command = lambda:self.AddChannel(BrTPRef))
                self.refsmenu.add_command(label = "FTP", command = lambda:self.AddChannel(FTPRef))
                self.refsmenu.add_command(label = "MethylTP", command = lambda:self.AddChannel(MethylTPRef))
                self.refsmenu.add_command(label = "CdODPA", command = lambda:self.AddChannel(CdODPARef))
                self.refsmenu.add_command(label = "toluene", command = lambda:self.AddChannel(tolueneRef))
                self.refsmenu.add_command(label = "CdMethylTP", command = lambda:self.AddChannel(CdMethylTPRef))
                self.menubar.add_cascade(label = 'References', menu = self.refsmenu)
                
                
                self.master.config(menu= self.menubar)
                
                
                
                
                self.left_click_menu = Menu(self.frame, tearoff=0)
                self.left_click_menu.add_command(label="open", command = self.DisplaySpectrum)
#                self.left_click_menu.add_command(label="blue", command=lambda:self.change_color('b'))
#                self.left_click_menu.add_command(label="black", command=lambda:self.change_color('k'))
#                self.left_click_menu.add_command(label="yellow", command=lambda:self.change_color('y'))
                
                
               # self.canvas._tkcanvas.bind("<Button-3>", self.popup)


                self.frame.pack(side = TOP, expand=1, fill=BOTH)#(row = 0, column = 0, padx = 25, pady = 25)
                self.legendbox.pack(side=BOTTOM)
                self.statusbar.pack(side = BOTTOM,expand=1,fill=X)
                self.checker_frame.pack(side=BOTTOM,expand = 1,fill=X)#(row=1,column=0)
                self.canvas._tkcanvas.pack( expand = 1, fill = BOTH)
                self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.frame)
                self.toolbar.update()
                self.toolbar.pack(side= BOTTOM,expand =True)
                self.canvas.draw()
                
                list_of_display_windows.append(self)
                
                if ax is not None:
                    
                    for line in ax.lines:
                        
                        self.Plot.a.add_line(checker(self,line,color = line.get_color()))
                    self.Plot.a.relim()
                    self.Plot.a.autoscale_view(tight = False)
                    self.Plot.canvas.draw()
                    self.current_checker = self.Plot.a.lines[-1]
                    plt.close(ax.get_figure())
                return None
        def popup(self,event):
            print event.x_root, event.y_root
            self.left_click_menu.post(event.x_root, event.y_root)
        def update_legend(self):
            
            if self.legend_var.get() == 0:
                self.Plot.a.get_legend().set_visible(False)
            else:
                l = list()
                for entry in self.checker_list:
                    if True:#entry.get_visible():
                        l.append(entry.commentbox.get())
                        self.Plot.a.legend(l)
                   
          
            self.Plot.canvas.draw()
            return 0
        def showinfo(self):
            tkMessageBox.showinfo('Spectrum info',self.current_checker.spectrum.info)
            return 0
            
        def getcolor(self): 
            self.color_list.rotate(1)
            return self.color_list[0]
                
       
        def DisplaySpectrum(self):
            import re
            options = {}
            #options['defaultextension'] = '.SPE'
            options['filetypes'] = [('all files','.*'),('SPE','.spe'),('txt', '.txt'),('csv','.csv')]
            options['multiple'] = True
            options['title'] = 'Open Spectrum...'
            options['parent'] = self.master
         
            str_name_list = tkFileDialog.askopenfilenames(**options)
           
            if type(str_name_list) == tuple:
                for name in str_name_list:
                    if 'notes' in name:
                        SFG_Notebook.SFG_NotebookWindow(target_file = name)
                    elif name =='':
                        continue
                    else:
                        newspectrum = RamanSpectrum(name)                            
                        self.Plot.a.add_line(checker(self,newspectrum,color = self.getcolor()))
                        self.Plot.a.relim()
                        self.Plot.a.autoscale_view(tight = False)
                        self.Plot.canvas.draw()
                        self.current_checker = self.Plot.a.lines[-1]
            elif str_name_list == '':
                    return 0
            elif type(str_name_list) == list:
                for name in re.split(' ',str_name_list):
                    newspectrum = RamanSpectrum(name)
                    self.Plot.a.add_line(checker(self,newspectrum,color = self.getcolor()))
                    self.Plot.a.relim()
                    self.Plot.a.autoscale_view(tight = False)
                    self.Plot.canvas.draw()
                    

                    self.current_checker = self.Plot.a.lines[-1]
            
      
               
            return 0

        def SaveSpectrum(self):
                
                file_opt = options = {}
                options['defaultextension'] = '.txt'
                options['filetypes'] = [('all files', '.*')]
                
                options['title'] = 'Open Spectrum...'
                options['initialfile'] = os.path.basename(self.current_checker.name)
                options['parent'] = self.master

                if self.current_checker  == None:
                        return 0
                str_filename = tkFileDialog.asksaveasfilename(**options)
               
                if str_filename == '':
                        return 0
                else:
                        data = transpose([self.current_checker.get_xdata(),self.current_checker.get_ydata()])
                        
                        savetxt(str_filename,data,delimiter = ',',comments = '#'+str(self.current_checker.spectrum.info))#SaveSpectrum(self.current_checker.channel.spec_array,str_filename)
                os.chdir(os.path.dirname(str_filename))
                return 0
        def ViewNotebook(self):
                
                print os.path.dirname(self.current_checker.name)
                try:
                    SFG_Notebook.SFG_NotebookWindow(target_dir = os.path.dirname(self.current_checker.name))
                except IOError:
                    tkSimpleDialog.Message('no file found')
                return 0 
        def zeroall(self):
                for c in self.Plot.a.lines:
                    c.set_ydata(c.get_ydata()-min(c.get_ydata()))
                self.Plot.a.relim()
                self.Plot.a.autoscale_view(tight = False)
                self.Plot.canvas.draw()
                return 0
                
                        
        def SmoothSpectrum(self):

                if self.current_checker == None:
                    return 0
                newspectrum = smooth(self.current_checker.spectrum)
                                                        
                self.Plot.a.add_line(checker(self,newspectrum,color = self.getcolor(),operations = 'sp = smooth(sp)\n'))
                self.Plot.a.relim()
                self.Plot.a.autoscale_view(tight = False)
                self.Plot.canvas.draw()
                self.current_checker = self.Plot.a.lines[-1]
                
      
                return 0
        def SPIDcorrect785(self):
            if self.current_checker == None:
                return 0
            else:
                newspectrum = SPIDcorrect785(self.current_checker.spectrum)
                                                        
                self.Plot.a.add_line(checker(self,newspectrum,color = self.getcolor(),operations = 'sp = SPIDcorrect785(sp)\n'))
                self.Plot.a.relim()
                self.Plot.a.autoscale_view(tight = False)
                self.Plot.canvas.draw()
                self.current_checker = self.Plot.a.lines[-1]
                
  
            return 0
        def SPIDcorrect633(self):
            if self.current_checker == None:
                return 0
            else:
                newspectrum = SPIDcorrect633(self.current_checker.spectrum)
                                                        
                self.Plot.a.add_line(checker(self,newspectrum,color = self.getcolor(),operations = 'sp = SPIDcorrect633(sp)\n'))
                self.Plot.a.relim()
                self.Plot.a.autoscale_view(tight = False)
                self.Plot.canvas.draw()
                self.current_checker = self.Plot.a.lines[-1]
                
  
            return 0
        def open_next_spectrum_in_folder(self):
                self.Plot.canvas.mpl_connect('key_press_event',self.open_next_spectrum)
                for c in self.checker_list[1:]:
                    self.RemoveSpectrum(self.checker)
                self.checker_list[0].set_current(0)
                
                return 0
        def open_next_spectrum(self,event):
                
                directory_index = os.listdir(os.path.dirname(os.path.abspath(self.current_checker.channel.spec_array.name)))
                for x in directory_index:
                    if 'txt' not in x:
                        directory_index.remove(x)
                directory_index.sort()
                i=directory_index.index(os.path.basename(self.current_checker.channel.spec_array.name))

                if i>len(directory_index)-2:
                    i=-1
                if 'txt' not in directory_index[1+1]:
                    i+=1
                if event.key == 'right':
                    i+=1
                elif event.key == 'left':
                    i-=1

                try:
                    newspectrum = RamanSpectrum(directory_index[i])
                except:
                    print 'error'
                    print 'i=',i
                    
                    return -1
                self.RemoveSpectrum(self.current_checker)
                self.AddChannel(self.newspectrum)
               
                self.checker_list[0].set_current(0)
                return 0
                
                
        def normalizeall(self):
            for check in self.checker_list:
                data = check.get_ydata()
                data[:]-=min(data)
                data/=max(data)
                check.set_ydata(data)
            self.Plot.a.relim()
            self.Plot.a.set_ylim(-0.5,1.5)
            self.Plot.a.autoscale_view(tight = False)
            self.Plot.canvas.draw()
            return 0
                
        def start_calc_noise(self):
              
                self.span = SpanSelector(self.Plot.a, self.calc_noise, 'horizontal')
                self.span.connect_event('pick_event',self.calc_noise)
                gcf().canvas.mpl_connect('button_press_event',self.disconnect)
                return 0
        def start_calc_area(self):
               
                self.span = SpanSelector(self.Plot.a, self.calc_area, 'horizontal')
                self.span.connect_event('pick_event',self.calc_area)
                gcf().canvas.mpl_connect('button_press_event',self.disconnect)
                
                return 0
        def start_autobaseline(self):
               # self.toolbar.release(None)
                self.span = SpanSelector(self.Plot.a, self.autobaseline, 'horizontal')
                self.span.connect_event('pick_event',self.autobaseline)
                gcf().canvas.mpl_connect('button_press_event',self.disconnect)
                
                return 0
        def autobaseline(self,start,end):
                order = int(tkSimpleDialog.askinteger('Fit order', 'Choose the polynomial order.'))
                if order == None:
                    return 0
                if self.current_checker == None:
                    return 0
                newspectrum = autobaseline(self.current_checker.spectrum,(start,end),order = order)
                                                      
                self.Plot.a.add_line(checker(self,newspectrum,color = self.getcolor(),operations = 'sp = autobaseline(sp), ('+str(start)+','+str(end)+'), order ='+str(order)+')\n'))
                self.Plot.a.relim()
                self.Plot.a.autoscale_view(tight = False)
                self.Plot.canvas.draw()
                self.current_checker = self.Plot.a.lines[-1]
                self.span.disconnect_events()
                
                return 0
                
        def calc_noise(self,start,end):
                try:
                    print "STD =", calc_noise(pandas.Series(self.current_checker.channel.get_ydata(),self.current_checker.channel.get_xdata()),(start,end))
                 
                except:
                    print 'error'
                return 0
        def calc_area(self, start,end):
                try:
                    print "Area =", calc_area(pandas.Series(self.current_checker.channel.get_ydata(),self.current_checker.channel.get_xdata()),(start,end)) 
                except:
                    print 'error'
                return 0
        def disconnect(self):
            #print event.button#gcf().canvas.mpl_disconnect(self.cid)
            self.span.disconnect_events()
            return 0
        def removenoise(self):
            newspectrum = removecorrelatednoise(self.current_checker.spectrum)
                                                        
            self.Plot.a.add_line(checker(self,newspectrum,operations = 'sp = removecorrelatednoise(sp)',color=self.getcolor()))
            self.Plot.a.relim()
            self.Plot.a.autoscale_view(tight = False)
            self.Plot.canvas.draw()
            self.current_checker = self.Plot.a.lines[-1]
            return None


                
        def AddChannel(self,spectrum):
                
                
                self.Plot.a.add_line(checker(self,spectrum))
                self.Plot.a.lines[-1].set_color(self.getcolor())
                self.Plot.a.relim()
                self.Plot.a.autoscale_view(tight = False)
                self.Plot.canvas.draw()
                self.current_checker = self.Plot.a.lines[-1]
                return 0 

       

        def RemoveSpectrum(self,checker):
                
                
                self.Plot.a.lines.remove(checker)
                self.Plot.a.relim()
                self.Plot.a.autoscale_view(tight = False)
                self.canvas.draw()
                checker.frame.pack_forget()
                return 0   
                
        def SaveFigure(self):
                os.chdir('/home/chris/Desktop')
                self.Plot.savefig('figure.png')
                f = open('/home/chris/Desktop/figure.py','wb')
                for line in self.Plot.a.lines:
                    f.write(line.operations)
                f.close()
                return 0
        def FFT(self):
                return 0
                
        def quitproc(self):
                self.master.destroy()
                list_of_display_windows.remove(self)
                if len(list_of_display_windows)==0:
                   self.rootref.destroy() 
                return 0
Exemplo n.º 3
0
class LSFQDialg(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.handles = []
        self.create_canvas()
        self.segments = []

        vbox = QVBoxLayout()
        vbox.addWidget(self.canvas)
        self.setLayout(vbox)

        self.resize(800, 600)
        self.move(320, 75)
        self.setWindowTitle("Least Square Fitting (2D)")

    def create_canvas(self):
        self.fig = plt.figure()
        self.canvas = FigureCanvas(self.fig)
        self.axes = plt.subplot(111)
        self.axes.set_xlabel("Scans")
        self.axes.set_ylabel("Instensity")
        self.axes.set_title("Least Square Fitting(2D)", fontsize=9)
        self.axes.tick_params(axis='both', labelsize=8)
        plt.subplots_adjust(bottom=0.22, top=0.90, left=0.08, right=0.9)

        self.span = SpanSelector(self.axes,
                                 self.span_select_callback,
                                 'horizontal',
                                 minspan=0.002,
                                 useblit=True,
                                 rectprops=dict(alpha=0.5, facecolor='red'),
                                 onmove_callback=None,
                                 button=[1])

        axspan = plt.axes([0.09, 0.04, 0.08, 0.075])
        axundo = plt.axes([0.2, 0.04, 0.08, 0.075])
        axstar = plt.axes([0.31, 0.04, 0.08, 0.075])
        self.btnspan = Button(axspan, 'span')
        self.btnundo = Button(axundo, 'undo')
        self.btnstar = Button(axstar, 'start')

        self.btnspan.on_clicked(self.span_mode)
        self.btnundo.on_clicked(self.undo_mode)
        self.btnstar.on_clicked(self.star_mode)

        self.span.set_active(True)
        self.redraw()
        ymino, ymaxo = self.axes.get_ylim()
        xmino, xmaxo = self.axes.get_xlim()
        self.oxy = [(xmino, xmaxo), (ymino, ymaxo)]

    def redraw(self):
        self.canvas.draw()
        self.update()

    def span_mode(self, event):
        self.span.connect_event('motion_notify_event', self.span.onmove)
        self.span.connect_event('button_press_event', self.span.press)
        self.span.connect_event('button_release_event', self.span.release)
        self.span.connect_event('draw_event', self.span.update_background)
        self.leftdblclick = False
        self.rightdblclick = False
        self.redraw()
        print "span"

    def undo_mode(self, event):
        self.span.disconnect_events()
        if len(self.segments) >= 1:
            del self.axes.collections[:]
            self.segments = self.segments[:-1]
            self.select_inter(self.segments)
            self.redraw()
        print "undo"

    def star_mode(self, event):
        if len(self.segments) == 0:
            msgBox = QMessageBox()
            msgBox.setText("No selected noise region")
            msgBox.exec_()
        else:
            fit, bas = self.backremv(self.segments)
            self.show_bas(bas)
            self.show_fit(fit)
            self.emit(SIGNAL('after_baseline'), fit)

    def show_bas(self, bas):
        self.axes.plot(np.sum(bas, axis=1), lw=2, c='k', alpha=.7, picker=5)

    def show_fit(self, fit):
        self.axes.plot(np.sum(fit, axis=1), lw=2, c='r', alpha=.7, picker=5)

    def show_org(self, x):
        self.axes.plot(np.sum(x, axis=0), lw=2, c='b', alpha=.7, picker=5)

    def span_select_callback(self, xmin, xmax):
        cc = np.arange(0, self.x.shape[0])
        indmin, indmax = np.searchsorted(cc, (xmin, xmax))
        indmax = min(len(self.x) - 1, indmax)
        self.segments.append((indmin, indmax))
        self.axes.vlines(xmin,
                         self.oxy[1][0],
                         self.oxy[1][1],
                         color='r',
                         linestyles='--')
        self.axes.vlines(xmax,
                         self.oxy[1][0],
                         self.oxy[1][1],
                         color='r',
                         linestyles='--')
        self.redraw()

    def updata_data(self, x):
        self.xx = x
        self.axes.clear()
        self.axes.set_xlabel("Scans")
        self.axes.set_ylabel("Instensity")
        self.axes.set_title("Least Square Fitting(2D)", fontsize=9)
        self.x = x['d']
        self.y = np.sum(self.x, axis=1)
        self.axes.plot(self.y, lw=1, c='b', alpha=.7, picker=5)
        diff_y = max(self.y) - min(self.y)
        self.axes.set_xlim(0, len(self.y))
        self.axes.set_ylim(0, max(self.y) * 1.1)
        ymino, ymaxo = self.axes.get_ylim()
        xmino, xmaxo = self.axes.get_xlim()
        self.oxy = [(xmino, xmaxo), (ymino, ymaxo)]
        self.plotorg = True
        self.redraw()

    def select_inter(self, segments):
        for i in range(0, len(segments)):
            indmin, indmax = segments[i]
            self.axes.vlines(self.x[indmin],
                             self.oxy[1][0],
                             self.oxy[1][1],
                             color='r',
                             linestyles='--')
            self.axes.vlines(self.x[indmax],
                             self.oxy[1][0],
                             self.oxy[1][1],
                             color='r',
                             linestyles='--')

    def backremv(self, seg):
        mn = np.shape(self.x)
        bak2 = np.zeros(mn)
        for i in range(0, mn[1]):
            tiab = []
            reg = []
            for j in range(0, len(seg)):
                tt = range(seg[j][0], seg[j][1])
                tiab.extend(self.x[tt, i])
                reg.extend(np.arange(seg[j][0], seg[j][1]))
            rm = reg - np.mean(reg)
            tm = tiab - np.mean(tiab)
            b = np.dot(np.dot(float(1) / np.dot(rm.T, rm), rm.T), tm)
            s = np.mean(tiab) - np.dot(np.mean(reg), b)
            b_est = s + b * np.arange(mn[0])
            bak2[:, i] = self.x[:, i] - b_est
        bak = self.x - bak2
        self.yy = bak2
        return bak2, bak

    def accept(self):
        self.xx['d'] = self.yy
        self.close()
Exemplo n.º 4
0
class TICPlot(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.handles = []
        self.ncr = dict()
        self.fileno = 0
        self.segments = []
        self.create_canvas()

    def create_canvas(self):
        self.fig = plt.figure()
        self.canvas = FigureCanvas(self.fig)
        self.axes = plt.subplot(111)
        self.axes.set_xlabel("Retention Time")
        self.axes.set_ylabel("Instensity")
        self.axes.tick_params(axis='both', labelsize=8)

        plt.subplots_adjust(bottom=0.25, top=0.90, left=0.08, right=0.9)
        self.zoom = RectangleSelector(self.axes,
                                      self.rectangle_select_callback,
                                      drawtype='box',
                                      useblit=True,
                                      button=[1],
                                      minspanx=5,
                                      minspany=5,
                                      spancoords='pixels')
        self.span = SpanSelector(self.axes,
                                 self.span_select_callback,
                                 'horizontal',
                                 minspan=0.002,
                                 useblit=True,
                                 rectprops=dict(alpha=0.5, facecolor='red'),
                                 onmove_callback=None,
                                 button=[1])
        axbasic = plt.axes([0.59, 0.04, 0.08, 0.075])
        axPan = plt.axes([0.7, 0.04, 0.08, 0.075])
        axPick = plt.axes([0.81, 0.04, 0.08, 0.075])
        self.btnBasic = Button(axbasic, 'Zoom')
        self.btnPan = Button(axPan, 'Span')
        self.btnPick = Button(axPick, 'Undo')
        axtic = plt.axes([0.92, 0.825, 0.06, 0.075])
        axext = plt.axes([0.92, 0.725, 0.06, 0.075])
        axres = plt.axes([0.92, 0.625, 0.06, 0.075])
        self.TICbutton = Button(axtic, 'TIC')
        self.EXTbutton = Button(axext, 'EXT')
        self.RESbutton = Button(axres, 'RES')

        vbox = QVBoxLayout()
        vbox.addWidget(self.canvas)
        self.setLayout(vbox)

        self.btnBasic.on_clicked(self.zoom_mode)
        self.btnPan.on_clicked(self.span_mode)
        self.btnPick.on_clicked(self.undo_mode)

        self.TICbutton.on_clicked(self.slot_tic)
        self.EXTbutton.on_clicked(self.slot_ext)
        self.RESbutton.on_clicked(self.slot_res)

        self.zoom_mode(True)
        self.redraw()
        ymino, ymaxo = self.axes.get_ylim()
        xmino, xmaxo = self.axes.get_xlim()
        self.oxy = [(xmino, xmaxo), (ymino, ymaxo)]

    def slot_tic(self, event):
        self.add_tic(self.ncr, self.fileno)

    def slot_ext(self, event):
        self.emit(SIGNAL("ext_plot"))

    def slot_res(self, event):
        self.emit(SIGNAL("res_plot"), )

    def add_tic(self, ncr, fn):
        if not len(self.segments):
            self.fn = fn
            self.ncr = ncr
            tic = self.ncr.tic()
            self.x = tic['rt']
            self.y = tic['val']
            self.axes.clear()
            self.axes.set_xlabel("Retention Time")
            self.axes.set_ylabel("Instensity")
            self.axes.set_title(str(fn), fontsize=9)
            self.axes.plot(self.x, self.y, lw=1, c='b', alpha=.7, picker=5)
            self.axes.set_xlim(min(self.x), max(self.x))
            self.axes.set_ylim(min(self.y), max(self.y) * 1.1)
            ymino, ymaxo = self.axes.get_ylim()
            xmino, xmaxo = self.axes.get_xlim()
            self.oxy = [(xmino, xmaxo), (ymino, ymaxo)]
            self.redraw()

    # def add_ext(self):

    def clear_data(self):
        self.axes.clear()
        self.axes.set_xlabel("Retention Time")
        self.axes.set_ylabel("Instensity")
        self.redraw()

    def redraw(self):
        self.canvas.draw()
        self.update()

    def zoom_mode(self, event):
        self.zoom.set_active(True)
        self.span.set_active(False)
        self.cidPress = self.canvas.mpl_connect('button_press_event',
                                                self.mouse_press_callback)
        self.cidRelease = self.canvas.mpl_connect('button_release_event',
                                                  self.mouse_release_callback)
        self.span.disconnect_events()
        self.leftdblclick = False
        self.rightdblclick = False
        self.redraw()
        print "zoom"

    def span_mode(self, event):
        self.zoom.set_active(False)
        self.span.set_active(True)
        self.span.connect_event('motion_notify_event', self.span.onmove)
        self.span.connect_event('button_press_event', self.span.press)
        self.span.connect_event('button_release_event', self.span.release)
        self.span.connect_event('draw_event', self.span.update_background)
        # self.span.connect_event('button_press_event', self.mouse_press_callback)
        self.rightdblclick = False
        self.leftdblclick = False
        self.rightdblclick = False
        self.redraw()
        print "span"

    def undo_mode(self, event):
        self.zoom.set_active(True)
        self.span.disconnect_events()
        self.cidPress = self.canvas.mpl_connect('button_press_event',
                                                self.mouse_press_callback)
        if len(self.segments) >= 1:
            self.emit(SIGNAL("delete_SELECT"), self.segments[-1])
            del self.axes.collections[:]
            self.segments = self.segments[:-1]
            self.select_inter(self.segments)
            if self.ind_right_press != 0:
                self.axes.vlines(self.xdata,
                                 self.oxy[1][0],
                                 self.oxy[1][1],
                                 color='g',
                                 linestyles='-')
            self.redraw()
        print "undo"

    def mouse_press_callback(self, event):
        if (event.button == 1 and event.dblclick == True):
            self.leftdblclick = True
        if event.button == 3:
            self.xdata = event.xdata
            self.ind_right_press = np.searchsorted(self.x, event.xdata)
            del self.axes.collections[:]
            self.axes.vlines(event.xdata,
                             self.oxy[1][0],
                             self.oxy[1][1],
                             color='g',
                             linestyles='-')
            self.select_inter(self.segments)
            self.redraw()
            self.emit(SIGNAL("MASS_SELECT"), self.ncr, self.ind_right_press)

    def select_inter(self, segments):
        for i in range(0, len(segments)):
            indmin, indmax = segments[i]
            self.axes.vlines(self.x[indmin],
                             self.oxy[1][0],
                             self.oxy[1][1],
                             color='r',
                             linestyles='--')
            self.axes.vlines(self.x[indmax],
                             self.oxy[1][0],
                             self.oxy[1][1],
                             color='r',
                             linestyles='--')

    def mouse_release_callback(self, event):
        if (self.leftdblclick):
            self.leftdblclick = False
            self.axes.set_xlim(self.oxy[0])
            self.axes.set_ylim(self.oxy[1])
            self.redraw()
        if (self.rightdblclick):
            self.rightdblclick = False
            del self.axes.collections[:]
            self.redraw()

    def rectangle_select_callback(self, eclick, erelease):
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata
        if eclick.button == 1 and erelease.button == 1:
            self.axes.set_xlim(min(x1, x2), max(x1, x2))
            self.axes.set_ylim(min(y1, y2), max(y1, y2))
            self.redraw()

    def span_select_callback(self, xmin, xmax):
        indmin, indmax = np.searchsorted(self.x, (xmin, xmax))
        indmax = min(len(self.x) - 1, indmax)
        self.segments.append((indmin, indmax))
        self.axes.vlines(xmin,
                         self.oxy[1][0],
                         self.oxy[1][1],
                         color='r',
                         linestyles='--')
        self.axes.vlines(xmax,
                         self.oxy[1][0],
                         self.oxy[1][1],
                         color='r',
                         linestyles='--')
        self.redraw()
        self.emit(SIGNAL("range_SELECT"), self.ncr, (indmin, indmax))

    def loading(self):
        self.axes.clear()
        self.axes.set_xlabel("Retention Time")
        self.axes.set_ylabel("Instensity")
        self.redraw()
        self.zoom_mode(True)
        ymino, ymaxo = self.axes.get_ylim()
        xmino, xmaxo = self.axes.get_xlim()
        self.oxy = [(xmino, xmaxo), (ymino, ymaxo)]