class MplWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MplWidget, self).__init__(parent)

        self.figure = Figure()
        
        self.ax = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        self.setLayout(layout)
        
        self.cb = None
        self.im = None
        self.imsz = None
        
    def imshow(self, img):
        if self.im:
            self.imsz = self.im.get_size()
            newsz = img.shape
            self.im.set_data(img)
            if self.imsz[0] != newsz[0] or self.imsz[1] != newsz[1]:    # update extent
                self.im.set_extent((-0.5, newsz[1]-0.5, newsz[0]-0.5, -0.5))            
        else:
            self.im = self.ax.imshow(img,interpolation='none')
        
        if self.cb:
            self.im.autoscale()
        else:
            self.cb = self.figure.colorbar(self.im)
            
        report_pixel = lambda x, y : "(%6.3f, %6.3f) %.3f" % (x,y, img[np.floor(y+0.5),np.floor(x+0.5)])
        self.ax.format_coord = report_pixel
            
        self.canvas.draw()
        self.canvas.flush_events()
class RoachPhaseStreamWindow(QMainWindow):

    thresholdClicked = QtCore.pyqtSignal()
    phaseSnapClicked = QtCore.pyqtSignal()
    phaseTimestreamClicked = QtCore.pyqtSignal()
    resetRoach = QtCore.pyqtSignal(int)
    
    def __init__(self,roach,config,parent=None):
        """
        Window for showing snapshot of phase timestream of resonators
        
        INPUTS:
            roach - A RoachStateMachine Object. We need this to access all the relevent settings
            config - ConfigParser object
            parent - Leave as default
        """
        QMainWindow.__init__(self,parent=parent)
        self._want_to_close = False
        self.roach=roach
        self.roachNum = self.roach.num
        self.config = config
        self.setWindowTitle('r'+str(self.roachNum)+': Phase Timestream')
        
        self.create_main_frame()
        
        self.snapDataList = []
        self.phaseNoiseDataList = []
        self.oldPhaseNoiseDataList = []
        self.thresholdDataList = []

        
        self.roach.snapPhase.connect(self.plotSnap)
        self.roach.timestreamPhase.connect(self.plotPhaseNoise)
    
    def initFreqs(self):
        """
        After we've loaded the frequency file in RoachStateMachine object then we can initialize some GUI elements
        """
        freqs = self.roach.roachController.freqList
        ch=self.spinbox_channel.value()
        
        self.spinbox_channel.setRange(0,len(freqs)-1)
        self.label_freq.setText('Freq: '+str(freqs[ch]/1.e9)+' GHz')
        
        if len(self.snapDataList)!=len(freqs):
            self.snapDataList = [None]*len(freqs)
        if len(self.phaseNoiseDataList)!=len(freqs):
            self.phaseNoiseDataList = [None]*len(freqs)
        if len(self.oldPhaseNoiseDataList)!=len(freqs):
            self.oldPhaseNoiseDataList = [None]*len(freqs)    
    
    def initThresh(self):
        """
        After we've loaded the thresholds we can show them
        Also everytime we change the channel we need to replot
        """
        try:
            ch=self.spinbox_channel.value()
            #thresh = self.roach.roachController.thresholds[ch]
            thresh = self.thresholdDataList[ch]
            self.label_thresh.setText('Threshold: '+str(thresh)+' deg')
            self.plotSnap()
        except:
            pass
    
    def appendThresh(self, thresholds):
        '''
        This function is called whenever the roach finishes a load threshold command
        
        INPUTS:
            thresholds - [nFreqs, 1] list of thresholds for each channel in radians
        '''
        self.thresholdDataList = thresholds
        self.initThresh()
    
    def plotPhaseNoise(self,ch=None, data=None,**kwargs):
        #self.spinbox_channel.setEnabled(False)
        currentCh = self.spinbox_channel.value()
        if ch is None: ch=currentCh
        if data is not None:
            self.appendPhaseNoiseData(ch,data)
        if self.isVisible() and ch==currentCh:
            self.makePhaseNoisePlot(**kwargs)
            self.draw()
        #self.spinbox_channel.setEnabled(True)
    
    def appendPhaseNoiseData(self, ch, data):
        fftlen = self.config.getint('Roach '+str(self.roachNum),'nLongsnapFftSamples')
        nFftAvg = int(np.floor(len(data)/fftlen))
        noiseData = np.zeros(fftlen)
        
        data = np.reshape(data[:nFftAvg*fftlen],(nFftAvg,fftlen))
        noiseData=np.fft.rfft(data)
        noiseData=np.abs(noiseData)**2  #power spectrum
        noiseData = 1.*np.average(noiseData,axis=0)/fftlen
        
        if np.all(noiseData>0):
            print 'Adding noise Data'
            if self.phaseNoiseDataList[ch] is not None: 
                print 'adding old noise data'
                self.oldPhaseNoiseDataList[ch] = np.copy(self.phaseNoiseDataList[ch])
            self.phaseNoiseDataList[ch]=noiseData
        else:
            print "Phase noise was all zeros!"
    
    def makePhaseNoisePlot(self, **kwargs):
        ch = self.spinbox_channel.value()
        
        fftlen = self.config.getint('Roach '+str(self.roachNum),'nLongsnapFftSamples')
        if self.oldPhaseNoiseDataList[ch] is not None:
            ydata = np.copy(self.oldPhaseNoiseDataList[ch])
            dt = 1.*self.roach.roachController.params['nChannelsPerStream']/self.roach.roachController.params['fpgaClockRate']
            x = np.fft.rfftfreq(fftlen,dt)
            self.line2.set_data(x,ydata)
            self.ax1.relim()
            self.ax1.autoscale_view(True,True,True)
        else:
            self.line2.set_data([],[])
        
        if self.phaseNoiseDataList[ch] is not None:
            ydata = np.copy(self.phaseNoiseDataList[ch])
            dt = 1.*self.roach.roachController.params['nChannelsPerStream']/self.roach.roachController.params['fpgaClockRate']
            x = np.fft.rfftfreq(fftlen,dt)
            self.line1.set_data(x,ydata)
            self.ax1.relim()
            self.ax1.autoscale_view(True,True,True)
        else:
            self.line1.set_data([],[])    
    
    def phaseTimeStream(self):
        """
        This function executes when you press the collect phase timestream button.
        After running any commands that need running, it gets a new phase timestream and plots the noise
        
        Works similiarly to phaseSnapShot()
        """
        ch=self.spinbox_channel.value()
        timelen = self.config.getfloat('Roach '+str(self.roachNum),'longsnaptime')
        QtCore.QMetaObject.invokeMethod(self.roach, 'getPhaseStream', Qt.QueuedConnection,
                                        QtCore.Q_ARG(int, ch),QtCore.Q_ARG(float, timelen))
        self.phaseTimestreamClicked.emit()
        
    def plotSnap(self,ch=None, data=None,**kwargs):
        self.spinbox_channel.setEnabled(False)
        currentCh = self.spinbox_channel.value()
        if ch is None: ch=currentCh
        if data is not None:
            self.appendSnapData(ch,data)
        if self.isVisible() and ch==currentCh:
            self.makeSnapPlot(**kwargs)
            self.draw()
        self.spinbox_channel.setEnabled(True)
    
    def appendSnapData(self,ch,data):
        self.snapDataList[ch]=data

    
    def makeSnapPlot(self,**kwargs):
        ch = self.spinbox_channel.value()
        self.ax2.clear()
        if self.snapDataList[ch] is not None:
            snapDict = self.snapDataList[ch]
            t = np.asarray(snapDict['time'])*1.e6
            data=np.asarray(snapDict['phase'])
            #print snapDict['trig']
            #print np.where(np.asarray(snapDict['time']))
            #print np.where(np.asarray(snapDict['time'])>0)
            trig=np.asarray(snapDict['trig'])
            data*=180./np.pi
            fmt = 'b.-'
            self.ax2.plot(t, data, fmt,**kwargs)
            print 'nPhotons: ',np.sum(trig)
            self.ax2.plot(t[np.where(trig)], data[np.where(trig)], 'ro')
            median=np.median(data)
            self.label_median.setText('Median: '+str(median)+' deg')
            self.ax2.axhline(y=median,color='k')
            try:
                #thresh = self.roach.roachController.thresholds[ch]*180./np.pi
                thresh = self.thresholdDataList[ch]
                thresh*=180./np.pi
                #self.ax2.axhline(y=median-thresh,color='r')
                self.ax2.axhline(y=median+thresh,color='r')
            except:
                pass
        self.ax2.set_xlabel('Time [us]')
        self.ax2.set_ylabel('Phase [deg]')
    
    def phaseSnapShot(self):
        """
        This function executes when you press the phase snap button.
        After running any commands that need running, it gets a new phase snap shot and plots it
        
        The way it works is: 
            The RoachStateMachine object is told that we want to run the function getPhaseFromSnap()
            But it won't run unless the roach thread is in it's event loop. 
            We emit a signal to the HighTemplar GUI telling it we want the phase snap shot
            
            --That's the end of this function-- (but next...)
            
            HighTemplar tells the RoachStateMachine object to add all commands (as if you clicked a button 1 below load thresholds)
            Then HighTemplar starts the roach thread's event loop
            The roach thread automatically starts executing any needed commands in it's queue (ie. loadFreq, DefineLUT, etc..)
            When the commands are done executing it executes anything waiting for the thread event loop (ie. getPhaseFromSnap())
            getPhaseFromSnap() runs on the RoachStateMachine object and when done emits a snapPhase signal with the data
            This window object sees that signal and updates the plot
        """
        ch=self.spinbox_channel.value()
        QtCore.QMetaObject.invokeMethod(self.roach, 'getPhaseFromSnap', Qt.QueuedConnection,
                                        QtCore.Q_ARG(int, ch))
        self.phaseSnapClicked.emit()
    
    def create_main_frame(self):
        """
        Makes GUI elements on the window
        
        
        """
        self.main_frame = QWidget()
        
        self.dpi = 100
        self.fig = Figure((9.0, 5.0), dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.main_frame)
        self.ax1 = self.fig.add_subplot(211)
        self.ax1.set_ylabel('Noise Power Spectrum')
        self.ax1.set_xlabel('f [Hz]')
        self.line2, = self.ax1.loglog([],[],color='cyan')
        self.line1, = self.ax1.loglog([],[],color='blue')       # line 1 on top of line 2
        self.ax2 = self.fig.add_subplot(212)
        self.ax2.set_xlabel('Time [us]')
        self.ax2.set_ylabel('Phase [Deg]')
        
        
        # Create the navigation toolbar, tied to the canvas
        self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)
        
        
        label_channel = QLabel('Channel:')
        self.spinbox_channel = QSpinBox()       #initializes to 0
        self.spinbox_channel.setRange(0,0)      #set the range after we read the freq file
        self.spinbox_channel.setWrapping(True)
        self.spinbox_channel.valueChanged.connect(lambda x: self.plotSnap())
        self.spinbox_channel.valueChanged.connect(lambda x: self.plotPhaseNoise())
        self.spinbox_channel.valueChanged.connect(lambda x: self.initFreqs())
        self.spinbox_channel.valueChanged.connect(lambda x: self.initThresh())
        
        self.label_freq = QLabel('Freq: 0 GHz')
        self.label_freq.setMinimumWidth(150)
        self.label_freq.setMaximumWidth(150)
        self.label_thresh = QLabel('Thresh: 0 deg')
        self.label_thresh.setMinimumWidth(150)
        self.label_thresh.setMaximumWidth(150)
        self.label_median = QLabel('Median: 0 deg')
        
        button_snapPhase = QPushButton("Phase Snapshot")
        button_snapPhase.setEnabled(True)
        button_snapPhase.clicked.connect(self.phaseSnapShot)
        
        
        numSnapsThresh = self.config.getint('Roach '+str(self.roachNum),'numsnaps_thresh')
        spinbox_numSnapsThresh = QSpinBox()
        spinbox_numSnapsThresh.setValue(numSnapsThresh)
        spinbox_numSnapsThresh.setRange(1,100)
        spinbox_numSnapsThresh.setSuffix(" *2 msec")
        spinbox_numSnapsThresh.setWrapping(False)
        spinbox_numSnapsThresh.setButtonSymbols(QAbstractSpinBox.NoButtons)
        spinbox_numSnapsThresh.setCorrectionMode(QAbstractSpinBox.CorrectToNearestValue)
        spinbox_numSnapsThresh.valueChanged.connect(partial(self.changedSetting,'numsnaps_thresh'))
        
        threshSigs = self.config.getfloat('Roach '+str(self.roachNum),'numsigs_thresh')
        spinbox_threshSigs = QDoubleSpinBox()
        spinbox_threshSigs.setValue(threshSigs)
        spinbox_threshSigs.setRange(0,100)
        spinbox_threshSigs.setSuffix(" sigmas")
        spinbox_threshSigs.setWrapping(False)
        spinbox_threshSigs.setButtonSymbols(QAbstractSpinBox.NoButtons)
        spinbox_threshSigs.setCorrectionMode(QAbstractSpinBox.CorrectToNearestValue)
        spinbox_threshSigs.valueChanged.connect(partial(self.changedSetting,'numsigs_thresh'))
        spinbox_threshSigs.valueChanged.connect(lambda x: self.resetRoach.emit(RoachStateMachine.LOADTHRESHOLD))       # reset state of roach
        
        button_loadThresh = QPushButton("Load Thresholds")
        button_loadThresh.setEnabled(True)
        button_loadThresh.clicked.connect(self.thresholdClicked)
        
        longSnapTime = self.config.getfloat('Roach '+str(self.roachNum),'longsnaptime')
        spinbox_longSnapTime = QDoubleSpinBox()
        spinbox_longSnapTime.setValue(longSnapTime)
        spinbox_longSnapTime.setRange(0,1000)
        spinbox_longSnapTime.setSuffix(" seconds")
        spinbox_longSnapTime.setWrapping(False)
        spinbox_longSnapTime.setButtonSymbols(QAbstractSpinBox.NoButtons)
        spinbox_longSnapTime.setCorrectionMode(QAbstractSpinBox.CorrectToNearestValue)
        spinbox_longSnapTime.valueChanged.connect(partial(self.changedSetting,'longsnaptime'))
        
        button_longSnap = QPushButton("Collect Phase Timestream")
        button_longSnap.setEnabled(True)
        button_longSnap.clicked.connect(self.phaseTimeStream)
        
        vbox_plot = QVBoxLayout()
        vbox_plot.addWidget(self.canvas)
        vbox_plot.addWidget(self.mpl_toolbar)
        
        hbox_ch = QHBoxLayout()
        hbox_ch.addWidget(label_channel)
        hbox_ch.addWidget(self.spinbox_channel)
        hbox_ch.addWidget(self.label_freq)
        hbox_ch.addWidget(self.label_thresh)
        hbox_ch.addWidget(self.label_median)
        hbox_ch.addWidget(button_snapPhase)
        hbox_ch.addStretch()
        
        hbox_thresh = QHBoxLayout()
        hbox_thresh.addWidget(spinbox_numSnapsThresh)
        hbox_thresh.addWidget(spinbox_threshSigs)
        hbox_thresh.addWidget(button_loadThresh)
        hbox_thresh.addStretch()
        
        hbox_phaseTimestream = QHBoxLayout()
        hbox_phaseTimestream.addWidget(spinbox_longSnapTime)
        hbox_phaseTimestream.addWidget(button_longSnap)
        hbox_phaseTimestream.addStretch()
        
        vbox1 = QVBoxLayout()
        vbox1.addLayout(vbox_plot)
        vbox1.addLayout(hbox_ch)
        vbox1.addLayout(hbox_thresh)
        vbox1.addLayout(hbox_phaseTimestream)
        
        self.main_frame.setLayout(vbox1)
        self.setCentralWidget(self.main_frame)
    
    def draw(self):
        #print 'r'+str(self.roachNum)+' drawing data - '+str(self.counter)
        self.canvas.draw()
        self.canvas.flush_events()
    
    def changedSetting(self,settingID,setting):
        """
        When a setting is changed, reflect the change in the config object which is shared across all GUI elements.
        
        INPUTS:
            settingID - the key in the configparser
            setting - the value
        """
        self.config.set('Roach '+str(self.roachNum),settingID,str(setting))
        #If we don't force the setting value to be a string then the configparser has trouble grabbing the value later on for some unknown reason
        newSetting = self.config.get('Roach '+str(self.roachNum),settingID)
        print 'setting ',settingID,' to ',newSetting
    
    def closeEvent(self, event):
        if self._want_to_close:
            event.accept()
            self.close()
        else:
            event.ignore()
            self.hide()
예제 #3
0
class mpl_widget(QWidget):
    def __init__(self, parent=None, mainWidget=None):
        self._SELECTEDCELLS = list()       # container for instances of selected cells, so we can delete them when we want
        self._SELECTEDCELLS_IJ = list()  # container for coords of selected cells, so we can delete them when we want
        self._SELECTEDCELLLINES = list()   # container for instances of selected cells, so we can delete them when we want
        self._GRIDLINES = None
        QWidget.__init__(self, parent)
        self.mainWidget = mainWidget
        self.create_main_frame()
        self.mpl_menu = mpl_menu(self)
        self.shift_is_held = False
        #self.connect(self.mpl_menu, QtCore.SIGNAL('mySignal'), self.mySlot)
        #print 'my parent is:', parent
        self.clear_selection()
        self.init_tooltips()

    def init_tooltips(self):
        self.canvas.setToolTip('If 2D plot => RMB click toggles menu <br> - RMB click selects cell <br> - selected cells are drawn with black border')
        self.grid_cb.setToolTip('If 2D plot => show computational grid <br> If 1D plot => show normal gridlines')
        self.cbar_button.setToolTip('If 2D plot => controls the color range. <br> Note: <br> - pressing UP and DOWN arrows cycles through colormaps <br> - dragging colorbar with RMB scales the color-range <br> - dragging colorbar with LMB shifts the color-range')
        self.mpl_toolbar.setToolTip('Shows coordinates (i,j, lat,lon) and data-value(z) under the cursor. <br> if you see <i>>>></i> coordinates are not visible. Enlarge the window')

    def create_main_frame(self):

        self.fig = Figure(dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.canvas.setFocusPolicy( Qt.ClickFocus )
        self.canvas.setFocus()

        self.mpl_toolbar = myNavigationToolbar(self.canvas, self)
        self.canvas.mpl_connect('button_press_event', self.on_click)
        self.canvas.mpl_connect('key_press_event', self.on_key_press)
        self.canvas.mpl_connect('key_release_event', self.on_key_release)
        #self.canvas.mpl_connect('button_press_event', self.disable_clicks)


        self.cbar_button = QPushButton("Color Range")
        self.cbar_button.setFocusPolicy( Qt.NoFocus )
        self.grid_cb = QCheckBox("Show Grid")
        self.grid_cb.setFocusPolicy( Qt.NoFocus )
        self.grid_cb.stateChanged.connect(self.showGrid)

        vbox = QVBoxLayout()
        hbox = QHBoxLayout()

        vbox.addWidget(self.canvas)  # the matplotlib canvas
        hbox.addWidget(self.mpl_toolbar)
        hbox.addWidget(self.cbar_button)
        hbox.addWidget(self.grid_cb)
        vbox.addLayout(hbox)
        self.setLayout(vbox)



    def on_click(self, event):
        if event.inaxes != self.get_axes()[0]: return
        #if self.get_axes()[0].format_coord(event.x, event.y) == 'outside data area': return
        if self.allow_menu():
            self.allow_popup_menu = True
            if self.shift_is_held:
                self.allow_popup_menu = False

            point = [int(event.xdata + .5), int(event.ydata + .5)]
            #print '>>>', point, '\t currently {0} selected'.format(len(self._SELECTEDCELLS))
            if event.button == 3 :  #if RMB is clicked

                # working with dialog for transect!
                if self.mainWidget.transect_dlg:
                    if self.mainWidget.transect_dlg.toogle_show_after_selected_cell:
                        realx, realy = self.get_real_xy(event.xdata, event.ydata, self.mainWidget.detect_variable_dimensions())
                        realpoint = [realy, realx]
                        #print 'real xy:', realpoint
                        if self.mainWidget.transect_dlg.toogle_show_after_selected_cell == 1:  # select point 1
                            self.allow_popup_menu = False
                            self.mainWidget.transect_dlg.data.set_p1(realpoint)
                        elif self.mainWidget.transect_dlg.toogle_show_after_selected_cell == 2:  # select point 2
                            self.allow_popup_menu = False
                            self.mainWidget.transect_dlg.data.set_p2(realpoint)

                        self.mainWidget.transect_dlg.update()
                        self.mainWidget.transect_dlg.show()
                
                # working with dialog for flux!
                if self.mainWidget.flux_dlg:
                    if self.mainWidget.flux_dlg.toogle_show_after_selected_cell:
                        if self.mainWidget.flux_dlg.toogle_show_after_selected_cell == 1:  # select point 1
                            self.allow_popup_menu = False
                            self.mainWidget.flux_dlg.data.set_p1(point)
                        elif self.mainWidget.flux_dlg.toogle_show_after_selected_cell == 2:  # select point 2
                            self.allow_popup_menu = False
                            self.mainWidget.flux_dlg.data.set_p2(point)

                        self.mainWidget.flux_dlg.update()
                        self.mainWidget.flux_dlg.show()



                if len(self._SELECTEDCELLS) == 0:  # if no cell is selected
                    self.add_selected_cell(point)


                else:  # if some cells are already selected
                    if self.mpl_menu.allow_rmb_select_cells() or self.shift_is_held:
                        # check if this point is already selected:
                        already_selected = False
                        for p in self._SELECTEDCELLS_IJ:
                            if (point[0] == p[0]) and (point[1] == p[1]):
                                already_selected = True
                                print 'cell already selected... is not added'

                        if not already_selected:
                            self.add_selected_cell(point)
                    else:
                        pass
                        #self.clear_selection()
                        #self.add_selected_cell(point)

    def cells_selected(self):
        if self._SELECTEDCELLS: return len(self._SELECTEDCELLS)
        else: return False

    def add_selected_cell(self, point):
        ''' point = [i, j]'''
        print 'selected cell:', point[0], point[1]
        c = self.draw_picked_cell(point)
        self._SELECTEDCELLS.append(c)
        self._SELECTEDCELLS_IJ.append(point)




    def get_selected_cells_ij(self):
        return self._SELECTEDCELLS_IJ

    def clear_selection(self):
        '''
        delete all graphical objects of selected cells
        redraw canvas
        '''
        print 'clearing stuff'
        if len(self._SELECTEDCELLLINES) > 0:
            for line in self._SELECTEDCELLLINES:
                l = line.pop(0)
                l.remove()
                del l
            del self._SELECTEDCELLLINES[:]
        #print 'cells ---- before:', len(self._SELECTEDCELLS)
        if len(self._SELECTEDCELLS) > 0:
            for cell in self._SELECTEDCELLS:
                for line in cell:
                    l = line.pop(0)
                    l.remove()
                    del l
            del self._SELECTEDCELLS[:]
        #print 'cells ---- left:', len(self._SELECTEDCELLS)


        #print 'cells-coords ----'
        #print len(self._SELECTEDCELLS_IJ)
        if self._SELECTEDCELLS_IJ:
            for cellcoords in self._SELECTEDCELLS_IJ:
                #cc = cellcoords.pop(0)
                #cellcoords.remove()
                del cellcoords
            del self._SELECTEDCELLS_IJ[:]
        #print 'cells ---- left,', len(self._SELECTEDCELLS_IJ)



        if len(self._SELECTEDCELLS) != 0:
            raise ValueError('List "self._SELECTEDCELLS" was not flushed')

        if len(self._SELECTEDCELLLINES) != 0:
            raise ValueError('List "self._SELECTEDCELLLINES" was not flushed')

        if len(self._SELECTEDCELLS_IJ) != 0:
            raise ValueError('List "self._SELECTEDCELLLINES" was not flushed')
        # update plot
        self.canvas.draw()
        #print 'finishing clear: cells left', len(self._SELECTEDCELLS)


    def showGrid(self, state):
        if self.fig.axes:
            current_plot = self.mainWidget.get_plotType()
            current_plot2D = self.mainWidget.get_plotType_for_timeseries()
            if state == Qt.Checked:
                if current_plot == '1D' or (current_plot2D =="2DZT"):
                    self.fig.axes[0].grid(True)
                elif current_plot == '2D' and (not current_plot2D =="2DZT"):
                    self.draw_pixel_grid(True)
            else:
                if current_plot == '1D' or (current_plot2D =="2DZT"):
                    self.fig.axes[0].grid(False)
                elif current_plot == '2D' and (not current_plot2D =="2DZT"):
                    self.draw_pixel_grid(False)
            self.canvas.draw()

    def draw_picked_cell(self, point):
        x = point[0]
        y = point[1]
        '''
        approach drawing a patch... not working
        cell_bnd = patches.Rectangle((x-.5, y-.5), 1, 1, fill=False, edgecolor="black", hatch=None, linewidth=1.)
        cell_instance = self.fig.axes[0].add_patch(cell_bnd)
        '''

        b_line = [(x-.5, x+.5), (y-.5, y-.5)]
        r_line = [(x+.5, x+.5), (y-.5, y+.5)]
        t_line = [(x-.5, x+.5), (y+.5, y+.5)]
        l_line = [(x-.5, x-.5), (y-.5, y+.5)]
        cell = [b_line, r_line, t_line, l_line]
        for i, l in enumerate(cell):
            ll = self.fig.axes[0].plot(l[0], l[1], 'k-', lw=.8)
            cell[i] = ll  # overwriting current Line2D object with object binded to an axes
        #self._SELECTEDCELLS.append(cell)  # collecting reference to this cell to be able to delete it
        #self._SELECTEDCELLS_IJ.append(point)  # collecting reference to this cell to be able to delete it

        self.canvas.draw()
        return cell


    def draw_line(self, point1, point2):
        line = [(point1[0], point2[0]), (point1[1], point2[1])]
        l = self.fig.axes[0].plot(line[0], line[1], 'k-', lw=2)
        return l

    def draw_pixel_grid(self, enable=True):
        if enable:
            dx = 1
            dy = 1
            x0 = -.5
            y0 = -.5

            if self.mainWidget.get_plotType_for_timeseries() == '2DXY':
                nx = self.mainWidget.get_nX()
                ny = self.mainWidget.get_nY()
            elif self.mainWidget.get_plotType_for_timeseries() == '2DZY':
                nx = self.mainWidget.get_nY()
                ny = self.mainWidget.get_nZ()
            elif self.mainWidget.get_plotType_for_timeseries() == '2DZX':
                nx = self.mainWidget.get_nX()
                ny = self.mainWidget.get_nZ()

            self._GRIDLINES = list()
            for n_hline in np.arange(ny+1):
                hline = [(x0, x0+nx), (y0+n_hline, y0+n_hline)]
                l = self.fig.axes[0].plot(hline[0], hline[1], 'k-', lw=.2)
                self._GRIDLINES.append(l)  # collecting reference to this line to be able to delete it

            for n_vline in np.arange(nx+1):
                vline = [(x0+n_vline, x0+n_vline), (y0, y0+ny)]
                l = self.fig.axes[0].plot(vline[0], vline[1], 'k-', lw=.2)
                self._GRIDLINES.append(l)  # collecting reference to this line to be able to delete it


        if not enable:
            #print 'deleting lines...'
            if self._GRIDLINES:  # if lines were created
                #print 'lines are here...'
                for line in self._GRIDLINES:
                    #print line
                    l = line.pop(0)
                    l.remove()
                    del l
            self.fig.canvas.draw()

    def on_key_press(self, event):
        #print 'key pressed:', event.key
        if event.key == 'shift':
            self.shift_is_held = True


    

    def on_key_release(self, event):
        #print 'key released:', event.key
        if event.key == 'shift':
            self.shift_is_held = False

        elif event.key == 'escape':
            self.clear_selection()


    def change_coordinate_formatter(self, ax, data2d,  bruteforce_flag=None, bruteforce_dims=None):
        ''' see http://stackoverflow.com/questions/14754931/matplotlib-values-under-cursor
        '''
        numrows, numcols = data2d.shape
        bruteforce_mode_on = False
        bruteforce_mode_on = (bruteforce_flag == '2DXY' and bruteforce_dims[-1] and bruteforce_dims[-2])


        def format_coord(x, y):
            col = int(x+0.5)
            row = int(y+0.5)

            if not bruteforce_mode_on:
                if col >= 0 and col < numcols and row >= 0 and row < numrows:
                    #z = data2d[row, col]
                    # sice we have artificially reversed y-coordinate axes, now reverse data!
                    # numrows-1, because if nrows=10 => row=[0:9]
                    z = data2d[numrows-1-row, col]
                    #return 'x=%1.1f y=%1.1f z=%1.6f' % (x, y, z)
                    return 'i=%d j=%d z=%.6f' % (col, row, z)
                else:
                    #return 'x=%1.4f, y=%1.4f' % (x, y)
                    return 'outside data area'

            elif bruteforce_flag == '2DXY' and bruteforce_dims[-1] and bruteforce_dims[-2]:
                '''
                our extend in X=[-0.5:numcols-0.5], Y=[-0.5:numrows-0.5], because col,row is cell center!
                '''
                if col >= 0 and col < numcols and row >= 0 and row < numrows:
                    #z = data2d[row, col]
                    # sice we have artificially reversed y-coordinate axes, now reverse data!
                    # numrows-1, because if nrows=10 => row=[0:9]
                    z = data2d[numrows-1-row, col]
                    real_x, real_y = self.get_real_xy(x, y, bruteforce_dims)

                    #return 'x=%1.1f y=%1.1f z=%1.6f' % (x, y, z)
                    #return 'i=%d j=%d z=%.3f x=%.4f y=%.4f' % (col, row, z, real_x, real_y)
                    return 'i=%d j=%d z=%.3f, %s=%.2f %s=%.2f' % (
                        col, row, z, bruteforce_dims[-1], real_x, bruteforce_dims[-2], real_y)
                else:
                    #return 'x=%1.4f, y=%1.4f' % (x, y)
                    return 'outside data area'
            else:
                raise ValueError('bruteforce_flag can be $None$ or $"2DXY"$. Passed %s' % bruteforce_flag)
        ax.format_coord = format_coord


    def allow_menu(self):
        allow = False
        #print "self.mainWidget.get_plotType():", self.mainWidget.get_plotType()
        #print "self.mainWidget.get_plotType_for_timeseries():", self.mainWidget.get_plotType_for_timeseries()
        if self.mainWidget.get_plotType() == "2D" and not self.mainWidget.get_plotType_for_timeseries() == "2DZT":
            allow = True
        return allow
    

    def get_real_xy(self, i, j, dimension_list):
        '''
        functions returns values of x,y based on passed indexes i, j

        '''
        if any(dimension_list[-2:-1]) is None:
            print 'Dimensions X,Y of current variable are not specified (variables that have same name as dimensions not found)'
            raise ValueError('Dimensions X,Y of current variable are not specified (variables that have same name as dimensions not found)')
        nc = self.mainWidget.get_selected_ncfile_instance()
        try:
            x_var = nc.variables[dimension_list[-1]]
            y_var = nc.variables[dimension_list[-2]]
            
        except:
            
            print ('Failed to load variables: {0}, {1}'.format(dimension_list[-1], dimension_list[-2]))
            raise ValueError('Failed to load variables: {0}, {1}'.format(dimension_list[-1], dimension_list[-2]))


        x_ratio = (x_var[-1]-x_var[0])/(len(x_var)-1)
        y_ratio = (y_var[-1]-y_var[0])/(len(y_var)-1)

        #x[i] = x_var[0]+x_ratio*i
        #y[j] = y_var[0]+y_ratio*j
        x = x_var[0] + x_ratio*i
        y = y_var[0] + y_ratio*j
        nc.close()
        return (x, y)

    def get_axes(self):
        return self.fig.get_axes()
    

    def fast_redraw(self, artist):
        background = [self.canvas.copy_from_bbox(self.get_axes()[0].bbox)]
        self.get_axes()[0].draw_artist(artist)
        self.canvas.restore_region(background)
        self.canvas.blit(self.get_axes()[0].bbox)
        self.canvas.update()
        self.canvas.flush_events()
예제 #4
0
class Main(QMainWindow, Ui_MainWindow):
	def __init__(self, ):
		super(Main, self).__init__()
		self.setupUi(self)
		self.pushButton_Start.clicked.connect(self.StartButton)
		self.pushButton_Stop.clicked.connect(self.StopButton)
		#self.pushButton_Start.setIcon(QtGui.QIcon('/home/insu13.yu/Works/PyQT/QtDesign/EmbedQtChart/start.png'))
		#self.pushButton_Stop.setIcon(QtGui.QIcon('/home/insu13.yu/Works/PyQT/QtDesign/EmbedQtChart/stop.png'))
		#self.pushButton_Start.setGeometry(200,20, 50,40)
		self.mCPU0 = []
		self.mCPU1 = []
		self.mCPU2 = []
		self.mCPU3 = []
		self.mCPU4 = []
		self.mCPU5 = []
		self.mCPU6 = []
		self.mCPU7 = []

		self.mDVFS_Max 	= []
		self.mDVFS_Min 	= []
		self.mDDR 		= []
		self.mBUS 		= []
		self.mGPUFreq 	= []
		self.mGPUUtil 	= []
		self.mAPT 		= []
		self.mPST 		= []
		self.mCPUG0 	= []
		self.mCPUG1 	= []
		self.mGPU 		= []
		#time index
		self.timeindex 	= 0

		#init CPU information panel
		self.fig1 = Figure()
		self.canvas1 = FigureCanvas(self.fig1)
		self.Layout_CPU.addWidget(self.canvas1)

		self.ax1 = [ self.fig1.add_subplot(811), self.fig1.add_subplot(812), self.fig1.add_subplot(813), self.fig1.add_subplot(814),
					 self.fig1.add_subplot(815), self.fig1.add_subplot(816), self.fig1.add_subplot(817), self.fig1.add_subplot(818)	]
		
		#init System information panel
		self.fig2 = Figure()
		self.canvas2 = FigureCanvas(self.fig2)
		self.Layout_System.addWidget(self.canvas2)

		# make plots
		self.ax2  = [ self.fig2.add_subplot(811), self.fig2.add_subplot(812), self.fig2.add_subplot(813), self.fig2.add_subplot(814),
					  self.fig2.add_subplot(815), self.fig2.add_subplot(816), self.fig2.add_subplot(817), self.fig2.add_subplot(818) ]

		# draw horizontal line
		#ax[0].axhline(y=0.5, xmin=0, xmax=1, color='#FF0000', linewidth=4)
			
		# draw vertical line
		#ax[0].axvline(x=50, ymin=0, ymax=1, color='#006000', linewidth=4)

			

	def setup_CPU_chart(self):
		## add navigation toolbar		
		#self.toolbar = NavigationToolbar(canvas, self.mplwindow, coordinates=True)
		#self.mplvl.addWidget(self.toolbar)
 
		# make plots
		for i in xrange(0,8):
			self.ax1[i].clear()
			# ============================================
			# Setup chart properties, tick and grid etcs
			# ============================================
			ticklines = self.ax1[i].get_xticklines()
			ticklines.extend( self.ax1[i].get_yticklines() )
			gridlines = self.ax1[i].get_xgridlines()
			gridlines.extend( self.ax1[i].get_ygridlines() )
			ticklabels = self.ax1[i].get_xticklabels()
			ticklabels.extend( self.ax1[i].get_yticklabels() )

			for line in ticklines:
				line.set_color('#00C040')
				line.set_linewidth(1)

			for line in gridlines:
				line.set_color('#00C040')
				line.set_linestyle('-')			

			for label in ticklabels:
				label.set_color('#404040') # drak grey
				label.set_fontsize('8') # or 'small'

			#self.ax1[0].axis([0,100,0,2100])
			self.ax1[i].set_autoscale_on(False)

			# show grid
			self.ax1[i].grid(True)

			# set your xticks manually (10 ticks)
			self.ax1[i].xaxis.set_ticks(numpy.arange(0,100,2.5)) # [i for i in range(0,100, 10)]

			# set your yticks manually (10 ticks)
			self.ax1[i].yaxis.set_ticks(numpy.arange(0, 1401 if i < 4 else 2201, 200))
			
			# remove label
			self.ax1[i].set_xticklabels([])

			self.ax1[i].set_axis_bgcolor((0, 0, 0))

		# Y labels
		self.ax1[0].set_ylabel('CPU0')
		self.ax1[1].set_ylabel('CPU1')
		self.ax1[2].set_ylabel('CPU2')
		self.ax1[3].set_ylabel('CPU3')
		self.ax1[4].set_ylabel('CPU4')
		self.ax1[5].set_ylabel('CPU5')
		self.ax1[6].set_ylabel('CPU6')
		self.ax1[7].set_ylabel('CPU7')

		self.fig1.subplots_adjust(left=0.10, bottom=0.03, right=0.98, top=0.99, wspace=0.2, hspace=0.1)
		

	def setup_System_chart(self):
		## add navigation toolbar		
		#self.toolbar = NavigationToolbar(canvas, self.mplwindow, coordinates=True)
		#self.mplvl.addWidget(self.toolbar)

		for i in xrange(0,8):
			# ============================================
			# Setup chart properties, tick and grid etcs
			# ============================================
			ticklines = self.ax2[i].get_xticklines()
			ticklines.extend( self.ax2[i].get_yticklines() )
			gridlines = self.ax2[i].get_xgridlines()
			gridlines.extend( self.ax2[i].get_ygridlines() )
			ticklabels = self.ax2[i].get_xticklabels()
			ticklabels.extend( self.ax2[i].get_yticklabels() )

			for line in ticklines:
				line.set_color('#00C040')
				line.set_linewidth(1)

			for line in gridlines:
				line.set_color('#00C040')
				line.set_linestyle('-')			

			for label in ticklabels:
				label.set_color('#404040') # drak grey
				if(i == 0 or i == 1):
					label.set_fontsize('8') # or 'small'
				else:
					label.set_fontsize('9') # or 'small'

			# show grid
			self.ax2[i].grid(True)
			
			# set your xticks manually (10 ticks)
			self.ax2[i].xaxis.set_ticks(numpy.arange(0,100,3)) # [i for i in range(0,100, 10)]
		
			# remove label
			self.ax2[i].set_xticklabels([])

			self.ax2[i].set_axis_bgcolor((0, 0, 0))
			
			self.ax2[i].set_autoscale_on(False)
			

		# Y ticks
		self.ax2[0].yaxis.set_ticks(numpy.arange(0, 1201, 200)) # DVFS
		self.ax2[1].yaxis.set_ticks(numpy.arange(0, 1301, 200)) # DDR
		self.ax2[2].yaxis.set_ticks(numpy.arange(0, 1001, 100)) # BUS
		self.ax2[3].yaxis.set_ticks(numpy.arange(0, 1001, 100)) # GPU Freq
		self.ax2[4].yaxis.set_ticks(numpy.arange(0, 101, 10)) # GPU Util
		#self.ax2[5].yaxis.set_ticks(numpy.arange(30, 71, 5)) # APT
		#self.ax2[6].yaxis.set_ticks(numpy.arange(30, 71, 5)) # PST
		self.ax2[7].yaxis.set_ticks(numpy.arange(0, 71, 10)) # Temperature

		self.ax2[5].axis([0, 100, 30,70])
		self.ax2[6].axis([0, 100, 30,70])

		# Y labels
		self.ax2[0].set_ylabel('DVFS (MHz)')
		self.ax2[1].set_ylabel('DDR (MHz)')
		self.ax2[2].set_ylabel('BUS (MHz)')
		self.ax2[3].set_ylabel('GPU Freq (MHz)')
		self.ax2[4].set_ylabel('GPU Util (%)')
		self.ax2[5].set_ylabel('APT (C)')
		self.ax2[6].set_ylabel('PST (C)')
		self.ax2[7].set_ylabel('Temperature (C)')

		self.fig2.subplots_adjust(left=0.10, bottom=0.03, right=0.98, top=0.99, wspace=0.2, hspace=0.1)

	
	def update(self):

		values = self.showfreq.GetValues()
		print ('value=', values)
		if values == None:
			values = self.showfreq.GetValues()
			print ('value=', values)

		self.mCPU0.append(values[1])
		self.mCPU1.append(values[2])
		self.mCPU2.append(values[3])
		self.mCPU3.append(values[4])
		self.mCPU4.append(values[5])
		self.mCPU5.append(values[6])
		self.mCPU6.append(values[7])
		self.mCPU7.append(values[8])

		self.mDVFS_Max.append(values[15])
		self.mDVFS_Min.append(values[16])
		self.mDDR.append(values[17])
		self.mBUS.append(values[18])
		self.mGPUFreq.append(values[13])
		self.mGPUUtil.append(values[14])
		self.mAPT.append(values[22])
		self.mPST.append(values[23])
		self.mCPUG0.append(values[19])
		self.mCPUG1.append(values[20])
		self.mGPU.append(values[21])
		self.timeindex += 1

		loc = self.timeindex	

		Max_Temperature = 40.0
		# DVFX Max
		if (values[15] == -1):
			self.LCD_DVFS_MAX.setStyleSheet( "color: #C0C0C0;" )
		else:
			self.LCD_DVFS_MAX.setStyleSheet( "color: #FF0000;" )

		# DVFX Min
		if (values[16] == -1):
			self.LCD_DVFS_MIN.setStyleSheet( "color: #C0C0C0;" )
		else:
			self.LCD_DVFS_MIN.setStyleSheet( "color: #FF0000;" )

		# GPU Freq 
		if (values[13] == 0):
			self.LCD_GPU_FREQ.setStyleSheet( "color: #C0C0C0;" )
		else:
			self.LCD_GPU_FREQ.setStyleSheet( "color: #0000FF;" )

		# GPU Util
		if (values[14] <= 0):
			self.LCD_GPU_UTIL.setStyleSheet( "color: #C0C0C0;" )		
		elif (values[14] >= 80): # default
			self.LCD_GPU_UTIL.setStyleSheet( "color: #FF0000;" )
		else:
			self.LCD_GPU_UTIL.setStyleSheet( "color: #0000FF;" )

		# APT
		if (values[22] >= Max_Temperature):
			self.LCD_APT.setStyleSheet( "color: #FF0000;" )
		else:
			self.LCD_APT.setStyleSheet( "color: #000000;" )

		# PST
		if (values[23] >= Max_Temperature):
			self.LCD_PST.setStyleSheet( "color: #FF0000;" )
		else:
			self.LCD_PST.setStyleSheet( "color: #000000;" )

		# GPU
		if (values[21] <= 0):
			self.LCD_GPU.setStyleSheet( "color: #C0C0C0;" )
		elif (values[14] >= 60): 
			self.LCD_GPU.setStyleSheet( "color: #FF0000;" )		
		else:
			self.LCD_GPU.setStyleSheet( "color: #000000;" )

		self.LCD_DVFS_MAX.display('%.f' % values[15])
		self.LCD_DVFS_MIN.display('%.f' % values[16])
		self.LCD_GPU_FREQ.display('%.f' % values[13])
		self.LCD_GPU_UTIL.display('%.f' % values[14])
		self.LCD_DDR.display('%.f' % values[17])
		self.LCD_BUS.display('%.f' % values[18])

		self.LCD_APT.display('%.1f\'' % values[22])
		self.LCD_PST.display('%.1f\'' % values[23])	
		self.LCD_CPU_G0.display('%.1f\'' % values[19])
		self.LCD_CPU_G1.display('%.1f\'' % values[20])
		self.LCD_GPU.display('%.1f\'' % values[21])

		self.LCD_CPU0.display('%.f' % values[1])
		self.LCD_CPU1.display('%.f' % values[2])
		self.LCD_CPU2.display('%.f' % values[3])
		self.LCD_CPU3.display('%.f' % values[4])
		self.LCD_CPU4.display('%.f' % values[5])
		self.LCD_CPU5.display('%.f' % values[6])
		self.LCD_CPU6.display('%.f' % values[7])
		self.LCD_CPU7.display('%.f' % values[8])


		# graph
		x = arange(100)
		padd = [None]*(100-loc)
		
		#draw graph, style, color, 
		width = 1.0
		anti = False


		self.ax1[0].plot(x, self.mCPU0[-100:] + padd, linestyle='-', color='#00FF00', linewidth=width, antialiased=anti)
		self.ax1[1].plot(x, self.mCPU1[-100:] + padd, linestyle='-', color='#00FF00', linewidth=width, antialiased=anti)
		self.ax1[2].plot(x, self.mCPU2[-100:] + padd, linestyle='-', color='#00FF00', linewidth=width, antialiased=anti)
		self.ax1[3].plot(x, self.mCPU3[-100:] + padd, linestyle='-', color='#00FF00', linewidth=width, antialiased=anti)
		self.ax1[4].plot(x, self.mCPU4[-100:] + padd, linestyle='-', color='#00FF00', linewidth=width, antialiased=anti)
		self.ax1[5].plot(x, self.mCPU5[-100:] + padd, linestyle='-', color='#00FF00', linewidth=width, antialiased=anti)
		self.ax1[6].plot(x, self.mCPU6[-100:] + padd, linestyle='-', color='#00FF00', linewidth=width, antialiased=anti)
		self.ax1[7].plot(x, self.mCPU7[-100:] + padd, linestyle='-', color='#00FF00', linewidth=width, antialiased=anti)
		
		#self.ax1[0].axvline(x=loc, ymin=0, ymax=1, color='#006000', linewidth=3)

		self.ax2[0].plot(x, self.mDVFS_Max[-100:] + padd, linestyle='-', color='#FFFF00', linewidth=width, antialiased=anti) # DVFS
		self.ax2[0].plot(x, self.mDVFS_Min[-100:] + padd, linestyle='-', color='#0000FF', linewidth=width, antialiased=anti) # DVFS
		self.ax2[1].plot(x, self.mDDR[-100:]      + padd, linestyle='-', color='#FFFF00', linewidth=width, antialiased=anti) # DDR
		self.ax2[2].plot(x, self.mBUS[-100:]      + padd, linestyle='-', color='#FFFF00', linewidth=width, antialiased=anti) # BUS
		self.ax2[3].plot(x, self.mGPUFreq[-100:]  + padd, linestyle='-', color='#FFFF00', linewidth=width, antialiased=anti) # GPU Freq
		self.ax2[4].plot(x, self.mGPUUtil[-100:]  + padd, linestyle='-', color='#FFFF00', linewidth=width, antialiased=anti) # GPU Util	
		self.ax2[5].plot(x, self.mAPT[-100:]      + padd, linestyle='-', color='#FF0000', linewidth=width, antialiased=anti) # APT
		self.ax2[6].plot(x, self.mPST[-100:]      + padd, linestyle='-', color='#FF0000', linewidth=width, antialiased=anti) # PST		
		self.ax2[7].plot(x, self.mCPUG0[-100:]    + padd, linestyle='-', color='#FF0000', linewidth=width, antialiased=anti) # C0 Temperature
		self.ax2[7].plot(x, self.mCPUG1[-100:]    + padd, linestyle='-', color='#00FF00', linewidth=width, antialiased=anti) # C1 Temperature
		self.ax2[7].plot(x, self.mGPU[-100:]      + padd, linestyle='-', color='#0000FF', linewidth=width, antialiased=anti) # C2 Temperature

		self.canvas1.draw()
		self.canvas2.draw()

		self.canvas1.flush_events()
		self.canvas2.flush_events()
		#self.show()

		self.thread = Timer(self.duration/1000.0, self.update)
		self.thread.start()


		"""ax1 = self.ax1
		x = np.arange(0,100.0)
		y1 = (np.cos(2*np.pi*x/50.0)+1.0) * 1000
		
		#ax1[0].clear()
		ax1[0].plot(x, y1, linestyle='-', color='#00FF00', linewidth=2)
		self.canvas1.draw()
		self.canvas1.flush_events()
		self.show()"""
		
		print ('Update is done')

	def StartButton(self):		
		print ('StartButton')
		Device_Info(self.listWidget)		
		self.duration = 1000
		self.showfreq = ShowFreq(self.duration)
		self.update() 
		self.thread = Timer(0.5, self.update)
		self.thread.start()
		#ani animation.FuncAnimation(fig, animate, interval = 10)

	
	def StopButton(self):
		print ('StopButton')
예제 #5
0
class SamplingWidget(QtGui.QWidget):
    def __init__(self):
        super(SamplingWidget, self).__init__()

        self.serial_con = serial.Serial(DEVICE_ADDRESS, BAUD_RATE)

        self.batch_size = None
        self.data = None

        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)
        self.axes = self.figure.add_subplot(111)

        self.left_mean_label = None
        self.left_std_label = None
        self.right_mean_label = None
        self.right_std_label = None
        self.batch_size_label = None

        self.label_edit = None

        self.accept_btn = None
        self.reject_btn = None

        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.toolbar())
        self.setLayout(layout)

        self.get_sample()

        self.canvas.draw()

    def toolbar(self):
        self.left_mean_label = QtGui.QLabel("0.00000")
        self.left_std_label = QtGui.QLabel("0.00000")
        self.right_mean_label = QtGui.QLabel("0.00000")
        self.right_std_label = QtGui.QLabel("0.00000")
        self.batch_size_label = QtGui.QLabel("0")

        self.label_edit = QtGui.QLineEdit()

        self.accept_btn = QtGui.QPushButton("Accept")
        self.accept_btn.clicked.connect(self.accept_sample)
        self.reject_btn = QtGui.QPushButton("Reject")
        self.reject_btn.clicked.connect(self.get_sample)

        layout = QtGui.QVBoxLayout()
        info_widget = QtGui.QWidget()

        info_layout = QtGui.QGridLayout()
        info_widget.setLayout(info_layout)

        info_layout.addWidget(QtGui.QLabel("Batch size: "), 1, 1)
        info_layout.addWidget(QtGui.QLabel("Left mean: "), 2, 1)
        info_layout.addWidget(QtGui.QLabel("Left std: "), 3, 1)
        info_layout.addWidget(QtGui.QLabel("Right mean: "), 4, 1)
        info_layout.addWidget(QtGui.QLabel("Right std: "), 5, 1)
        info_layout.addWidget(self.batch_size_label, 1, 2)
        info_layout.addWidget(self.left_mean_label, 2, 2)
        info_layout.addWidget(self.left_std_label, 3, 2)
        info_layout.addWidget(self.right_mean_label, 4, 2)
        info_layout.addWidget(self.right_std_label, 5, 2)

        layout.addWidget(info_widget)
        layout.addSpacerItem(
            QtGui.QSpacerItem(1, 10, QtGui.QSizePolicy.Expanding,
                              QtGui.QSizePolicy.Expanding))
        layout.addWidget(QtGui.QLabel("Label:"))
        layout.addWidget(self.label_edit)
        layout.addWidget(self.accept_btn)
        layout.addWidget(self.reject_btn)
        widget = QtGui.QWidget()
        widget.setFixedWidth(100)
        widget.setLayout(layout)
        return widget

    def set_data(self, batch_size, data):
        self.left_mean_label.setText(str(round(np.mean(data[0]), 5)))
        self.left_std_label.setText(str(round(np.std(data[0]), 5)))
        self.right_mean_label.setText(str(round(np.mean(data[1]), 5)))
        self.right_std_label.setText(str(round(np.std(data[1]), 5)))
        self.batch_size_label.setText(str(batch_size))

        print("Plotting data...")
        plot_data(self.axes, data)
        self.canvas.draw()
        self.canvas.flush_events()

        self.batch_size = batch_size
        self.data = data

    def accept_sample(self):
        label = None
        try:
            label = float(self.label_edit.text())
        except ValueError:
            try:
                label = int(self.label_edit.text())
            except ValueError:
                print("Failed to interpret label")
                return

        if label < -90.0 or 90.0 < label:
            print("Label not in range")
            return

        print("Saving sample...")
        save_sample(FILE_PATH + '32kHz_' + str(self.batch_size) + '.csv',
                    self.data, label)
        self.get_sample()

    def get_sample(self):
        print("Getting sample...")
        batch_size, data = sample(self.serial_con, 1000)
        self.set_data(batch_size, data)
        return
예제 #6
0
class Main(QMainWindow, Ui_MainWindow):
    def __init__(self, ):
        super(Main, self).__init__()
        self.setupUi(self)
        self.pushButton_Start.clicked.connect(self.StartButton)
        self.pushButton_Stop.clicked.connect(self.StopButton)
        #self.pushButton_Start.setIcon(QtGui.QIcon('/home/insu13.yu/Works/PyQT/QtDesign/EmbedQtChart/start.png'))
        #self.pushButton_Stop.setIcon(QtGui.QIcon('/home/insu13.yu/Works/PyQT/QtDesign/EmbedQtChart/stop.png'))
        #self.pushButton_Start.setGeometry(200,20, 50,40)
        self.mCPU0 = []
        self.mCPU1 = []
        self.mCPU2 = []
        self.mCPU3 = []
        self.mCPU4 = []
        self.mCPU5 = []
        self.mCPU6 = []
        self.mCPU7 = []

        self.mDVFS_Max = []
        self.mDVFS_Min = []
        self.mDDR = []
        self.mBUS = []
        self.mGPUFreq = []
        self.mGPUUtil = []
        self.mAPT = []
        self.mPST = []
        self.mCPUG0 = []
        self.mCPUG1 = []
        self.mGPU = []
        #time index
        self.timeindex = 0

        #init CPU information panel
        self.fig1 = Figure()
        self.canvas1 = FigureCanvas(self.fig1)
        self.Layout_CPU.addWidget(self.canvas1)

        self.ax1 = [
            self.fig1.add_subplot(811),
            self.fig1.add_subplot(812),
            self.fig1.add_subplot(813),
            self.fig1.add_subplot(814),
            self.fig1.add_subplot(815),
            self.fig1.add_subplot(816),
            self.fig1.add_subplot(817),
            self.fig1.add_subplot(818)
        ]

        #init System information panel
        self.fig2 = Figure()
        self.canvas2 = FigureCanvas(self.fig2)
        self.Layout_System.addWidget(self.canvas2)

        # make plots
        self.ax2 = [
            self.fig2.add_subplot(811),
            self.fig2.add_subplot(812),
            self.fig2.add_subplot(813),
            self.fig2.add_subplot(814),
            self.fig2.add_subplot(815),
            self.fig2.add_subplot(816),
            self.fig2.add_subplot(817),
            self.fig2.add_subplot(818)
        ]

        # draw horizontal line
        #ax[0].axhline(y=0.5, xmin=0, xmax=1, color='#FF0000', linewidth=4)

        # draw vertical line
        #ax[0].axvline(x=50, ymin=0, ymax=1, color='#006000', linewidth=4)

    def setup_CPU_chart(self):
        ## add navigation toolbar
        #self.toolbar = NavigationToolbar(canvas, self.mplwindow, coordinates=True)
        #self.mplvl.addWidget(self.toolbar)

        # make plots
        for i in xrange(0, 8):
            self.ax1[i].clear()
            # ============================================
            # Setup chart properties, tick and grid etcs
            # ============================================
            ticklines = self.ax1[i].get_xticklines()
            ticklines.extend(self.ax1[i].get_yticklines())
            gridlines = self.ax1[i].get_xgridlines()
            gridlines.extend(self.ax1[i].get_ygridlines())
            ticklabels = self.ax1[i].get_xticklabels()
            ticklabels.extend(self.ax1[i].get_yticklabels())

            for line in ticklines:
                line.set_color('#00C040')
                line.set_linewidth(1)

            for line in gridlines:
                line.set_color('#00C040')
                line.set_linestyle('-')

            for label in ticklabels:
                label.set_color('#404040')  # drak grey
                label.set_fontsize('8')  # or 'small'

            #self.ax1[0].axis([0,100,0,2100])
            self.ax1[i].set_autoscale_on(False)

            # show grid
            self.ax1[i].grid(True)

            # set your xticks manually (10 ticks)
            self.ax1[i].xaxis.set_ticks(numpy.arange(
                0, 100, 2.5))  # [i for i in range(0,100, 10)]

            # set your yticks manually (10 ticks)
            self.ax1[i].yaxis.set_ticks(
                numpy.arange(0, 1401 if i < 4 else 2201, 200))

            # remove label
            self.ax1[i].set_xticklabels([])

            self.ax1[i].set_axis_bgcolor((0, 0, 0))

        # Y labels
        self.ax1[0].set_ylabel('CPU0')
        self.ax1[1].set_ylabel('CPU1')
        self.ax1[2].set_ylabel('CPU2')
        self.ax1[3].set_ylabel('CPU3')
        self.ax1[4].set_ylabel('CPU4')
        self.ax1[5].set_ylabel('CPU5')
        self.ax1[6].set_ylabel('CPU6')
        self.ax1[7].set_ylabel('CPU7')

        self.fig1.subplots_adjust(left=0.10,
                                  bottom=0.03,
                                  right=0.98,
                                  top=0.99,
                                  wspace=0.2,
                                  hspace=0.1)

    def setup_System_chart(self):
        ## add navigation toolbar
        #self.toolbar = NavigationToolbar(canvas, self.mplwindow, coordinates=True)
        #self.mplvl.addWidget(self.toolbar)

        for i in xrange(0, 8):
            # ============================================
            # Setup chart properties, tick and grid etcs
            # ============================================
            ticklines = self.ax2[i].get_xticklines()
            ticklines.extend(self.ax2[i].get_yticklines())
            gridlines = self.ax2[i].get_xgridlines()
            gridlines.extend(self.ax2[i].get_ygridlines())
            ticklabels = self.ax2[i].get_xticklabels()
            ticklabels.extend(self.ax2[i].get_yticklabels())

            for line in ticklines:
                line.set_color('#00C040')
                line.set_linewidth(1)

            for line in gridlines:
                line.set_color('#00C040')
                line.set_linestyle('-')

            for label in ticklabels:
                label.set_color('#404040')  # drak grey
                if (i == 0 or i == 1):
                    label.set_fontsize('8')  # or 'small'
                else:
                    label.set_fontsize('9')  # or 'small'

            # show grid
            self.ax2[i].grid(True)

            # set your xticks manually (10 ticks)
            self.ax2[i].xaxis.set_ticks(numpy.arange(
                0, 100, 3))  # [i for i in range(0,100, 10)]

            # remove label
            self.ax2[i].set_xticklabels([])

            self.ax2[i].set_axis_bgcolor((0, 0, 0))

            self.ax2[i].set_autoscale_on(False)

        # Y ticks
        self.ax2[0].yaxis.set_ticks(numpy.arange(0, 1201, 200))  # DVFS
        self.ax2[1].yaxis.set_ticks(numpy.arange(0, 1301, 200))  # DDR
        self.ax2[2].yaxis.set_ticks(numpy.arange(0, 1001, 100))  # BUS
        self.ax2[3].yaxis.set_ticks(numpy.arange(0, 1001, 100))  # GPU Freq
        self.ax2[4].yaxis.set_ticks(numpy.arange(0, 101, 10))  # GPU Util
        #self.ax2[5].yaxis.set_ticks(numpy.arange(30, 71, 5)) # APT
        #self.ax2[6].yaxis.set_ticks(numpy.arange(30, 71, 5)) # PST
        self.ax2[7].yaxis.set_ticks(numpy.arange(0, 71, 10))  # Temperature

        self.ax2[5].axis([0, 100, 30, 70])
        self.ax2[6].axis([0, 100, 30, 70])

        # Y labels
        self.ax2[0].set_ylabel('DVFS (MHz)')
        self.ax2[1].set_ylabel('DDR (MHz)')
        self.ax2[2].set_ylabel('BUS (MHz)')
        self.ax2[3].set_ylabel('GPU Freq (MHz)')
        self.ax2[4].set_ylabel('GPU Util (%)')
        self.ax2[5].set_ylabel('APT (C)')
        self.ax2[6].set_ylabel('PST (C)')
        self.ax2[7].set_ylabel('Temperature (C)')

        self.fig2.subplots_adjust(left=0.10,
                                  bottom=0.03,
                                  right=0.98,
                                  top=0.99,
                                  wspace=0.2,
                                  hspace=0.1)

    def update(self):

        values = self.showfreq.GetValues()
        print('value=', values)
        if values == None:
            values = self.showfreq.GetValues()
            print('value=', values)

        self.mCPU0.append(values[1])
        self.mCPU1.append(values[2])
        self.mCPU2.append(values[3])
        self.mCPU3.append(values[4])
        self.mCPU4.append(values[5])
        self.mCPU5.append(values[6])
        self.mCPU6.append(values[7])
        self.mCPU7.append(values[8])

        self.mDVFS_Max.append(values[15])
        self.mDVFS_Min.append(values[16])
        self.mDDR.append(values[17])
        self.mBUS.append(values[18])
        self.mGPUFreq.append(values[13])
        self.mGPUUtil.append(values[14])
        self.mAPT.append(values[22])
        self.mPST.append(values[23])
        self.mCPUG0.append(values[19])
        self.mCPUG1.append(values[20])
        self.mGPU.append(values[21])
        self.timeindex += 1

        loc = self.timeindex

        Max_Temperature = 40.0
        # DVFX Max
        if (values[15] == -1):
            self.LCD_DVFS_MAX.setStyleSheet("color: #C0C0C0;")
        else:
            self.LCD_DVFS_MAX.setStyleSheet("color: #FF0000;")

        # DVFX Min
        if (values[16] == -1):
            self.LCD_DVFS_MIN.setStyleSheet("color: #C0C0C0;")
        else:
            self.LCD_DVFS_MIN.setStyleSheet("color: #FF0000;")

        # GPU Freq
        if (values[13] == 0):
            self.LCD_GPU_FREQ.setStyleSheet("color: #C0C0C0;")
        else:
            self.LCD_GPU_FREQ.setStyleSheet("color: #0000FF;")

        # GPU Util
        if (values[14] <= 0):
            self.LCD_GPU_UTIL.setStyleSheet("color: #C0C0C0;")
        elif (values[14] >= 80):  # default
            self.LCD_GPU_UTIL.setStyleSheet("color: #FF0000;")
        else:
            self.LCD_GPU_UTIL.setStyleSheet("color: #0000FF;")

        # APT
        if (values[22] >= Max_Temperature):
            self.LCD_APT.setStyleSheet("color: #FF0000;")
        else:
            self.LCD_APT.setStyleSheet("color: #000000;")

        # PST
        if (values[23] >= Max_Temperature):
            self.LCD_PST.setStyleSheet("color: #FF0000;")
        else:
            self.LCD_PST.setStyleSheet("color: #000000;")

        # GPU
        if (values[21] <= 0):
            self.LCD_GPU.setStyleSheet("color: #C0C0C0;")
        elif (values[14] >= 60):
            self.LCD_GPU.setStyleSheet("color: #FF0000;")
        else:
            self.LCD_GPU.setStyleSheet("color: #000000;")

        self.LCD_DVFS_MAX.display('%.f' % values[15])
        self.LCD_DVFS_MIN.display('%.f' % values[16])
        self.LCD_GPU_FREQ.display('%.f' % values[13])
        self.LCD_GPU_UTIL.display('%.f' % values[14])
        self.LCD_DDR.display('%.f' % values[17])
        self.LCD_BUS.display('%.f' % values[18])

        self.LCD_APT.display('%.1f\'' % values[22])
        self.LCD_PST.display('%.1f\'' % values[23])
        self.LCD_CPU_G0.display('%.1f\'' % values[19])
        self.LCD_CPU_G1.display('%.1f\'' % values[20])
        self.LCD_GPU.display('%.1f\'' % values[21])

        self.LCD_CPU0.display('%.f' % values[1])
        self.LCD_CPU1.display('%.f' % values[2])
        self.LCD_CPU2.display('%.f' % values[3])
        self.LCD_CPU3.display('%.f' % values[4])
        self.LCD_CPU4.display('%.f' % values[5])
        self.LCD_CPU5.display('%.f' % values[6])
        self.LCD_CPU6.display('%.f' % values[7])
        self.LCD_CPU7.display('%.f' % values[8])

        # graph
        x = arange(100)
        padd = [None] * (100 - loc)

        #draw graph, style, color,
        width = 1.0
        anti = False

        self.ax1[0].plot(x,
                         self.mCPU0[-100:] + padd,
                         linestyle='-',
                         color='#00FF00',
                         linewidth=width,
                         antialiased=anti)
        self.ax1[1].plot(x,
                         self.mCPU1[-100:] + padd,
                         linestyle='-',
                         color='#00FF00',
                         linewidth=width,
                         antialiased=anti)
        self.ax1[2].plot(x,
                         self.mCPU2[-100:] + padd,
                         linestyle='-',
                         color='#00FF00',
                         linewidth=width,
                         antialiased=anti)
        self.ax1[3].plot(x,
                         self.mCPU3[-100:] + padd,
                         linestyle='-',
                         color='#00FF00',
                         linewidth=width,
                         antialiased=anti)
        self.ax1[4].plot(x,
                         self.mCPU4[-100:] + padd,
                         linestyle='-',
                         color='#00FF00',
                         linewidth=width,
                         antialiased=anti)
        self.ax1[5].plot(x,
                         self.mCPU5[-100:] + padd,
                         linestyle='-',
                         color='#00FF00',
                         linewidth=width,
                         antialiased=anti)
        self.ax1[6].plot(x,
                         self.mCPU6[-100:] + padd,
                         linestyle='-',
                         color='#00FF00',
                         linewidth=width,
                         antialiased=anti)
        self.ax1[7].plot(x,
                         self.mCPU7[-100:] + padd,
                         linestyle='-',
                         color='#00FF00',
                         linewidth=width,
                         antialiased=anti)

        #self.ax1[0].axvline(x=loc, ymin=0, ymax=1, color='#006000', linewidth=3)

        self.ax2[0].plot(x,
                         self.mDVFS_Max[-100:] + padd,
                         linestyle='-',
                         color='#FFFF00',
                         linewidth=width,
                         antialiased=anti)  # DVFS
        self.ax2[0].plot(x,
                         self.mDVFS_Min[-100:] + padd,
                         linestyle='-',
                         color='#0000FF',
                         linewidth=width,
                         antialiased=anti)  # DVFS
        self.ax2[1].plot(x,
                         self.mDDR[-100:] + padd,
                         linestyle='-',
                         color='#FFFF00',
                         linewidth=width,
                         antialiased=anti)  # DDR
        self.ax2[2].plot(x,
                         self.mBUS[-100:] + padd,
                         linestyle='-',
                         color='#FFFF00',
                         linewidth=width,
                         antialiased=anti)  # BUS
        self.ax2[3].plot(x,
                         self.mGPUFreq[-100:] + padd,
                         linestyle='-',
                         color='#FFFF00',
                         linewidth=width,
                         antialiased=anti)  # GPU Freq
        self.ax2[4].plot(x,
                         self.mGPUUtil[-100:] + padd,
                         linestyle='-',
                         color='#FFFF00',
                         linewidth=width,
                         antialiased=anti)  # GPU Util
        self.ax2[5].plot(x,
                         self.mAPT[-100:] + padd,
                         linestyle='-',
                         color='#FF0000',
                         linewidth=width,
                         antialiased=anti)  # APT
        self.ax2[6].plot(x,
                         self.mPST[-100:] + padd,
                         linestyle='-',
                         color='#FF0000',
                         linewidth=width,
                         antialiased=anti)  # PST
        self.ax2[7].plot(x,
                         self.mCPUG0[-100:] + padd,
                         linestyle='-',
                         color='#FF0000',
                         linewidth=width,
                         antialiased=anti)  # C0 Temperature
        self.ax2[7].plot(x,
                         self.mCPUG1[-100:] + padd,
                         linestyle='-',
                         color='#00FF00',
                         linewidth=width,
                         antialiased=anti)  # C1 Temperature
        self.ax2[7].plot(x,
                         self.mGPU[-100:] + padd,
                         linestyle='-',
                         color='#0000FF',
                         linewidth=width,
                         antialiased=anti)  # C2 Temperature

        self.canvas1.draw()
        self.canvas2.draw()

        self.canvas1.flush_events()
        self.canvas2.flush_events()
        #self.show()

        self.thread = Timer(self.duration / 1000.0, self.update)
        self.thread.start()
        """ax1 = self.ax1
		x = np.arange(0,100.0)
		y1 = (np.cos(2*np.pi*x/50.0)+1.0) * 1000
		
		#ax1[0].clear()
		ax1[0].plot(x, y1, linestyle='-', color='#00FF00', linewidth=2)
		self.canvas1.draw()
		self.canvas1.flush_events()
		self.show()"""

        print('Update is done')

    def StartButton(self):
        print('StartButton')
        Device_Info(self.listWidget)
        self.duration = 1000
        self.showfreq = ShowFreq(self.duration)
        self.update()
        self.thread = Timer(0.5, self.update)
        self.thread.start()
        #ani animation.FuncAnimation(fig, animate, interval = 10)

    def StopButton(self):
        print('StopButton')
예제 #7
0
class PlotHandler(object):
    def __init__(self, parent):
        self.figure = Figure(tight_layout=True)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setContentsMargins(0,0,0,0)
        self.axes = self.figure.add_subplot(111, projection='3d')
        Axes3D.set_autoscale_on(self.axes, True)
        Axes3D.autoscale_view(self.axes)
        self.canvas.setParent(parent)
        self.activePlot = None
        self.activePopulation = None

        self.surface = None
        self.scatter = None

    def get_widget(self):
        return self.canvas

    def updatePlot(self, X, Y, Z, population=None):
        self.activePlot = (X,Y,Z)
        x, y = np.meshgrid(X,Y)

        if self.surface is not None:
            self.surface.remove()

        if self.scatter is not None:
            self.scatter.remove()

        # surface
        self.surface = Axes3D.plot_surface(
                self.axes,
                x, y, Z,
                rstride=1,
                cstride=1,
                cmap=cm.coolwarm,
                linewidth=0,
                antialiased=False,
                shade=False,
                alpha=0.5
        )

        # population
        if population is not None:
            self.activePopulation = population
            x, y, z = self.preparePopulationData(population)
            self.scatter = Axes3D.scatter(self.axes, x, y, z, c="r", marker="o")
            self.scatter.set_alpha(1.0)

        # Draw all
        self.canvas.draw()
        self.canvas.flush_events()

    def updatePopulation(self, population):
        self.activePopulation = population
        x, y, z = self.preparePopulationData(population)

        if self.scatter is not None:
            self.scatter.remove()

        self.scatter = Axes3D.scatter(self.axes, x, y, z, c="r", marker="o")
        # self.surface.set_zorder(2)
        # self.scatter.set_zorder(100)
        self.scatter.set_alpha(1.0)
        self.canvas.draw()
        self.canvas.flush_events()

    def preparePopulationData(self, population):
        x = []
        y = []
        z = []
        for p in population:
            # x.append(p.parameters[0])
            # y.append(p.parameters[1])
            # z.append(p.fitness)
            x.append(p[0])
            y.append(p[1])
            z.append(p[2]+0.1)
        return (x, y, z)
예제 #8
0
class mGraph(QtGui.QWidget):
    def __init__(self, device, parent=None):
        QtGui.QWidget.__init__(self, parent)
        # Create a matplotlib figure.
        self.figure = plt.figure()
        self.figure.set_facecolor('r')
        # Create a QFrame to house the plot. This is not necessary,
        # just makes it look nice.
        self.matframe = QtGui.QFrame()
        self.matLayout = QtGui.QVBoxLayout()
        self.matLayout.setSpacing(0)
        self.matframe.setLayout(self.matLayout)
        self.matframe.setFrameShape(QtGui.QFrame.Panel)
        self.matframe.setFrameShadow(QtGui.QFrame.Plain)
        self.matframe.setStyleSheet(
            "background-color: rgb(70,80,88); "
            "margin:0px; border:2px solid rgb(0, 0, 0); ")
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setSizePolicy(QtGui.QSizePolicy.Preferred,
                                  QtGui.QSizePolicy.Preferred)
        # This is the device we want to use.
        self.device = device
        # This sets up axis on which to plot.
        color = (189. / 255, 195. / 255, 199. / 255)
        self.ax = self.figure.add_subplot(111, axisbg=color)
        ax = self.ax
        # Add the matplotlib canvas to the QFrame.
        self.matLayout.addWidget(self.canvas)
        # The following lines set up all the colors, makes it look nice.
        # The code to do it is far from pretty and I am planning
        # on cleaning this up a bit.
        self.figure.patch.set_color((70. / 255, 80. / 255, 88. / 255))
        self.figure.patch.set_edgecolor((70. / 255, 80. / 255, 88. / 255))
        ax.spines['bottom'].set_color(color)
        ax.spines['top'].set_color(color)
        ax.spines['right'].set_color(color)
        ax.spines['left'].set_color(color)
        ax.tick_params(axis='x', colors=color)
        ax.tick_params(axis='y', colors=color)
        ax.title.set_color(color)
        ax.yaxis.label.set_color(color)
        ax.xaxis.label.set_color(color)
        ax.xaxis.get_offset_text().set_color(color)
        ax.yaxis.get_offset_text().set_color(color)
        # This is an array of all the lines on the plot. A line for
        # every parameter.
        self.line = []
        self.mins = 0
        self.maxes = 1
        # Each element of line holds a plot, to be combined onto
        # the same graph.
        self.line.append(ax.plot(1, 1, label="Getting Data...")[0])

        # In order to handle interactivity, I had to do some odd stuff
        # with the toolbar buttons: self.home holds the original
        # function called when the home button on the toolbar
        # is clicked.
        self.home = NavigationToolbar.home
        # We now change the function that is called when the toolbar is
        # clicked.
        NavigationToolbar.home = self.enableAutoScaling
        self.toolbar = NavigationToolbar(self.canvas, self)

        self.cid = self.canvas.mpl_connect('button_press_event',
                                           self.disableAutoScaling)
        self.setStyleSheet("QPushButton{\
                    color:rgb(189,195, 199); \
                    background:rgb(70, 80, 88)};")
        self.fullGraphBtn = QtGui.QPushButton("Show Interactive Graph")
        self.fullGraphBtn.clicked.connect(self.openFullGraphGui)
        self.toolbarFrame = QtGui.QFrame()
        toolbarFrameLayout = QtGui.QVBoxLayout()
        toolbarFrameLayout.addWidget(self.toolbar)
        self.toolbar.setParent(None)
        self.toolbarFrame.setLayout(toolbarFrameLayout)
        self.toolbarFrame.setStyleSheet("\
                   border:2px solid rgb(0,0,0);\
                   color:rgb(189,195,199); \
                   background:rgb(70, 80, 88);")
        self.toolbar.setStyleSheet("\
                   border:0px solid rgb(0,0,0);\
                   QDialog{background:rgb(70, 80, 88)}")
        self.matPlotInfo = QtGui.QLabel()
        self.alertFont = QtGui.QFont()
        self.alertFont.setPointSize(12)
        self.matPlotInfo.setStyleSheet("color:rgb(200, 69, 50);")
        self.matPlotInfo.setText("Auto refresh disabled, "
                                 "click HOME button to enable.")
        self.matPlotInfo.setFont(self.alertFont)

        #self.refreshRateSec = device.getFrame().getPlotRefreshRate()
        self.refreshRateSec = device.getFrame().getPlotRefreshRate()
        self.timer = QtCore.QTimer(self)

        self.hidden = True
        self.home = True
        self.initialized = False
        self.currTimeRange = 120
        self.lineSelect = MCheckableComboBox()
        self.lineSelect.setSizeAdjustPolicy(0)
        self.lineSelect.setStyleSheet("\
                    background-color:rgb(70, 80, 88);\
                    color:rgb(189,195, 199);")
        self.plot(self.currTimeRange)

        self.timer.timeout.connect(partial(self.plot, self.currTimeRange))
        self.timer.start(self.refreshRateSec * 1000)

        # Did it store data?
        self.dataOk = True
        self.hideButton = QtGui.QPushButton("Show Plot")
        self.hideButton.clicked.connect(self.togglePlot)
        self.oneMinButton = QtGui.QPushButton("1 min")
        self.oneMinButton.clicked.connect(partial(self.plot, 60))
        self.tenMinButton = QtGui.QPushButton("10 min")
        self.tenMinButton.clicked.connect(partial(self.plot, 600))
        self.twoHrButton = QtGui.QPushButton("2 hr")
        self.twoHrButton.clicked.connect(partial(self.plot, 7200))
        self.twelveHrButton = QtGui.QPushButton("12 hr")
        self.twelveHrButton.clicked.connect(partial(self.plot, 43200))
        self.threeDayButton = QtGui.QPushButton("3 day")
        self.threeDayButton.clicked.connect(partial(self.plot, 259200))
        self.oneWkButton = QtGui.QPushButton("1 week")
        self.oneWkButton.clicked.connect(partial(self.plot, 604800))
        self.allButton = QtGui.QPushButton("All Time")
        self.allButton.clicked.connect(partial(self.plot, None))

        self.canvas.hide()
        self.toolbar.hide()

        # Set the layout.
        buttonLayout1 = QtGui.QHBoxLayout()
        buttonLayout1.addWidget(self.hideButton)
        buttonLayout1.addWidget(self.fullGraphBtn)
        buttonLayout1.addStretch(0)
        buttonLayout2 = QtGui.QHBoxLayout()
        settingsbuttons1 = QtGui.QHBoxLayout()

        buttonLayout2.addWidget(self.oneMinButton)
        buttonLayout2.addWidget(self.tenMinButton)
        buttonLayout2.addWidget(self.twoHrButton)
        buttonLayout2.addWidget(self.twelveHrButton)
        buttonLayout2.addWidget(self.threeDayButton)
        buttonLayout2.addWidget(self.oneWkButton)
        buttonLayout2.addWidget(self.allButton)
        buttonLayout2.addStretch(0)
        self.oneMinButton.hide()
        self.tenMinButton.hide()
        self.twoHrButton.hide()
        self.twelveHrButton.hide()
        self.threeDayButton.hide()
        self.oneWkButton.hide()
        self.allButton.hide()
        self.lineSelect.hide()
        self.matframe.hide()
        self.matPlotInfo.hide()
        self.toolbarFrame.hide()

        settingsbuttons1.addWidget(self.lineSelect)
        layout = QtGui.QVBoxLayout()
        allButtonsLayout = QtGui.QHBoxLayout()
        timeButtonsLayout = QtGui.QVBoxLayout()
        allButtonsLayout.addLayout(timeButtonsLayout)
        layout.addLayout(allButtonsLayout)
        allButtonsLayout.addLayout(settingsbuttons1)
        timeButtonsLayout.addLayout(buttonLayout1)
        timeButtonsLayout.addLayout(buttonLayout2)
        timeButtonsLayout.addWidget(self.matPlotInfo)
        layout.addWidget(self.matframe)
        layout.addWidget(self.toolbarFrame)

        self.setLayout(layout)

    def enableAutoScaling(self):
        self.timer.start(self.refreshRateSec * 1000)
        self.home = True
        self.matPlotInfo.hide()
        self.plot(self.currTimeRange)

    def disableAutoScaling(self, event):
        self.home = False
        self.matPlotInfo.show()
        self.canvas.update()
        self.timer.stop()

    def togglePlot(self):
        if not self.hidden:
            self.canvas.hide()
            self.toolbar.hide()
            self.oneMinButton.hide()
            self.tenMinButton.hide()
            self.twoHrButton.hide()
            self.twelveHrButton.hide()
            self.threeDayButton.hide()
            self.oneWkButton.hide()
            self.allButton.hide()
            self.matPlotInfo.hide()
            self.matframe.hide()
            self.lineSelect.hide()
            self.toolbarFrame.hide()
            self.timer.stop()
            self.hideButton.setText("Show Plot")
            self.hidden = True
        elif self.hidden:
            self.canvas.show()
            self.toolbar.show()
            self.oneMinButton.show()
            self.tenMinButton.show()
            self.twoHrButton.show()
            self.twelveHrButton.show()
            self.threeDayButton.show()
            self.oneWkButton.show()
            self.allButton.show()
            self.plot(self.currTimeRange)
            self.matframe.show()
            self.lineSelect.show()
            self.toolbarFrame.show()
            self.timer.start(self.refreshRateSec * 1000)
            self.hideButton.setText("Hide Plot")
            self.enableAutoScaling()
            self.hidden = False

    def initializePlot(self, dataSet):
        if dataSet:
            varNames = dataSet.getVariables()
            varNames = [varNames[1][i][0] for i in range(len(varNames[1]))]
            self.dropdownFont = QtGui.QFont()
            self.dropdownFont.setPointSize(12)
        if dataSet is not None:
            self.initialized = True
            self.line[0].remove()
            self.line = []

            for i in range(len(varNames)):
                self.line.append(self.ax.plot(1, 1, label=varNames[i])[0])
                text = QtCore.QString(varNames[i])
                self.lineSelect.addItem(text)
                self.lineSelect.setFont(self.dropdownFont)
                self.lineSelect.setChecked(i, True)

    def changeIndependenVarRange(self, timeRange):
        if not self.hidden:
            if timeRange != self.currTimeRange:
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(
                    lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)
            plotRefreshRate = self.device.getFrame().getPlotRefreshRate()
            if self.refreshRateSec != plotRefreshRate:
                self.refreshRateSec = plotRefreshRate
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(
                    lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)

    def getDataRangeFromDataSet(self, dataSet, time):
        if dataSet:
            data = dataSet.getData()
            i = len(data) - 1
            if time:
                while data[i][0] > (data[-1][0] - time):
                    i -= 1
                    if -1 * i > len(data):
                        return data
                data = data[i:-1]
            return data
        else:
            return None

    def openFullGraphGui(self):
        # print "opening full graph gui."
        dataSet = self.device.getFrame().getDataSet().getData()
        # print dataSet
        times = [dt.datetime.fromtimestamp(elem[0]) for elem in dataSet]
        vars = self.device.getFrame().getDataSet().getVariables()

        self.fullgraphcont = fullGraphContainer(times, vars, dataSet)
        self.fullgraphcont.show()

    def plot(self, time):
        times = None
        self.changeIndependenVarRange(time)
        dataSet = self.device.getFrame().getDataSet()

        if not self.initialized:
            self.initializePlot(dataSet)
            self.legend = self.ax.legend(loc='upper left')
            # This is the ONLY time canvas.draw is called. It should
            # NOT be called anywhere else if the graphing speed is
            # to be fast.
            self.canvas.draw()
        else:
            data = self.getDataRangeFromDataSet(dataSet, time)
            for i in range(len(data[0]) - 1):
                if self.lineSelect.isChecked(i):
                    times = [dt.datetime.fromtimestamp(row[0]) for row in data]
                    column = [row[i + 1] for row in data]
                    if not self.line[i].get_visible():
                        self.line[i].set_visible(True)
                    self.line[i].set_data(times, column)
                    self.legend = self.ax.legend(loc='upper left')
                    self.ax.grid(True)
                    self.ax.hold(True)
                else:
                    self.line[i].set_visible(False)
                pass
            self.ax.set_title(self.device.getFrame().getTitle(),
                              color=(189. / 255, 195. / 255, 199. / 255))
            if self.home and times:
                self.ax.set_xlim(times[0], times[-1])
                self.ax.relim(visible_only=True)
                self.ax.autoscale(axis='y')

            frame = self.device.getFrame()
            yLabel = frame.getYLabel()
            if yLabel is not None:
                if frame.getCustomUnits():
                    self.ax.set_ylabel("%s (%s)" %
                                       (yLabel, frame.getCustomUnits()))
                elif frame.getUnits()[i - 1]:
                    self.ax.set_ylabel("%s (%s)" %
                                       (yLabel, frame.getUnits()[i - 1]))

            locator = AutoDateLocator()

            self.ax.xaxis.set_major_locator(locator)
            self.ax.xaxis.set_major_formatter(DateFormatter('%m/%d %H:%M:%S'))
            self.figure.autofmt_xdate()
            self.ax.draw_artist(self.figure)
            self.ax.draw_artist(self.ax.patch)
            self.ax.draw_artist(self.ax.yaxis)
            self.ax.draw_artist(self.ax.xaxis)

            for i, line in enumerate(self.line):
                self.ax.draw_artist(line)

            self.ax.set_xlabel("Time")
            self.ax.draw_artist(self.legend)

            self.canvas.update()

            self.canvas.flush_events()
예제 #9
0
class streamPick(QtGui.QMainWindow):
    def __init__(self, stream=None, parent=None):
        # Initialising QtGui
        QtCore.QLocale.setDefault(QtCore.QLocale.c())
        qApp = QtGui.QApplication(sys.argv)

        # Init vars
        if stream is None:
            msg = 'Define stream = obspy.core.Stream()'
            raise ValueError(msg)
        self.st = stream.copy()
        self._picks = []
        self.savefile = None
        self.onset_types = ['emergent', 'impulsive', 'questionable']

        # Load filters from pickle
        try:
            self.bpfilter = pickle.load(open('.pick_filters', 'r'))
        except:
            self.bpfilter = []
        # Internal variables
        # Gui vars
        self._shortcuts = {'st_next': 'c',
                           'st_previous': 'x',
                           'filter_apply': 'f',
                           'pick_p': 'q',
                           'pick_s': 'w',
                           'pick_custom': 't',
                           'pick_remove': 'r',
                           }
        self._plt_drag = None
        self._current_filter = None
        # Init stations
        self._initStations()  # defines list self._stations
        self._stationCycle = cycle(self._stations)
        self._streamStation(self._stationCycle.next())
        # Init QtGui
        QtGui.QMainWindow.__init__(self)
        self.setupUI()
        # exec QtApp
        qApp.exec_()

    def setupUI(self):
        '''
        Setup the UI
        '''
        self.main_widget = QtGui.QWidget(self)
        # Init parts of the UI
        self._initMenu()
        self._createStatusBar()
        self._initPlots()
        self._wadatiPlt = None

        # Define layout
        l = QtGui.QVBoxLayout(self.main_widget)
        l.addLayout(self.btnbar)
        l.addWidget(self.canvas)

        self.setCentralWidget(self.main_widget)
        self.setGeometry(300, 300, 1200, 800)
        self.setWindowTitle('obspy.core.Stream-Picker')
        self.show()

    def _initPlots(self):
        self.fig = Figure(facecolor='.86', dpi=72, frameon=True)
        # Change facecolor
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
        # Draw the matplotlib figure
        self._drawFig()
        # Connect the events
        self.fig.canvas.mpl_connect('scroll_event',
                                    self._pltOnScroll)
        self.fig.canvas.mpl_connect('motion_notify_event',
                                    self._pltOnDrag)
        self.fig.canvas.mpl_connect('button_release_event',
                                    self._pltOnButtonRelease)
        self.fig.canvas.mpl_connect('button_press_event',
                                    self._pltOnButtonPress)

    def _initMenu(self):
        # Next and Prev Button
        nxt = QtGui.QPushButton('Next >>',
                                shortcut=self._shortcuts['st_next'])
        nxt.clicked.connect(self._pltNextStation)
        nxt.setToolTip('shortcut <b>c</d>')
        nxt.setMaximumWidth(150)
        prv = QtGui.QPushButton('<< Prev',
                                shortcut=self._shortcuts['st_previous'])
        prv.clicked.connect(self._pltPrevStation)
        prv.setToolTip('shortcut <b>x</d>')
        prv.setMaximumWidth(150)

        # Stations drop-down
        self.stcb = QtGui.QComboBox(self)
        for st in self._stations:
            self.stcb.addItem(st)
        self.stcb.activated.connect(self._pltStation)
        self.stcb.setMaximumWidth(100)
        self.stcb.setMinimumWidth(80)

        # Filter buttons
        self.fltrbtn = QtGui.QPushButton('Filter Trace',
                                    shortcut=self._shortcuts['filter_apply'])
        self.fltrbtn.setToolTip('shortcut <b>f</b>')
        self.fltrbtn.setCheckable(True)
        #self.fltrbtn.setAutoFillBackground(True)
        self.fltrbtn.setStyleSheet(QtCore.QString(
                    'QPushButton:checked {background-color: lightgreen;}'))
        self.fltrbtn.clicked.connect(self._appFilter)

        self.fltrcb = QtGui.QComboBox(self)
        self.fltrcb.activated.connect(self._changeFilter)
        self.fltrcb.setMaximumWidth(170)
        self.fltrcb.setMinimumWidth(150)
        self._updateFilterCB()  # fill QComboBox

        # edit/delete filer buttons
        fltredit = QtGui.QPushButton('Edit')
        fltredit.resize(fltredit.sizeHint())
        fltredit.clicked.connect(self._editFilter)

        fltrdel = QtGui.QPushButton('Delete')
        fltrdel.resize(fltrdel.sizeHint())
        fltrdel.clicked.connect(self._deleteFilter)

        btnstyle = QtGui.QFrame(fltredit)
        btnstyle.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)
        btnstyle = QtGui.QFrame(fltrdel)
        btnstyle.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)

        # onset type
        _radbtn = []
        for _o in self.onset_types:
                _radbtn.append(QtGui.QRadioButton(str(_o[0].upper())))
                _radbtn[-1].setToolTip('Onset ' + _o)
                _radbtn[-1].clicked.connect(self._drawPicks)
                if _o == 'impulsive':
                    _radbtn[-1].setChecked(True)
        self.onsetGrp = QtGui.QButtonGroup()
        self.onsetGrp.setExclusive(True)
        onsetbtns = QtGui.QHBoxLayout()
        for _i, _btn in enumerate(_radbtn):
            self.onsetGrp.addButton(_btn, _i)
            onsetbtns.addWidget(_btn)

        # Arrange buttons
        vline = QtGui.QFrame()
        vline.setFrameStyle(QtGui.QFrame.VLine | QtGui.QFrame.Raised)
        self.btnbar = QtGui.QHBoxLayout()
        self.btnbar.addWidget(prv)
        self.btnbar.addWidget(nxt)
        self.btnbar.addWidget(QtGui.QLabel('Station'))
        self.btnbar.addWidget(self.stcb)
        ##
        self.btnbar.addWidget(vline)
        self.btnbar.addWidget(self.fltrbtn)
        self.btnbar.addWidget(self.fltrcb)
        self.btnbar.addWidget(fltredit)
        self.btnbar.addWidget(fltrdel)
        ##
        self.btnbar.addWidget(vline)
        self.btnbar.addWidget(QtGui.QLabel('Pick Onset: '))
        self.btnbar.addLayout(onsetbtns)
        self.btnbar.addStretch(3)

        # Menubar
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(QtGui.QIcon().fromTheme('document-save'),
                            'Save', self._saveCatalog)
        fileMenu.addAction(QtGui.QIcon().fromTheme('document-save'),
                            'Save as QuakeML File', self._saveCatalogDlg)
        fileMenu.addAction(QtGui.QIcon().fromTheme('document-open'),
                            'Load QuakeML File', self._openCatalogDlg)
        fileMenu.addSeparator()
        fileMenu.addAction('Save Plot', self._savePlotDlg)
        fileMenu.addSeparator()
        fileMenu.addAction(QtGui.QIcon().fromTheme('application-exit'),
                            'Exit', self.close)
        #windowMenu = menubar.addMenu('&Windows')
        #windowMenu.addAction('Wadati Diagram', self._opnWadatiPlot)
        aboutMenu = menubar.addMenu('&About')
        aboutMenu.addAction(QtGui.QIcon().fromTheme('info'),
                            'Info', self._infoDlg)

    def _drawFig(self):
        '''
        Draws all matplotlib figures
        '''
        num_plots = len(self._current_st)
        self.fig.clear()
        self._appFilter(draw=False)
        for _i, tr in enumerate(self._current_st):
            ax = self.fig.add_subplot(num_plots, 1, _i)
            ax.plot(tr.data, 'k', antialiased=True, rasterized=True, lod=False)
            ax.axhline(0, color='k', alpha=.05)
            ax.set_xlim([0, tr.data.size])
            ax.text(.02, .925, self._current_st[_i].id,
                        transform=ax.transAxes, va='top', ha='left', alpha=.75)
            ax.channel = tr.stats.channel
            if _i == 0:
                ax.set_xlabel('Seconds')

        # plot picks
        self._drawPicks(draw=False)
        self.fig.suptitle('%s - %s - %s / %.1f Hz / %d samples per chanel' % (self._current_st[-1].stats.network,
                            self._current_st[-1].stats.station,
                            self._current_st[-1].stats.starttime.isoformat(),
                            1./self._current_st[-1].stats.delta,
                            self._current_st[-1].stats.npts),
                            x=.2)
        self._updateSB()
        self._canvasDraw()

    def _initStations(self):
        '''
        Creates a list holding unique station names
        '''
        self._stations = []
        for _tr in self.st:
            if _tr.stats.station not in self._stations:
                self._stations.append(_tr.stats.station)
        self._stations.sort()

    def _getPhases(self):
        '''
        Creates a list holding unique phase names
        '''
        phases = []
        for _pick in self._picks:
            if _pick.phase_hint not in phases:
                phases.append(_pick.phase_hint)
        return phases

    def _streamStation(self, station):
        '''
        Copies the current stream object from self.st through
        obspy.stream.select(station=)
        '''
        if station not in self._stations:
            return
        self._current_st = self.st.select(station=station).copy()
        self._current_stname = station
        self._current_network = self._current_st[0].stats.network
        # Sort and detrend streams
        self._current_st.sort(['channel'])
        self._current_st.detrend('linear')

    def _setPick(self, xdata, phase, channel, polarity='undecideable', overwrite_existing=False):
        '''
        Write obspy.core.event.Pick into self._picks list
        '''
        picktime = self._current_st[0].stats.starttime +\
                (xdata * self._current_st[0].stats.delta)

        this_pick = event.Pick()
        overwrite = True
        # Overwrite existing phase's picktime
        if overwrite_existing:
            for _pick in self._getPicks():
                if _pick.phase_hint == phase and\
                        _pick.waveform_id.channel_code == channel:
                    this_pick = _pick
                    overwrite = False
                    break

        creation_info = event.CreationInfo(
            author='ObsPy.StreamPick',
            creation_time=UTCDateTime())
        # Create new event.Pick()
        this_pick.time = picktime
        this_pick.phase_hint = phase
        this_pick.waveform_id = event.WaveformStreamID(
            network_code=self._current_st[0].stats.network,
            station_code=self._current_st[0].stats.station,
            location_code=self._current_st[0].stats.location,
            channel_code=channel)
        this_pick.evaluation_mode = 'manual'
        this_pick.creation_info = creation_info
        this_pick.onset = self.onset_types[self.onsetGrp.checkedId()]
        this_pick.evaluation_status = 'preliminary'
        this_pick.polarity = polarity
        #if self._current_filter is not None:
        #    this_pick.comments.append(event.Comment(
        #                text=str(self.bpfilter[self.fltrcb.currentIndex()])))
        if overwrite:
            self._picks.append(this_pick)

    def _delPicks(self, network, station, channel):
        '''
        Deletes pick from catalog
        '''
        for _i, _pick in enumerate(self._picks):
            if _pick.waveform_id.network_code == network\
                    and _pick.waveform_id.station_code == station\
                    and _pick.waveform_id.channel_code == channel:
                self._picks.remove(_pick)

    def _getPicks(self):
        '''
        Create a list of picks for the current plot
        '''
        this_st_picks = []
        for _i, pick in enumerate(self._picks):
            if pick.waveform_id.station_code == self._current_stname and\
                    self._current_st[0].stats.starttime <\
                    pick.time < self._current_st[0].stats.endtime:
                this_st_picks.append(_i)
        return [self._picks[i] for i in this_st_picks]

    def _getPickXPosition(self, picks):
        '''
        Convert picktimes into relative positions along x-axis
        '''
        xpicks = []
        for _pick in picks:
            xpicks.append((_pick.time-self._current_st[0].stats.starttime)
                            / self._current_st[0].stats.delta)
        return np.array(xpicks)

    def _drawPicks(self, draw=True):
        '''
        Draw picklines onto axes
        '''
        picks = self._getPicks()
        xpicks = self._getPickXPosition(picks)

        for _ax in self.fig.get_axes():
            lines = []
            labels = []
            points = []
            transOffset = offset_copy(_ax.transData, fig=self.fig,
                            x=5, y=0, units='points')
            for _i, _xpick in enumerate(xpicks):
                if picks[_i].phase_hint == 'S':
                    color = 'r'
                elif picks[_i].phase_hint == 'P':
                    color = 'g'
                else:
                    color = 'b'
                if _ax.channel != picks[_i].waveform_id.channel_code:
                    alpha = .2
                else:
                    alpha = .8

                lines.append(matplotlib.lines.Line2D([_xpick, _xpick],
                            [_ax.get_ylim()[0]*.9, _ax.get_ylim()[1]*.8],
                            color=color, alpha=alpha, rasterized=True))
                lines[-1].obspy_pick = picks[_i]

                points.append(matplotlib.lines.Line2D([_xpick], [_ax.lines[0].get_ydata()[int(_xpick)]],
                            marker='o', mfc=color, mec=color, alpha=alpha, ms=5))

                labels.append(matplotlib.text.Text(_xpick,
                            _ax.get_ylim()[0]*.8, text=picks[_i].phase_hint,
                            color=color, size=10, alpha=alpha,
                            transform=transOffset))

            # delete all artists
            del _ax.artists[0:]
            # add updated objects
            for li, la, po in zip(lines, labels, points):
                _ax.add_artist(li)
                _ax.add_artist(la)
                _ax.add_artist(po)

        if draw:
            self._canvasDraw()

    # Plot Controls
    def _pltOnScroll(self, event):
        '''
        Scrolls/Redraws the plots along x axis
        '''
        if event.inaxes is None:
            return

        if event.key == 'control':
            axes = [event.inaxes]
        else:
            axes = self.fig.get_axes()

        for _ax in axes:
            left = _ax.get_xlim()[0]
            right = _ax.get_xlim()[1]
            extent = right - left
            dzoom = .2 * extent
            aspect_left = (event.xdata - _ax.get_xlim()[0]) / extent
            aspect_right = (_ax.get_xlim()[1] - event.xdata) / extent

            if event.button == 'up':
                left += dzoom * aspect_left
                right -= dzoom * aspect_right
            elif event.button == 'down':
                left -= dzoom * aspect_left
                right += dzoom * aspect_right
            else:
                return
            _ax.set_xlim([left, right])
        self._canvasDraw()

    def _pltOnDrag(self, event):
        '''
        Drags/Redraws the plot upon drag
        '''
        if event.inaxes is None:
            return

        if event.key == 'control':
            axes = [event.inaxes]
        else:
            axes = self.fig.get_axes()

        if event.button == 2:
            if self._plt_drag is None:
                self._plt_drag = event.xdata
                return
            for _ax in axes:
                _ax.set_xlim([_ax.get_xlim()[0] +
                        (self._plt_drag - event.xdata),
                        _ax.get_xlim()[1] + (self._plt_drag - event.xdata)])
        else:
            return
        self._canvasDraw()

    def _pltOnButtonRelease(self, event):
        '''
        On Button Release Reset drag variable
        '''
        self._plt_drag = None

    def _pltOnButtonPress(self, event):
        '''
        This Function is evoked when the user picks
        '''
        if event.key is not None:
            event.key = event.key.lower()
        if event.inaxes is None:
            return
        channel = event.inaxes.channel
        tr_amp = event.inaxes.lines[0].get_ydata()[int(event.xdata)+3] -\
                    event.inaxes.lines[0].get_ydata()[int(event.xdata)]
        if tr_amp < 0:
            polarity = 'negative'
        elif tr_amp > 0:
            polarity = 'positive'
        else:
            polarity = 'undecideable'

        if event.key == self._shortcuts['pick_p'] and event.button == 1:
            self._setPick(event.xdata, phase='P', channel=channel,
                            polarity=polarity)
        elif event.key == self._shortcuts['pick_s'] and event.button == 1:
            self._setPick(event.xdata, phase='S', channel=channel,
                            polarity=polarity)
        elif event.key == self._shortcuts['pick_custom'] and event.button == 1:
            text, ok = QtGui.QInputDialog.getItem(self, 'Custom Phase',
                'Enter phase name:', self._getPhases())
            if ok:
                self._setPick(event.xdata, phase=text, channel=channel,
                                polarity=polarity)
        elif event.key == self._shortcuts['pick_remove']:
            self._delPicks(network=self._current_network,
                            station=self._current_stname,
                            channel=channel)
        else:
            return
        self._updateSB()
        self._drawPicks()

    def _pltNextStation(self):
        '''
        Plot next station
        '''
        self._streamStation(self._stationCycle.next())
        self._drawFig()

    def _pltPrevStation(self):
        '''
        Plot previous station
        '''
        for _i in range(len(self._stations)-1):
            prevStation = self._stationCycle.next()
        self._streamStation(prevStation)
        self._drawFig()

    def _pltStation(self):
        '''
        Plot station from DropDown Menu
        '''
        _i = self.stcb.currentIndex()
        while self._stationCycle.next() != self._stations[_i]:
            pass
        self._streamStation(self._stations[_i])
        self._drawFig()

    # Filter functions
    def _appFilter(self, button=True, draw=True):
        '''
        Apply bandpass filter
        '''
        _i = self.fltrcb.currentIndex()
        self._streamStation(self._current_stname)
        if self.fltrbtn.isChecked() is False:
            self._current_filter = None
        else:
            self._current_st.filter('bandpass',
                                    freqmin=self.bpfilter[_i]['freqmin'],
                                    freqmax=self.bpfilter[_i]['freqmax'],
                                    corners=self.bpfilter[_i]['corners'],
                                    zerophase=True)
            self._current_filter = _i
        for _i, _ax in enumerate(self.fig.get_axes()):
            if len(_ax.lines) == 0:
                continue
            _ax.lines[0].set_ydata(self._current_st[_i].data)
            _ax.relim()
            _ax.autoscale_view()
        if draw is True:
            self._drawPicks(draw=False)
            self._canvasDraw()
        self._updateSB()

    def _newFilter(self):
        '''
        Create new filter
        '''
        newFilter = self.defFilter(self)
        if newFilter.exec_():
                self.bpfilter.append(newFilter.getValues())
                self._updateFilterCB()
                self.fltrcb.setCurrentIndex(len(self.bpfilter)-1)
                self._appFilter()

    def _editFilter(self):
        '''
        Edit existing filter
        '''
        _i = self.fltrcb.currentIndex()
        this_filter = self.bpfilter[_i]
        editFilter = self.defFilter(self, this_filter)
        if editFilter.exec_():
                self.bpfilter[_i] = editFilter.getValues()
                self._updateFilterCB()
                self.fltrcb.setCurrentIndex(_i)
                self._appFilter()

    def _deleteFilter(self):
        '''
        Delete filter
        '''
        _i = self.fltrcb.currentIndex()
        self.fltrbtn.setChecked(False)
        self.bpfilter.pop(_i)
        self._updateFilterCB()
        self._appFilter()

    def _changeFilter(self, index):
        '''
        Evoke this is filter in drop-down is changed
        '''
        if index == len(self.bpfilter):
            return self._newFilter()
        else:
            return self._appFilter()

    def _updateFilterCB(self):
        '''
        Update the filter QComboBox
        '''
        self.fltrcb.clear()
        self.fltrcb.setCurrentIndex(-1)
        for _i, _f in enumerate(self.bpfilter):
            self.fltrcb.addItem('%s [%.2f - %.2f Hz]' % (_f['name'],
                _f['freqmin'], _f['freqmax']))
        self.fltrcb.addItem('Create new Filter...')

    # Status bar functions
    def _createStatusBar(self):
        '''
        Creates the status bar
        '''
        sb = QtGui.QStatusBar()
        sb.setFixedHeight(18)
        self.setStatusBar(sb)
        self.statusBar().showMessage('Ready')

    def _updateSB(self, statustext=None):
        '''
        Updates the statusbar text
        '''
        if statustext is None:
            self.stcb.setCurrentIndex(
                self._stations.index(self._current_stname))
            msg = 'Station %i/%i - %i Picks' % (
                self._stations.index(self._current_stname)+1,
                len(self._stations), len(self._getPicks()))
            if self._current_filter is not None:
                msg += ' - Bandpass %s [%.2f - %.2f Hz]' % (
                    self.bpfilter[self._current_filter]['name'],
                    self.bpfilter[self._current_filter]['freqmin'],
                    self.bpfilter[self._current_filter]['freqmax'])
            else:
                msg += ' - Raw Data'
            self.statusBar().showMessage(msg)

    def _openCatalogDlg(self):
        filename = QtGui.QFileDialog.getOpenFileName(self,
                        'Load QuakeML Picks',
                        os.getcwd(), 'QuakeML Format (*.xml)', '20')
        if filename:
            self._openCatalog(str(filename))
            self.savefile = str(filename)

    def _openCatalog(self, filename):
        '''
        Open existing QuakeML catalog
        '''
        try:
            print 'Opening QuakeML Catalog %s' % filename
            cat = event.readEvents(filename)
            self._picks = cat[0].picks
            self._drawPicks()
        except:
            msg = 'Could not open QuakeML file %s' % (filename)
            raise IOError(msg)

    def _saveCatalogDlg(self):
        '''
        Save catalog through QtDialog
        '''
        self.savefile = QtGui.QFileDialog.getSaveFileName(self,
                        'Save QuakeML Picks',
                        os.getcwd(), 'QuakeML Format (*.xml)')
        if not self.savefile:
            self.savefile = None
            return
        self.savefile = str(self.savefile)
        if os.path.splitext(self.savefile)[1].lower() != '.xml':
            self.savefile += '.xml'
        self._saveCatalog()

    def _saveCatalog(self, filename=None):
        '''
        Saves the catalog to filename
        '''
        if self.savefile is None and filename is None:
            return self._saveCatalogDlg()
        if filename is not None:
            savefile = filename
        else:
            savefile = self.savefile
        cat = event.Catalog()
        cat.events.append(event.Event(picks=self._picks))
        cat.write(savefile, format='QUAKEML')
        print 'Picks saved as %s' % savefile

    def _savePlotDlg(self):
        '''
        Save Plot Image Qt Dialog and Matplotlib wrapper
        '''
        filename = QtGui.QFileDialog.getSaveFileName(self, 'Save Plot',
                        os.getcwd(),
                        'Image Format (*.png *.pdf *.ps *.svg *.eps)')
        if not filename:
            return
        filename = str(filename)
        format = os.path.splitext(filename)[1][1:].lower()
        if format not in ['png', 'pdf', 'ps', 'svg', 'eps']:
            format = 'png'
            filename += '.' + format
        self.fig.savefig(filename=filename, format=format, dpi=72)

    def getPicks(self):
        return self._picks

    def _opnWadatiPlot(self):
        self._wadatiPlt = QtGui.NewWindow()
        self._wadatiPlt.show()

    def _infoDlg(self):
        msg = """
                <h3><b>obspy.core.stream-Picker</b></h3>
                <br><br>
                <div>
                StreamPick is a lightweight seismological
                wave time picker for <code>obspy.core.Stream()</code>
                objects. It further utilises the <code>obspy.core.event</code>
                class to store picks in the QuakeML format.
                </div>
                <h4>Controls:</h4>
                <blockquote>
                <table>
                    <tr>
                        <td width=20><b>%s</b></td><td>Next station</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td><td>Previous station</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td><td>Toggle filter</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Set P-Phase pick at mouse position</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Set S-Phase pick at mouse position</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Set custom phase pick at mouse position</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Remove last pick in trace</td>
                    </tr>
                </table>
                </blockquote>
                <h4>Plot Controls:</h4>
                <blockquote>
                Use mouse wheel to zoom in- and out. Middle mouse button moves
                plot along x-axis.<br>
                Hit <b>Ctrl</b> to manipulate a single plot.
                <br>
                </blockquote>
                <div>
                Programm stores filter parameters in <code>.pick_filter</code>
                and a backup of recent picks in
                <code>.picks-obspy.xml.bak</code>.<br><br>
                See <a href=http://www.github.org/miili/StreamPick>
                http://www.github.org/miili/StreamPick</a> and
                <a href=http://www.obspy.org>http://www.obspy.org</a>
                for further documentation.
                </div>
                """ % (
                    self._shortcuts['st_next'],
                    self._shortcuts['st_previous'],
                    self._shortcuts['filter_apply'],
                    self._shortcuts['pick_p'],
                    self._shortcuts['pick_s'],
                    self._shortcuts['pick_custom'],
                    self._shortcuts['pick_remove'],
                    )
        QtGui.QMessageBox.about(self, 'About', msg)

    def _canvasDraw(self):
        '''
        Redraws the canvas and re-sets mouse focus
        '''
        for _i, _ax in enumerate(self.fig.get_axes()):
            _ax.set_xticklabels(_ax.get_xticks() * self._current_st[_i].stats.delta)
        self.canvas.draw_idle()
        self.canvas.flush_events()
        self.canvas.setFocus()
        return

    def closeEvent(self, evnt):
        '''
        This function is called upon closing the QtGui
        '''
        # Save Picks
        pickle.dump(self.bpfilter, open('.pick_filters', 'w'))
        # Save Catalog
        if len(self._picks) > 0:
            self._saveCatalog('.picks-obspy.xml.bak')
        if self.savefile is None and len(self._picks) > 0:
            ask = QtGui.QMessageBox.question(self, 'Save Picks?',
                'Do you want to save your picks?',
                QtGui.QMessageBox.Save |
                QtGui.QMessageBox.Discard |
                QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
            if ask == QtGui.QMessageBox.Save:
                self._saveCatalog()
            elif ask == QtGui.QMessageBox.Cancel:
                evnt.ignore()
        print self._picks


    # Filter Dialog
    class defFilter(QtGui.QDialog):
        def __init__(self, parent=None, filtervalues=None):
            '''
            Bandpass filter dialog... Qt layout and stuff
            '''
            QtGui.QDialog.__init__(self, parent)
            self.setWindowTitle('Create new Bandpass-Filter')

            # Frequency QDoubleSpinBoxes
            self.frqmin = QtGui.QDoubleSpinBox(decimals=2, maximum=100,
                            minimum=0.01, singleStep=0.1, value=0.1)
            self.frqmax = QtGui.QDoubleSpinBox(decimals=2, maximum=100,
                            minimum=0.01, singleStep=0.1, value=10.0)

            # Radio buttons for corners
            _corners = [2, 4, 8]
            _radbtn = []
            for _c in _corners:
                _radbtn.append(QtGui.QRadioButton(str(_c)))
                if _c == 4:
                    _radbtn[-1].setChecked(True)

            self.corner = QtGui.QButtonGroup()
            self.corner.setExclusive(True)

            radiogrp = QtGui.QHBoxLayout()
            for _i, _r in enumerate(_radbtn):
                self.corner.addButton(_r, _corners[_i])
                radiogrp.addWidget(_radbtn[_i])

            # Filter name
            self.fltname = QtGui.QLineEdit('Filter Name')
            self.fltname.selectAll()

            # Make Layout
            grid = QtGui.QGridLayout()
            grid.addWidget(QtGui.QLabel('Filter Name'), 0, 0)
            grid.addWidget(self.fltname, 0, 1)
            grid.addWidget(QtGui.QLabel('Min. Frequency'), 1, 0)
            grid.addWidget(self.frqmin, 1, 1)
            grid.addWidget(QtGui.QLabel('Max. Frequency'), 2, 0)
            grid.addWidget(self.frqmax, 2, 1)
            grid.addWidget(QtGui.QLabel('Corners'), 3, 0)
            grid.addLayout(radiogrp, 3, 1)
            grid.setVerticalSpacing(10)

            btnbox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok |
                                            QtGui.QDialogButtonBox.Cancel)
            btnbox.accepted.connect(self.accept)
            btnbox.rejected.connect(self.reject)

            layout = QtGui.QVBoxLayout()
            layout.addWidget(QtGui.QLabel('Define a minimum and maximum' +
                ' frequency\nfor the bandpass filter.\nFunction utilises ' +
                'obspy.signal.filter (zerophase=True).\n'))
            layout.addLayout(grid)
            layout.addWidget(btnbox)

            if filtervalues is not None:
                self.fltname.setText(filtervalues['name'])
                self.frqmin.setValue(filtervalues['freqmin'])
                self.frqmax.setValue(filtervalues['freqmax'])
                self.corner.button(filtervalues['corners']).setChecked(True)

            self.setLayout(layout)
            self.setSizeGripEnabled(False)

        def getValues(self):
            '''
            Return filter dialogs values as a dictionary
            '''
            return dict(name=str(self.fltname.text()),
                        freqmin=float(self.frqmin.cleanText()),
                        freqmax=float(self.frqmax.cleanText()),
                        corners=int(int(self.corner.checkedId())))
예제 #10
0
class testWindow(QMainWindow):

    def __init__(self,parent=None):
        QMainWindow.__init__(self,parent=parent)
        self.setWindowTitle('Truncate DAC Attenuation')
        self.create_main_frame()

        self.powerSweepDataPath = '/'



    def plotTruncatedHistogram(self,*args):
        #clear the axes
        self.ax1.clear()    

        #get the roach number
        roachNum = self.spinbox_roachNumber.value()

        #set the new range for the cutoff atten spinbox, custom for each roach
        self.spinbox_cutoffAtten.setRange(np.amin(self.roachList[roachNum].attens),100)
        self.cutoff = self.spinbox_cutoffAtten.value()
        #print a warning if the cutoff value is out of range of DAC attens in file
        if np.logical_or(self.cutoff<np.amin(self.roachList[roachNum].attens),self.cutoff>np.amax(self.roachList[roachNum].attens)):
            print 'cutoff attenuation is out of range of measured values'

        #find where the DAC atten array has values < cutoff value, update the truncatedAttens array
        #modify the roach object
        self.violatingIndices = np.where(self.roachList[roachNum].attens < self.cutoff)[0]       
        self.roachList[roachNum].truncatedAttens = np.copy(self.roachList[roachNum].attens)
        self.roachList[roachNum].truncatedAttens[self.violatingIndices] = self.cutoff

        #set up the bins for the histogram plot
        self.bins = range(int(np.amin(self.roachList[roachNum].attens)),int(np.amax(self.roachList[roachNum].attens)))
        #plot the truncatedAttens histogram
        self.ax1.hist(self.roachList[roachNum].truncatedAttens,self.bins)
        self.draw()
        #plot the pre-truncated attens histogram for comparison
        self.ax1.hist(self.roachList[roachNum].attens,self.bins,alpha = 0.7)  #alpha sets the transparency
        self.ax1.set_ylabel('number of resonators')
        self.ax1.set_xlabel('DAC atten [dB]')
        #set plot label as filename
        self.ax1.set_title(self.roachList[roachNum].filename[len(self.powerSweepDataPath)+1:]) 
        self.draw()
        
        #update the roach object with new cutoff value
        self.roachList[roachNum].cutoff = self.cutoff
        
        if 0:
            print 'plotting roach: ',self.roachList[roachNum].filename[len(self.powerSweepDataPath):]



    def setCutoffAttenSpinboxValue(self):
        #call this function when changing the roach number spinbox value
        roachNum = self.spinbox_roachNumber.value() #get the roach number
        #catch the situation when the new cutoff value is the same as the previous value
        if self.spinbox_cutoffAtten.value() == self.roachList[roachNum].cutoff: 
            self.plotTruncatedHistogram()
        self.spinbox_cutoffAtten.setRange(0,100)
        self.spinbox_cutoffAtten.setValue(self.roachList[roachNum].cutoff)
    


    def getFilenameFromUser(self):
        #create an open file dialog box to prompt user to select a file to load
        filename = str(QFileDialog.getOpenFileName(self, 'Select One File', '/'))
        print os.path.dirname(filename)
        #set the data path variable
        self.powerSweepDataPath = os.path.dirname(filename)

        #load in the data. Look for all files ending with ".txt" and add them to list of files to load in.
        #ignore files that end with "_trunc.txt", because those are what this program outputs
        fileListRaw = []
        for file in os.listdir(self.powerSweepDataPath):
            if file.endswith(".txt"):
                if file.endswith("_trunc.txt"): 
                    print 'skipping loading of ' + str(file)
                else:
                    fileListRaw = fileListRaw + [os.path.join(self.powerSweepDataPath, file)]
        self.fileListRaw = fileListRaw
        print '\nloading data\n'

        #create list of roach objects. One roach per file loaded. 
        self.roachList = []
        for ii in range(len(self.fileListRaw)):
            self.roachList = self.roachList + [roach(self.fileListRaw[ii])]

        #plot the first roach by setting the cutoff atten spinbox value
        self.setCutoffAttenSpinboxValue()


    def saveOneRoach(self):
        #save data of currently displayed histogram in a new file with "_trunc.txt" at end.
        roachNum = self.spinbox_roachNumber.value()
        self.roachList[roachNum].dataTruncated[:,2] = self.roachList[roachNum].truncatedAttens
        print '\nWriting ',self.fileListRaw[roachNum][:-4]+'_trunc.txt'
        np.savetxt(self.fileListRaw[roachNum][:-4]+'_trunc.txt', self.roachList[roachNum].dataTruncated,fmt='%6i %10.9e %4i')


    def saveAllRoach(self):
        #save all roach truncated histograms.
        for ii in range(len(self.fileListRaw)):
            self.roachList[ii].dataTruncated[:,2] = self.roachList[ii].truncatedAttens
            print '\nWriting ',self.fileListRaw[ii][:-4]+'_trunc.txt'
            np.savetxt(self.fileListRaw[ii][:-4]+'_trunc.txt', self.roachList[ii].dataTruncated,fmt='%6i %10.9e %4i')
        print '\nSAVE ALL OPERATION COMPLETE.'


        
            
        


    def create_main_frame(self):
        """
        Makes GUI elements on the window
        """

        #Define the plot window. 
        self.main_frame = QWidget()
        self.dpi = 100
        self.fig = Figure((9.0, 5.0), dpi=self.dpi) #define the figure, set the size and resolution
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.main_frame)
        self.ax1 = self.fig.add_subplot(111)
#        self.ax1.set_ylabel('y axis label')
#        self.ax1.set_xlabel('resonator attenuation [dB]')

        #Define the button that will save one roach.
        button_save = QPushButton("Save")
        button_save.setEnabled(True)
        button_save.setToolTip('Saves current roach.')
        button_save.clicked.connect(self.saveOneRoach)


        #Define the button that will save all roaches.
        button_saveAll = QPushButton("Save All")
        button_saveAll.setEnabled(True)
        button_saveAll.clicked.connect(self.saveAllRoach)


        #Define the button that will load data 
        button_loadData = QPushButton("Open")
        button_loadData.setEnabled(True)
        button_loadData.setToolTip('Select one of the power sweep files you want to look at.\n All other files in the same directory will be loaded as well.')
        button_loadData.clicked.connect(self.getFilenameFromUser)


        #make a label for the roach number spinbox
        label_roachNumber = QLabel('Roach Number')


        #make a label for the roach cutoff attenuation
        label_cutoff = QLabel('Cutoff Attenuation')


        #Let's draw a spin box for the roach number.
        roachNumber = 0
        self.spinbox_roachNumber = QSpinBox()
        self.spinbox_roachNumber.setValue(roachNumber)
        self.spinbox_roachNumber.setRange(0,9)
        self.spinbox_roachNumber.setWrapping(False)
        self.spinbox_roachNumber.setToolTip('Use up/down arrows on keyboard!.')
        self.spinbox_roachNumber.valueChanged.connect(self.setCutoffAttenSpinboxValue)  
        # Using .connect will send self.makePlot an argument which is equal to the new value. 


        #Let's draw spin box for the cutoff attenuation.
        initCutoff = 0
        self.spinbox_cutoffAtten = QSpinBox()
        self.spinbox_cutoffAtten.setValue(initCutoff)
        self.spinbox_cutoffAtten.setRange(0,100)
        self.spinbox_cutoffAtten.setWrapping(False)
        self.spinbox_cutoffAtten.setToolTip('Use up/down arrows on keyboard!.')
        self.spinbox_cutoffAtten.valueChanged.connect(self.plotTruncatedHistogram)  


        #create a vertical box for the plot to go in.
        vbox_plot = QVBoxLayout()
        vbox_plot.addWidget(self.canvas)

        #create a vbox for the roach label and spinbox to go in
        vbox_roachNumber = QVBoxLayout()
        vbox_roachNumber.addWidget(label_roachNumber)
        vbox_roachNumber.addWidget(self.spinbox_roachNumber)


        #create a vbox for the atten cutoff label and atten cutoff spinbox to go in
        vbox_cutoffAtten = QVBoxLayout()
        vbox_cutoffAtten.addWidget(label_cutoff)
        vbox_cutoffAtten.addWidget(self.spinbox_cutoffAtten)

        #Create an h box for the buttons and spinboxes to go in.
        hbox_ch = QHBoxLayout()
        hbox_ch.addWidget(button_loadData)
        hbox_ch.addLayout(vbox_roachNumber)
        hbox_ch.addLayout(vbox_cutoffAtten)
        hbox_ch.addWidget(button_save)
        hbox_ch.addWidget(button_saveAll)

        #Now create another vbox, and add the plot vbox and the button's hbox to the new vbox.
        vbox_combined = QVBoxLayout()
        vbox_combined.addLayout(vbox_plot)
        vbox_combined.addLayout(hbox_ch)

        #Set the main_frame's layout to be vbox_combined
        self.main_frame.setLayout(vbox_combined)

        #Set the overall QWidget to have the layout of the main_frame.
        self.setCentralWidget(self.main_frame)


    def draw(self):
        #The plot window calls this function
        self.canvas.draw()
        self.canvas.flush_events()
예제 #11
0
class mGraph(QtGui.QWidget):
    def __init__(self, device, parent=None):
        QtGui.QWidget.__init__(self, parent)
        # Create a matplotlib figure
        self.figure = plt.figure()
        self.figure.set_facecolor("r")
        # Create a QFrame to house the plot. This is not necessary, just makes it look nice
        self.matframe = QtGui.QFrame()
        self.matLayout = QtGui.QVBoxLayout()
        self.matLayout.setSpacing(0)
        self.matframe.setLayout(self.matLayout)
        self.matframe.setFrameShape(QtGui.QFrame.Panel)
        self.matframe.setFrameShadow(QtGui.QFrame.Plain)
        self.matframe.setStyleSheet("background-color: rgb(70,80,88); margin:0px; border:2px solid rgb(0, 0, 0); ")
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
        # This is the device we want to use
        self.device = device
        # This sets up axis on which to plot
        self.ax = self.figure.add_subplot(111, axisbg=(189.0 / 255, 195.0 / 255, 199.0 / 255))
        # Add the matplotlib canvas to the QFrame
        self.matLayout.addWidget(self.canvas)
        # The following lines set up all the colors, makes it look nice. The code to do it is
        # far from pretty and I am planning on cleaning this up a bit.
        self.figure.patch.set_color((70.0 / 255, 80.0 / 255, 88.0 / 255))
        self.figure.patch.set_edgecolor((70.0 / 255, 80.0 / 255, 88.0 / 255))
        self.ax.spines["bottom"].set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.spines["top"].set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.spines["right"].set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.spines["left"].set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.tick_params(axis="x", colors=(189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.tick_params(axis="y", colors=(189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.title.set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.yaxis.label.set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.xaxis.label.set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.xaxis.get_offset_text().set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.yaxis.get_offset_text().set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        # This is an array of all the lines on the plot. A line for every parameter
        self.line = []
        # Each element of line holds a plot, to be combined onto the same graph
        self.line.append(self.ax.plot(1, 1, label="Getting Data...")[0])
        # This is the ONLY time canvas.draw is called. It should NOT be called anywhere else if
        # the graphing speed is to be fast.
        self.canvas.draw()
        # In order to handle interactivity, I had to do some odd stuff with the
        # toolbar buttons. Self.home holds the original function called when the home button on the toolbar
        # is clicked.
        self.home = NavigationToolbar.home
        # We now change the function that is called when the toolbar is clicked.
        NavigationToolbar.home = self.enableAutoScaling
        self.toolbar = NavigationToolbar(self.canvas, self)
        # print [item for item in dir(self.toolbar) if type(item) == QtGui.QDialog]
        self.cid = self.canvas.mpl_connect("button_press_event", self.disableAutoScaling)
        self.setStyleSheet(
            "QPushButton{\
                    color:rgb(189,195, 199); \
                    background:rgb(70, 80, 88)}"
        )
        self.toolbarFrame = QtGui.QFrame()
        toolbarFrameLayout = QtGui.QVBoxLayout()
        toolbarFrameLayout.addWidget(self.toolbar)
        self.toolbar.setParent(None)
        self.toolbarFrame.setLayout(toolbarFrameLayout)
        self.toolbarFrame.setStyleSheet(
            "\
                    border:2px solid rgb(0,0,0);\
                    color:rgb(189,195,199); \
                    background:rgb(70, 80, 88);\
                    "
        )
        self.toolbar.setStyleSheet(
            "\
                    border:0px solid rgb(0,0,0);\
                    QDialog{background:rgb(250, 80, 88)}\
                    "
        )
        # print dir(self.toolbar)
        # print self.toolbar.children()
        # print self.toolbar.setPalette
        self.matPlotInfo = QtGui.QLabel()
        self.alertFont = QtGui.QFont()
        self.alertFont.setPointSize(12)
        self.matPlotInfo.setStyleSheet("color:rgb(200, 69, 50);")
        self.matPlotInfo.setText("Auto refresh disabled, click HOME button to enable.")
        self.matPlotInfo.setFont(self.alertFont)

        self.refreshRateSec = device.getFrame().getPlotRefreshRate()
        self.timer = QtCore.QTimer(self)

        self.hidden = True
        self.home = True
        self.currTimeRange = 120
        self.plot(self.currTimeRange)

        self.timer.timeout.connect(partial(self.plot, self.currTimeRange))
        self.timer.start(self.refreshRateSec * 1000)
        # did it store data?
        self.dataOk = True
        self.hideButton = QtGui.QPushButton("Show Plot")
        self.hideButton.clicked.connect(self.togglePlot)
        self.thrtysecButton = QtGui.QPushButton("30 Sec")
        self.thrtysecButton.clicked.connect(partial(self.plot, 30))
        self.twoMinButton = QtGui.QPushButton("2 Min")
        self.twoMinButton.clicked.connect(partial(self.plot, 120))
        self.fiveMinButton = QtGui.QPushButton("5 Min")
        self.fiveMinButton.clicked.connect(partial(self.plot, 300))
        self.thrtyMinButton = QtGui.QPushButton("30 Min")
        self.thrtyMinButton.clicked.connect(partial(self.plot, 1800))
        self.twoHrButton = QtGui.QPushButton("2 Hr")
        self.twoHrButton.clicked.connect(partial(self.plot, 7200))
        self.tenHrButton = QtGui.QPushButton("10 Hr")
        self.tenHrButton.clicked.connect(partial(self.plot, 36000))
        self.oneDayButton = QtGui.QPushButton("24 Hr")
        self.oneDayButton.clicked.connect(partial(self.plot, 86400))
        self.oneWkButton = QtGui.QPushButton("1 Wk")
        self.oneWkButton.clicked.connect(partial(self.plot, 604800))
        self.twoWkButton = QtGui.QPushButton("2 Wk")
        self.twoWkButton.clicked.connect(partial(self.plot, 1209600))
        self.allButton = QtGui.QPushButton("All Time")
        self.allButton.clicked.connect(partial(self.plot, None))
        self.canvas.hide()
        self.toolbar.hide()

        # set the layout

        buttonLayout = QtGui.QHBoxLayout()
        buttonLayout.addWidget(self.hideButton)
        buttonLayout.addStretch(0)
        buttonLayout2 = QtGui.QHBoxLayout()

        buttonLayout3 = QtGui.QHBoxLayout()

        buttonLayout2.addWidget(self.thrtysecButton)
        buttonLayout2.addWidget(self.twoMinButton)
        buttonLayout2.addWidget(self.fiveMinButton)
        buttonLayout2.addWidget(self.thrtyMinButton)
        buttonLayout2.addWidget(self.twoHrButton)
        buttonLayout2.addStretch(0)
        buttonLayout3.addWidget(self.tenHrButton)
        buttonLayout3.addWidget(self.oneDayButton)
        buttonLayout3.addWidget(self.oneWkButton)
        buttonLayout3.addWidget(self.twoWkButton)
        buttonLayout3.addWidget(self.allButton)
        buttonLayout3.addStretch(0)
        self.thrtysecButton.hide()
        self.twoMinButton.hide()
        self.fiveMinButton.hide()
        self.thrtyMinButton.hide()
        self.twoHrButton.hide()
        self.tenHrButton.hide()
        self.oneDayButton.hide()
        self.oneWkButton.hide()
        self.twoWkButton.hide()
        self.allButton.hide()
        self.matframe.hide()
        self.matPlotInfo.hide()
        self.toolbarFrame.hide()

        layout = QtGui.QVBoxLayout()
        layout.addLayout(buttonLayout)
        layout.addLayout(buttonLayout2)
        layout.addLayout(buttonLayout3)
        layout.addWidget(self.matPlotInfo)
        layout.addWidget(self.matframe)
        layout.addWidget(self.toolbarFrame)

        self.setLayout(layout)

    def enableAutoScaling(self):
        self.timer.start(self.refreshRateSec * 1000)
        # self.canvas.mpl_disconnect(self.cid)
        # self.cid = self.canvas.mpl_connect('button_press_event', self.disableAutoScaling)
        self.home = True
        self.matPlotInfo.hide()
        # self.deviceThread = threading.Thread(target =
        # self.plot, args=[self.currTimeRange])
        # If the main thread stops, stop the child thread
        # self.deviceThread.daemon = True
        # Start the thread
        # self.deviceThread.start()

        self.plot(self.currTimeRange)

    def disableAutoScaling(self, event):
        self.home = False
        self.matPlotInfo.show()
        self.canvas.update()
        # plt.show()
        # print event.name
        # self.canvas.mpl_disconnect(self.cid)
        # self.cid = self.canvas.mpl_connect('button_press_event', self.enableAutoScaling)
        self.timer.stop()
        # self.zoom(self.toolbar)

    def togglePlot(self):

        if not self.hidden:
            self.canvas.hide()
            self.toolbar.hide()
            self.thrtysecButton.hide()
            self.twoMinButton.hide()
            self.fiveMinButton.hide()
            self.thrtyMinButton.hide()
            self.twoHrButton.hide()
            self.tenHrButton.hide()
            self.oneDayButton.hide()
            self.oneWkButton.hide()
            self.twoWkButton.hide()
            self.allButton.hide()
            self.matPlotInfo.hide()
            self.matframe.hide()
            self.toolbarFrame.hide()
            self.timer.stop()
            self.hideButton.setText("Show Plot")
            self.hidden = True

        elif self.hidden:
            self.canvas.show()
            self.toolbar.show()
            self.thrtysecButton.show()
            self.twoMinButton.show()
            self.fiveMinButton.show()
            self.thrtyMinButton.show()
            self.twoHrButton.show()
            self.tenHrButton.show()
            self.oneDayButton.show()
            self.oneWkButton.show()
            self.twoWkButton.show()
            self.allButton.show()
            self.plot(self.currTimeRange)
            self.matframe.show()
            self.toolbarFrame.show()
            self.timer.start(self.refreshRateSec * 1000)
            self.hideButton.setText("Hide Plot")
            self.enableAutoScaling()
            self.hidden = False

    def plot(self, timeRange):
        if not self.hidden:
            if timeRange != self.currTimeRange:
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)
            if self.refreshRateSec != self.device.getFrame().getPlotRefreshRate():
                # print "New plot refresh rate: ", self.device.getFrame().getPlotRefreshRate()
                self.refreshRateSec = self.device.getFrame().getPlotRefreshRate()
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)
            dataSet = self.device.getFrame().getDataSet()
            # If the dataset exists
            if dataSet is not None:
                # Get all data from the dataset
                data = dataSet.getData()
                self.ax.hold(False)
                try:
                    # for each entry in the dataset [[time], [[data], [data], [data...]]]
                    # print data
                    # Get the corresponding times that the values were recorded

                    for i in range(1, len(data[-1])):
                        # Get colum. aka all values from parameter i over time
                        column = [row[i] for row in data]

                        # print times
                        # If the there is  no defined a time range
                        if self.currTimeRange is None:
                            times = [datetime.datetime.fromtimestamp(row[0]) for row in data]
                            # Plot all of the data (columns) vs time
                            # self.ax.plot_date(times, column, label =
                            # dataSet.getVariables()[1][i-1][0])
                            pass
                        else:
                            # Otherwise, if the user PREVIOUSLY defined a time range,
                            # we need to look for the beginning of it.
                            # Start by getting the current time
                            dstamp = dateStamp()
                            # The dataset should be from now to -timerange
                            # time(now)-time(range)
                            startTime = dstamp.utcNowFloat() - self.currTimeRange
                            # If timeRange is not None, then we know we need
                            # to display only a certain range of values
                            # However, if the starttime defined is less than the lowest time, we
                            # do not have enough data to display the whole thing, so we must
                            # display all that we have instead. We do this by setting
                            # currTimeRange = 0.
                            if timeRange is not None and startTime < float(data[0][0]):
                                self.currTimeRange = None
                            # For all entries in data
                            for y in range(len(data)):
                                # We are searching backwards through the dataset to find a time
                                # just before the time range specified
                                if data[len(data) - y - 1][0] < startTime:
                                    # once we find it, we know the beginning index of the data to be
                                    # displayed
                                    index = y
                                    # Get the times and datafrom the index and columns to the end of the dataset
                                    times = [datetime.datetime.fromtimestamp(row[0]) for row in data[-index:]]
                                    # print times[0]
                                    column = [row[i] for row in data[-index:]]
                                    # Exit the loop
                                    break

                        try:
                            while len(self.line) <= i:
                                self.line.append(self.ax.plot(1, 1, label=dataSet.getVariables()[1][i - 1][0])[0])

                            self.line[i].set_data(times, column)
                            self.ax.legend(loc="upper left", shadow=True, fancybox=True)
                            # maxi = max(column)
                            # mini = min(column)
                            # newMax = max(column)
                            # newMini = min(column)
                            # if(newMax>maxi)
                            # maxi=newMax
                            # self.ax.set_ylim(mini-mini/2, maxi+maxi/2)
                            # if(newMini<mini)
                            # self.ax.set_ylim(mini-mini/2, maxi+maxi/2)
                            # maxi = max(column)
                            # mini = min(column)

                            # self.ax.set_ylim(mini-mini/2, maxi+maxi/2)
                            # self.ax.set_xlim(min(times), max(times))
                            # self.ax.draw_artist(self.line[i])
                        except:

                            traceback.print_exc()

                            # print "Failed to log data"
                        # Add a legend
                        legend = self.ax.legend(loc="upper left")
                        self.ax.set_title(
                            self.device.getFrame().getTitle(), color=(189.0 / 255, 195.0 / 255, 199.0 / 255)
                        )

                        if (
                            self.device.getFrame().getYLabel() is not None
                            and len(self.device.getFrame().getCustomUnits()) is not 0
                        ):
                            self.ax.set_ylabel(
                                self.device.getFrame().getYLabel()
                                + " ("
                                + self.device.getFrame().getCustomUnits()
                                + ")"
                            )
                        elif (
                            self.device.getFrame().getYLabel() is not None
                            and len(self.device.getFrame().getUnits()[i - 1]) is not 0
                        ):

                            self.ax.set_ylabel(
                                self.device.getFrame().getYLabel()
                                + " ("
                                + self.device.getFrame().getUnits()[i - 1]
                                + ")"
                            )

                        self.ax.set_xlabel("Time")

                        self.ax.hold(True)
                        # locator = AutoDateLocator()
                        # self.ax.fmt_xdata = AutoDateFormatter()
                        # self.ax.xaxis.set_major_locator(locator)
                        # self.ax.xaxis.set_major_locator(locator)
                        # self.ax.xaxis.set_major_formatter(DateFormatter('%m/%d'))

                        # self.ax.fmt_xdata = mdates.DateFormatter('%m/%d %H:%M:%S')
                        # print "type: ", type(times[-1])
                        # print "time[-1]: ",times[-1]
                        # self.ax.set_ylim(bottom = 733681, top = 733682)

                        # self.figure.tight_layout()
                        self.ax.grid(True)

                except Exception as e:
                    print "Error"
                try:

                    self.ax.grid(True)
                    # self.ax.clear(self.ax.yaxis)
                    # self.ax.cla()

                    if self.home:
                        self.ax.set_xlim(times[0], times[-1])
                        self.ax.relim()
                        self.ax.autoscale()

                    # print self.ax.get_data_interval()
                    self.ax.draw_artist(self.figure)
                    self.ax.draw_artist(self.ax.patch)

                    locator = AutoDateLocator()

                    self.ax.xaxis.set_major_locator(locator)
                    self.ax.xaxis.set_major_formatter(DateFormatter("%m/%d %H:%M:%S"))
                    self.figure.autofmt_xdate()
                    # print [time.toordinal() for time in times]
                    self.ax.draw_artist(self.ax.yaxis)
                    self.ax.draw_artist(self.ax.xaxis)

                    for line in self.line:
                        self.ax.draw_artist(line)

                    # self.ax.axis('off')

                    self.ax.draw_artist(legend)

                    self.canvas.update()

                    self.canvas.flush_events()

                except:
                    times = [datetime.datetime.fromtimestamp(row[0]) for row in data]
                    traceback.print_exc()
                    self.ax.set_xlim(times[0], times[-1])
                    self.ax.relim()
                    self.ax.autoscale()
                    # print self.ax.get_data_interval()
                    pass
예제 #12
0
class streamPick(QtGui.QMainWindow):
    def __init__(self, stream=None, parent=None):
        # Initialising QtGui
        QtCore.QLocale.setDefault(QtCore.QLocale.c())
        qApp = QtGui.QApplication(sys.argv)

        # Init vars
        if stream is None:
            msg = 'Define stream = obspy.core.Stream()'
            raise ValueError(msg)
        self.st = stream.copy()
        self._picks = []
        self.savefile = None
        self.onset_types = ['emergent', 'impulsive', 'questionable']

        # Load filters from pickle
        try:
            self.bpfilter = pickle.load(open('.pick_filters', 'r'))
        except:
            self.bpfilter = []
        # Internal variables
        # Gui vars
        self._shortcuts = {
            'st_next': 'c',
            'st_previous': 'x',
            'filter_apply': 'f',
            'pick_p': 'q',
            'pick_s': 'w',
            'pick_custom': 't',
            'pick_remove': 'r',
        }
        self._plt_drag = None
        self._current_filter = None
        # Init stations
        self._initStations()  # defines list self._stations
        self._stationCycle = cycle(self._stations)
        self._streamStation(self._stationCycle.next())
        # Init QtGui
        QtGui.QMainWindow.__init__(self)
        self.setupUI()
        # exec QtApp
        qApp.exec_()

    def setupUI(self):
        '''
        Setup the UI
        '''
        self.main_widget = QtGui.QWidget(self)
        # Init parts of the UI
        self._initMenu()
        self._createStatusBar()
        self._initPlots()
        self._wadatiPlt = None

        # Define layout
        l = QtGui.QVBoxLayout(self.main_widget)
        l.addLayout(self.btnbar)
        l.addWidget(self.canvas)

        self.setCentralWidget(self.main_widget)
        self.setGeometry(300, 300, 1200, 800)
        self.setWindowTitle('obspy.core.Stream-Picker')
        self.show()

    def _initPlots(self):
        self.fig = Figure(facecolor='.86', dpi=72, frameon=True)
        # Change facecolor
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
        # Draw the matplotlib figure
        self._drawFig()
        # Connect the events
        self.fig.canvas.mpl_connect('scroll_event', self._pltOnScroll)
        self.fig.canvas.mpl_connect('motion_notify_event', self._pltOnDrag)
        self.fig.canvas.mpl_connect('button_release_event',
                                    self._pltOnButtonRelease)
        self.fig.canvas.mpl_connect('button_press_event',
                                    self._pltOnButtonPress)

    def _initMenu(self):
        # Next and Prev Button
        nxt = QtGui.QPushButton('Next >>', shortcut=self._shortcuts['st_next'])
        nxt.clicked.connect(self._pltNextStation)
        nxt.setToolTip('shortcut <b>c</d>')
        nxt.setMaximumWidth(150)
        prv = QtGui.QPushButton('<< Prev',
                                shortcut=self._shortcuts['st_previous'])
        prv.clicked.connect(self._pltPrevStation)
        prv.setToolTip('shortcut <b>x</d>')
        prv.setMaximumWidth(150)

        # Stations drop-down
        self.stcb = QtGui.QComboBox(self)
        for st in self._stations:
            self.stcb.addItem(st)
        self.stcb.activated.connect(self._pltStation)
        self.stcb.setMaximumWidth(100)
        self.stcb.setMinimumWidth(80)

        # Filter buttons
        self.fltrbtn = QtGui.QPushButton(
            'Filter Trace', shortcut=self._shortcuts['filter_apply'])
        self.fltrbtn.setToolTip('shortcut <b>f</b>')
        self.fltrbtn.setCheckable(True)
        #self.fltrbtn.setAutoFillBackground(True)
        self.fltrbtn.setStyleSheet(
            QtCore.QString(
                'QPushButton:checked {background-color: lightgreen;}'))
        self.fltrbtn.clicked.connect(self._appFilter)

        self.fltrcb = QtGui.QComboBox(self)
        self.fltrcb.activated.connect(self._changeFilter)
        self.fltrcb.setMaximumWidth(170)
        self.fltrcb.setMinimumWidth(150)
        self._updateFilterCB()  # fill QComboBox

        # edit/delete filer buttons
        fltredit = QtGui.QPushButton('Edit')
        fltredit.resize(fltredit.sizeHint())
        fltredit.clicked.connect(self._editFilter)

        fltrdel = QtGui.QPushButton('Delete')
        fltrdel.resize(fltrdel.sizeHint())
        fltrdel.clicked.connect(self._deleteFilter)

        btnstyle = QtGui.QFrame(fltredit)
        btnstyle.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)
        btnstyle = QtGui.QFrame(fltrdel)
        btnstyle.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)

        # onset type
        _radbtn = []
        for _o in self.onset_types:
            _radbtn.append(QtGui.QRadioButton(str(_o[0].upper())))
            _radbtn[-1].setToolTip('Onset ' + _o)
            _radbtn[-1].clicked.connect(self._drawPicks)
            if _o == 'impulsive':
                _radbtn[-1].setChecked(True)
        self.onsetGrp = QtGui.QButtonGroup()
        self.onsetGrp.setExclusive(True)
        onsetbtns = QtGui.QHBoxLayout()
        for _i, _btn in enumerate(_radbtn):
            self.onsetGrp.addButton(_btn, _i)
            onsetbtns.addWidget(_btn)

        # Arrange buttons
        vline = QtGui.QFrame()
        vline.setFrameStyle(QtGui.QFrame.VLine | QtGui.QFrame.Raised)
        self.btnbar = QtGui.QHBoxLayout()
        self.btnbar.addWidget(prv)
        self.btnbar.addWidget(nxt)
        self.btnbar.addWidget(QtGui.QLabel('Station'))
        self.btnbar.addWidget(self.stcb)
        ##
        self.btnbar.addWidget(vline)
        self.btnbar.addWidget(self.fltrbtn)
        self.btnbar.addWidget(self.fltrcb)
        self.btnbar.addWidget(fltredit)
        self.btnbar.addWidget(fltrdel)
        ##
        self.btnbar.addWidget(vline)
        self.btnbar.addWidget(QtGui.QLabel('Pick Onset: '))
        self.btnbar.addLayout(onsetbtns)
        self.btnbar.addStretch(3)

        # Menubar
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(QtGui.QIcon().fromTheme('document-save'), 'Save',
                           self._saveCatalog)
        fileMenu.addAction(QtGui.QIcon().fromTheme('document-save'),
                           'Save as QuakeML File', self._saveCatalogDlg)
        fileMenu.addAction(QtGui.QIcon().fromTheme('document-open'),
                           'Load QuakeML File', self._openCatalogDlg)
        fileMenu.addSeparator()
        fileMenu.addAction('Save Plot', self._savePlotDlg)
        fileMenu.addSeparator()
        fileMenu.addAction(QtGui.QIcon().fromTheme('application-exit'), 'Exit',
                           self.close)
        #windowMenu = menubar.addMenu('&Windows')
        #windowMenu.addAction('Wadati Diagram', self._opnWadatiPlot)
        aboutMenu = menubar.addMenu('&About')
        aboutMenu.addAction(QtGui.QIcon().fromTheme('info'), 'Info',
                            self._infoDlg)

    def _drawFig(self):
        '''
        Draws all matplotlib figures
        '''
        num_plots = len(self._current_st)
        self.fig.clear()
        self._appFilter(draw=False)
        for _i, tr in enumerate(self._current_st):
            ax = self.fig.add_subplot(num_plots, 1, _i)
            ax.plot(tr.data, 'k', antialiased=True, rasterized=True, lod=False)
            ax.axhline(0, color='k', alpha=.05)
            ax.set_xlim([0, tr.data.size])
            ax.text(.02,
                    .925,
                    self._current_st[_i].id,
                    transform=ax.transAxes,
                    va='top',
                    ha='left',
                    alpha=.75)
            ax.channel = tr.stats.channel
            if _i == 0:
                ax.set_xlabel('Seconds')

        # plot picks
        self._drawPicks(draw=False)
        self.fig.suptitle('%s - %s - %s / %.1f Hz / %d samples per chanel' %
                          (self._current_st[-1].stats.network,
                           self._current_st[-1].stats.station,
                           self._current_st[-1].stats.starttime.isoformat(),
                           1. / self._current_st[-1].stats.delta,
                           self._current_st[-1].stats.npts),
                          x=.2)
        self._updateSB()
        self._canvasDraw()

    def _initStations(self):
        '''
        Creates a list holding unique station names
        '''
        self._stations = []
        for _tr in self.st:
            if _tr.stats.station not in self._stations:
                self._stations.append(_tr.stats.station)
        self._stations.sort()

    def _getPhases(self):
        '''
        Creates a list holding unique phase names
        '''
        phases = []
        for _pick in self._picks:
            if _pick.phase_hint not in phases:
                phases.append(_pick.phase_hint)
        return phases

    def _streamStation(self, station):
        '''
        Copies the current stream object from self.st through
        obspy.stream.select(station=)
        '''
        if station not in self._stations:
            return
        self._current_st = self.st.select(station=station).copy()
        self._current_stname = station
        self._current_network = self._current_st[0].stats.network
        # Sort and detrend streams
        self._current_st.sort(['channel'])
        self._current_st.detrend('linear')

    def _setPick(self,
                 xdata,
                 phase,
                 channel,
                 polarity='undecideable',
                 overwrite_existing=False):
        '''
        Write obspy.core.event.Pick into self._picks list
        '''
        picktime = self._current_st[0].stats.starttime +\
                (xdata * self._current_st[0].stats.delta)

        this_pick = event.Pick()
        overwrite = True
        # Overwrite existing phase's picktime
        if overwrite_existing:
            for _pick in self._getPicks():
                if _pick.phase_hint == phase and\
                        _pick.waveform_id.channel_code == channel:
                    this_pick = _pick
                    overwrite = False
                    break

        creation_info = event.CreationInfo(author='ObsPy.StreamPick',
                                           creation_time=UTCDateTime())
        # Create new event.Pick()
        this_pick.time = picktime
        this_pick.phase_hint = phase
        this_pick.waveform_id = event.WaveformStreamID(
            network_code=self._current_st[0].stats.network,
            station_code=self._current_st[0].stats.station,
            location_code=self._current_st[0].stats.location,
            channel_code=channel)
        this_pick.evaluation_mode = 'manual'
        this_pick.creation_info = creation_info
        this_pick.onset = self.onset_types[self.onsetGrp.checkedId()]
        this_pick.evaluation_status = 'preliminary'
        this_pick.polarity = polarity
        #if self._current_filter is not None:
        #    this_pick.comments.append(event.Comment(
        #                text=str(self.bpfilter[self.fltrcb.currentIndex()])))
        if overwrite:
            self._picks.append(this_pick)

    def _delPicks(self, network, station, channel):
        '''
        Deletes pick from catalog
        '''
        for _i, _pick in enumerate(self._picks):
            if _pick.waveform_id.network_code == network\
                    and _pick.waveform_id.station_code == station\
                    and _pick.waveform_id.channel_code == channel:
                self._picks.remove(_pick)

    def _getPicks(self):
        '''
        Create a list of picks for the current plot
        '''
        this_st_picks = []
        for _i, pick in enumerate(self._picks):
            if pick.waveform_id.station_code == self._current_stname and\
                    self._current_st[0].stats.starttime <\
                    pick.time < self._current_st[0].stats.endtime:
                this_st_picks.append(_i)
        return [self._picks[i] for i in this_st_picks]

    def _getPickXPosition(self, picks):
        '''
        Convert picktimes into relative positions along x-axis
        '''
        xpicks = []
        for _pick in picks:
            xpicks.append((_pick.time - self._current_st[0].stats.starttime) /
                          self._current_st[0].stats.delta)
        return np.array(xpicks)

    def _drawPicks(self, draw=True):
        '''
        Draw picklines onto axes
        '''
        picks = self._getPicks()
        xpicks = self._getPickXPosition(picks)

        for _ax in self.fig.get_axes():
            lines = []
            labels = []
            points = []
            transOffset = offset_copy(_ax.transData,
                                      fig=self.fig,
                                      x=5,
                                      y=0,
                                      units='points')
            for _i, _xpick in enumerate(xpicks):
                if picks[_i].phase_hint == 'S':
                    color = 'r'
                elif picks[_i].phase_hint == 'P':
                    color = 'g'
                else:
                    color = 'b'
                if _ax.channel != picks[_i].waveform_id.channel_code:
                    alpha = .2
                else:
                    alpha = .8

                lines.append(
                    matplotlib.lines.Line2D(
                        [_xpick, _xpick],
                        [_ax.get_ylim()[0] * .9,
                         _ax.get_ylim()[1] * .8],
                        color=color,
                        alpha=alpha,
                        rasterized=True))
                lines[-1].obspy_pick = picks[_i]

                points.append(
                    matplotlib.lines.Line2D(
                        [_xpick], [_ax.lines[0].get_ydata()[int(_xpick)]],
                        marker='o',
                        mfc=color,
                        mec=color,
                        alpha=alpha,
                        ms=5))

                labels.append(
                    matplotlib.text.Text(_xpick,
                                         _ax.get_ylim()[0] * .8,
                                         text=picks[_i].phase_hint,
                                         color=color,
                                         size=10,
                                         alpha=alpha,
                                         transform=transOffset))

            # delete all artists
            del _ax.artists[0:]
            # add updated objects
            for li, la, po in zip(lines, labels, points):
                _ax.add_artist(li)
                _ax.add_artist(la)
                _ax.add_artist(po)

        if draw:
            self._canvasDraw()

    # Plot Controls
    def _pltOnScroll(self, event):
        '''
        Scrolls/Redraws the plots along x axis
        '''
        if event.inaxes is None:
            return

        if event.key == 'control':
            axes = [event.inaxes]
        else:
            axes = self.fig.get_axes()

        for _ax in axes:
            left = _ax.get_xlim()[0]
            right = _ax.get_xlim()[1]
            extent = right - left
            dzoom = .2 * extent
            aspect_left = (event.xdata - _ax.get_xlim()[0]) / extent
            aspect_right = (_ax.get_xlim()[1] - event.xdata) / extent

            if event.button == 'up':
                left += dzoom * aspect_left
                right -= dzoom * aspect_right
            elif event.button == 'down':
                left -= dzoom * aspect_left
                right += dzoom * aspect_right
            else:
                return
            _ax.set_xlim([left, right])
        self._canvasDraw()

    def _pltOnDrag(self, event):
        '''
        Drags/Redraws the plot upon drag
        '''
        if event.inaxes is None:
            return

        if event.key == 'control':
            axes = [event.inaxes]
        else:
            axes = self.fig.get_axes()

        if event.button == 2:
            if self._plt_drag is None:
                self._plt_drag = event.xdata
                return
            for _ax in axes:
                _ax.set_xlim([
                    _ax.get_xlim()[0] + (self._plt_drag - event.xdata),
                    _ax.get_xlim()[1] + (self._plt_drag - event.xdata)
                ])
        else:
            return
        self._canvasDraw()

    def _pltOnButtonRelease(self, event):
        '''
        On Button Release Reset drag variable
        '''
        self._plt_drag = None

    def _pltOnButtonPress(self, event):
        '''
        This Function is evoked when the user picks
        '''
        if event.key is not None:
            event.key = event.key.lower()
        if event.inaxes is None:
            return
        channel = event.inaxes.channel
        tr_amp = event.inaxes.lines[0].get_ydata()[int(event.xdata)+3] -\
                    event.inaxes.lines[0].get_ydata()[int(event.xdata)]
        if tr_amp < 0:
            polarity = 'negative'
        elif tr_amp > 0:
            polarity = 'positive'
        else:
            polarity = 'undecideable'

        if event.key == self._shortcuts['pick_p'] and event.button == 1:
            self._setPick(event.xdata,
                          phase='P',
                          channel=channel,
                          polarity=polarity)
        elif event.key == self._shortcuts['pick_s'] and event.button == 1:
            self._setPick(event.xdata,
                          phase='S',
                          channel=channel,
                          polarity=polarity)
        elif event.key == self._shortcuts['pick_custom'] and event.button == 1:
            text, ok = QtGui.QInputDialog.getItem(self, 'Custom Phase',
                                                  'Enter phase name:',
                                                  self._getPhases())
            if ok:
                self._setPick(event.xdata,
                              phase=text,
                              channel=channel,
                              polarity=polarity)
        elif event.key == self._shortcuts['pick_remove']:
            self._delPicks(network=self._current_network,
                           station=self._current_stname,
                           channel=channel)
        else:
            return
        self._updateSB()
        self._drawPicks()

    def _pltNextStation(self):
        '''
        Plot next station
        '''
        self._streamStation(self._stationCycle.next())
        self._drawFig()

    def _pltPrevStation(self):
        '''
        Plot previous station
        '''
        for _i in range(len(self._stations) - 1):
            prevStation = self._stationCycle.next()
        self._streamStation(prevStation)
        self._drawFig()

    def _pltStation(self):
        '''
        Plot station from DropDown Menu
        '''
        _i = self.stcb.currentIndex()
        while self._stationCycle.next() != self._stations[_i]:
            pass
        self._streamStation(self._stations[_i])
        self._drawFig()

    # Filter functions
    def _appFilter(self, button=True, draw=True):
        '''
        Apply bandpass filter
        '''
        _i = self.fltrcb.currentIndex()
        self._streamStation(self._current_stname)
        if self.fltrbtn.isChecked() is False:
            self._current_filter = None
        else:
            self._current_st.filter('bandpass',
                                    freqmin=self.bpfilter[_i]['freqmin'],
                                    freqmax=self.bpfilter[_i]['freqmax'],
                                    corners=self.bpfilter[_i]['corners'],
                                    zerophase=True)
            self._current_filter = _i
        for _i, _ax in enumerate(self.fig.get_axes()):
            if len(_ax.lines) == 0:
                continue
            _ax.lines[0].set_ydata(self._current_st[_i].data)
            _ax.relim()
            _ax.autoscale_view()
        if draw is True:
            self._drawPicks(draw=False)
            self._canvasDraw()
        self._updateSB()

    def _newFilter(self):
        '''
        Create new filter
        '''
        newFilter = self.defFilter(self)
        if newFilter.exec_():
            self.bpfilter.append(newFilter.getValues())
            self._updateFilterCB()
            self.fltrcb.setCurrentIndex(len(self.bpfilter) - 1)
            self._appFilter()

    def _editFilter(self):
        '''
        Edit existing filter
        '''
        _i = self.fltrcb.currentIndex()
        this_filter = self.bpfilter[_i]
        editFilter = self.defFilter(self, this_filter)
        if editFilter.exec_():
            self.bpfilter[_i] = editFilter.getValues()
            self._updateFilterCB()
            self.fltrcb.setCurrentIndex(_i)
            self._appFilter()

    def _deleteFilter(self):
        '''
        Delete filter
        '''
        _i = self.fltrcb.currentIndex()
        self.fltrbtn.setChecked(False)
        self.bpfilter.pop(_i)
        self._updateFilterCB()
        self._appFilter()

    def _changeFilter(self, index):
        '''
        Evoke this is filter in drop-down is changed
        '''
        if index == len(self.bpfilter):
            return self._newFilter()
        else:
            return self._appFilter()

    def _updateFilterCB(self):
        '''
        Update the filter QComboBox
        '''
        self.fltrcb.clear()
        self.fltrcb.setCurrentIndex(-1)
        for _i, _f in enumerate(self.bpfilter):
            self.fltrcb.addItem('%s [%.2f - %.2f Hz]' %
                                (_f['name'], _f['freqmin'], _f['freqmax']))
        self.fltrcb.addItem('Create new Filter...')

    # Status bar functions
    def _createStatusBar(self):
        '''
        Creates the status bar
        '''
        sb = QtGui.QStatusBar()
        sb.setFixedHeight(18)
        self.setStatusBar(sb)
        self.statusBar().showMessage('Ready')

    def _updateSB(self, statustext=None):
        '''
        Updates the statusbar text
        '''
        if statustext is None:
            self.stcb.setCurrentIndex(
                self._stations.index(self._current_stname))
            msg = 'Station %i/%i - %i Picks' % (
                self._stations.index(self._current_stname) + 1,
                len(self._stations), len(self._getPicks()))
            if self._current_filter is not None:
                msg += ' - Bandpass %s [%.2f - %.2f Hz]' % (
                    self.bpfilter[self._current_filter]['name'],
                    self.bpfilter[self._current_filter]['freqmin'],
                    self.bpfilter[self._current_filter]['freqmax'])
            else:
                msg += ' - Raw Data'
            self.statusBar().showMessage(msg)

    def _openCatalogDlg(self):
        filename = QtGui.QFileDialog.getOpenFileName(self,
                                                     'Load QuakeML Picks',
                                                     os.getcwd(),
                                                     'QuakeML Format (*.xml)',
                                                     '20')
        if filename:
            self._openCatalog(str(filename))
            self.savefile = str(filename)

    def _openCatalog(self, filename):
        '''
        Open existing QuakeML catalog
        '''
        try:
            print 'Opening QuakeML Catalog %s' % filename
            cat = event.readEvents(filename)
            self._picks = cat[0].picks
            self._drawPicks()
        except:
            msg = 'Could not open QuakeML file %s' % (filename)
            raise IOError(msg)

    def _saveCatalogDlg(self):
        '''
        Save catalog through QtDialog
        '''
        self.savefile = QtGui.QFileDialog.getSaveFileName(
            self, 'Save QuakeML Picks', os.getcwd(), 'QuakeML Format (*.xml)')
        if not self.savefile:
            self.savefile = None
            return
        self.savefile = str(self.savefile)
        if os.path.splitext(self.savefile)[1].lower() != '.xml':
            self.savefile += '.xml'
        self._saveCatalog()

    def _saveCatalog(self, filename=None):
        '''
        Saves the catalog to filename
        '''
        if self.savefile is None and filename is None:
            return self._saveCatalogDlg()
        if filename is not None:
            savefile = filename
        else:
            savefile = self.savefile
        cat = event.Catalog()
        cat.events.append(event.Event(picks=self._picks))
        cat.write(savefile, format='QUAKEML')
        print 'Picks saved as %s' % savefile

    def _savePlotDlg(self):
        '''
        Save Plot Image Qt Dialog and Matplotlib wrapper
        '''
        filename = QtGui.QFileDialog.getSaveFileName(
            self, 'Save Plot', os.getcwd(),
            'Image Format (*.png *.pdf *.ps *.svg *.eps)')
        if not filename:
            return
        filename = str(filename)
        format = os.path.splitext(filename)[1][1:].lower()
        if format not in ['png', 'pdf', 'ps', 'svg', 'eps']:
            format = 'png'
            filename += '.' + format
        self.fig.savefig(filename=filename, format=format, dpi=72)

    def getPicks(self):
        return self._picks

    def _opnWadatiPlot(self):
        self._wadatiPlt = QtGui.NewWindow()
        self._wadatiPlt.show()

    def _infoDlg(self):
        msg = """
                <h3><b>obspy.core.stream-Picker</b></h3>
                <br><br>
                <div>
                StreamPick is a lightweight seismological
                wave time picker for <code>obspy.core.Stream()</code>
                objects. It further utilises the <code>obspy.core.event</code>
                class to store picks in the QuakeML format.
                </div>
                <h4>Controls:</h4>
                <blockquote>
                <table>
                    <tr>
                        <td width=20><b>%s</b></td><td>Next station</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td><td>Previous station</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td><td>Toggle filter</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Set P-Phase pick at mouse position</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Set S-Phase pick at mouse position</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Set custom phase pick at mouse position</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Remove last pick in trace</td>
                    </tr>
                </table>
                </blockquote>
                <h4>Plot Controls:</h4>
                <blockquote>
                Use mouse wheel to zoom in- and out. Middle mouse button moves
                plot along x-axis.<br>
                Hit <b>Ctrl</b> to manipulate a single plot.
                <br>
                </blockquote>
                <div>
                Programm stores filter parameters in <code>.pick_filter</code>
                and a backup of recent picks in
                <code>.picks-obspy.xml.bak</code>.<br><br>
                See <a href=http://www.github.org/miili/StreamPick>
                http://www.github.org/miili/StreamPick</a> and
                <a href=http://www.obspy.org>http://www.obspy.org</a>
                for further documentation.
                </div>
                """ % (
            self._shortcuts['st_next'],
            self._shortcuts['st_previous'],
            self._shortcuts['filter_apply'],
            self._shortcuts['pick_p'],
            self._shortcuts['pick_s'],
            self._shortcuts['pick_custom'],
            self._shortcuts['pick_remove'],
        )
        QtGui.QMessageBox.about(self, 'About', msg)

    def _canvasDraw(self):
        '''
        Redraws the canvas and re-sets mouse focus
        '''
        for _i, _ax in enumerate(self.fig.get_axes()):
            _ax.set_xticklabels(_ax.get_xticks() *
                                self._current_st[_i].stats.delta)
        self.canvas.draw_idle()
        self.canvas.flush_events()
        self.canvas.setFocus()
        return

    def closeEvent(self, evnt):
        '''
        This function is called upon closing the QtGui
        '''
        # Save Picks
        pickle.dump(self.bpfilter, open('.pick_filters', 'w'))
        # Save Catalog
        if len(self._picks) > 0:
            self._saveCatalog('.picks-obspy.xml.bak')
        if self.savefile is None and len(self._picks) > 0:
            ask = QtGui.QMessageBox.question(
                self, 'Save Picks?', 'Do you want to save your picks?',
                QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard
                | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
            if ask == QtGui.QMessageBox.Save:
                self._saveCatalog()
            elif ask == QtGui.QMessageBox.Cancel:
                evnt.ignore()
        print self._picks

    # Filter Dialog
    class defFilter(QtGui.QDialog):
        def __init__(self, parent=None, filtervalues=None):
            '''
            Bandpass filter dialog... Qt layout and stuff
            '''
            QtGui.QDialog.__init__(self, parent)
            self.setWindowTitle('Create new Bandpass-Filter')

            # Frequency QDoubleSpinBoxes
            self.frqmin = QtGui.QDoubleSpinBox(decimals=2,
                                               maximum=100,
                                               minimum=0.01,
                                               singleStep=0.1,
                                               value=0.1)
            self.frqmax = QtGui.QDoubleSpinBox(decimals=2,
                                               maximum=100,
                                               minimum=0.01,
                                               singleStep=0.1,
                                               value=10.0)

            # Radio buttons for corners
            _corners = [2, 4, 8]
            _radbtn = []
            for _c in _corners:
                _radbtn.append(QtGui.QRadioButton(str(_c)))
                if _c == 4:
                    _radbtn[-1].setChecked(True)

            self.corner = QtGui.QButtonGroup()
            self.corner.setExclusive(True)

            radiogrp = QtGui.QHBoxLayout()
            for _i, _r in enumerate(_radbtn):
                self.corner.addButton(_r, _corners[_i])
                radiogrp.addWidget(_radbtn[_i])

            # Filter name
            self.fltname = QtGui.QLineEdit('Filter Name')
            self.fltname.selectAll()

            # Make Layout
            grid = QtGui.QGridLayout()
            grid.addWidget(QtGui.QLabel('Filter Name'), 0, 0)
            grid.addWidget(self.fltname, 0, 1)
            grid.addWidget(QtGui.QLabel('Min. Frequency'), 1, 0)
            grid.addWidget(self.frqmin, 1, 1)
            grid.addWidget(QtGui.QLabel('Max. Frequency'), 2, 0)
            grid.addWidget(self.frqmax, 2, 1)
            grid.addWidget(QtGui.QLabel('Corners'), 3, 0)
            grid.addLayout(radiogrp, 3, 1)
            grid.setVerticalSpacing(10)

            btnbox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok
                                            | QtGui.QDialogButtonBox.Cancel)
            btnbox.accepted.connect(self.accept)
            btnbox.rejected.connect(self.reject)

            layout = QtGui.QVBoxLayout()
            layout.addWidget(
                QtGui.QLabel(
                    'Define a minimum and maximum' +
                    ' frequency\nfor the bandpass filter.\nFunction utilises '
                    + 'obspy.signal.filter (zerophase=True).\n'))
            layout.addLayout(grid)
            layout.addWidget(btnbox)

            if filtervalues is not None:
                self.fltname.setText(filtervalues['name'])
                self.frqmin.setValue(filtervalues['freqmin'])
                self.frqmax.setValue(filtervalues['freqmax'])
                self.corner.button(filtervalues['corners']).setChecked(True)

            self.setLayout(layout)
            self.setSizeGripEnabled(False)

        def getValues(self):
            '''
            Return filter dialogs values as a dictionary
            '''
            return dict(name=str(self.fltname.text()),
                        freqmin=float(self.frqmin.cleanText()),
                        freqmax=float(self.frqmax.cleanText()),
                        corners=int(int(self.corner.checkedId())))
예제 #13
0
class SecondUiClass(QtGui.QMainWindow):
    # class variables
    pressure = np.array([])
    ion_pressure = np.array([])
    date = np.array([])
    import_pressure = np.array([])
    import_date = np.array([])
    Log_pressure = False
    Import = False

    def __init__(self, parent=None):
        super(SecondUiClass, self).__init__(parent)
        # create window
        self._main = QtGui.QWidget()
        self.setCentralWidget(self._main)
        self.layout = QtGui.QVBoxLayout(self._main)
        self.setGeometry(100, 100, 1000, 600)
        self.setWindowTitle("FHiRE Vacuum Controller - Graphing Window")

        #set up action menu
        actionPressure = QtGui.QAction("Graph Pressure", self)
        actionLog_Pressure = QtGui.QAction("Graph Log Pressure", self)
        actionPressure.triggered.connect(self.PlotPressure)
        actionLog_Pressure.triggered.connect(self.PlotLogPressure)

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('&Options')
        fileMenu.addAction(actionPressure)
        fileMenu.addAction(actionLog_Pressure)

        # set up figure
        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)
        self.layout.addWidget(self.canvas)
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolbar)

    # main plot process
    def Plot(self, dat_file):
        # set up graph
        self.ax = self.figure.add_subplot(111)
        self.ax.hold(False)

        # check if import or live data
        if dat_file == False:
            self.ax.plot(self.date, self.pressure, 'r-')
        else:
            self.Import = True
            self.ax.plot(self.import_date, self.import_pressure, 'r-')

        # format axes
        self.ax.set_xlabel('Time (h:m:s)')
        self.ax.set_ylabel('Pressure (Torr)')
        myFmt = mdates.DateFormatter('%H:%M:%S')
        self.ax.xaxis.set_major_formatter(myFmt)
        self.ax.xaxis.set_minor_locator(AutoMinorLocator())
        self.ax.yaxis.set_minor_locator(AutoMinorLocator())

        self.canvas.draw()
        self.canvas.flush_events()

    # modify plot to show pressure or log pressure
    def PlotPressure(self):
        self.Log_pressure = False
        self.updateThread()

    def PlotLogPressure(self):
        self.Log_pressure = True
        self.updateThread()

    # update graph
    def updateThread(self):
        update_thread = threading.Thread(target=self.UpdatePlot)
        update_thread.start()

    def UpdatePlot(self):
        # check if graphing imported data, live data, log pressure or pressure
        if self.Log_pressure == False and self.Import == False:
            self.ax.plot(self.date, self.pressure, 'r-')
            self.ax.set_ylabel('Pressure (Torr)')
        elif self.Log_pressure == False and self.Import == True:
            self.ax.plot(self.import_date, self.import_pressure, 'r-')
            self.ax.set_ylabel('Pressure (Torr)')
        elif self.Log_pressure == True and self.Import == False:
            self.ax.plot(self.date, np.log10(self.pressure), 'r-')
            self.ax.set_ylabel('Log Pressure (Torr)')
        else:
            self.ax.plot(self.import_date, np.log10(self.import_pressure),
                         'r-')
            self.ax.set_ylabel('Log Pressure (Torr)')

        # format axes
        self.ax.set_xlabel('Time (h:m:s)')
        myFmt = mdates.DateFormatter('%I:%M:%S')
        self.ax.xaxis.set_major_formatter(myFmt)
        self.ax.xaxis.set_minor_locator(AutoMinorLocator())
        self.ax.yaxis.set_minor_locator(AutoMinorLocator())
        self.ax.relim()
        self.ax.autoscale_view()
        self.toolbar.update()
        self.canvas.draw()
        self.canvas.flush_events()
예제 #14
0
class streamPick(QtGui.QMainWindow):
    def __init__(self, stream=None, parent=None):
        # Initialising QtGui
        QtCore.QLocale.setDefault(QtCore.QLocale.c())
        qApp = QtGui.QApplication(sys.argv)

        # Init vars
        if stream is None:
            msg = "Define stream = obspy.core.Stream()"
            raise ValueError(msg)
        self.st = stream.copy()
        self._picks = []
        self.savefile = None
        self.onset_types = ["emergent", "impulsive", "questionable"]

        # Load filters from pickle
        try:
            self.bpfilter = pickle.load(open(".pick_filters", "r"))
        except:
            self.bpfilter = []
        # Internal variables
        # Gui vars
        self._shortcuts = {
            "st_next": "c",
            "st_previous": "x",
            "filter_apply": "f",
            "pick_p": "p",
            "pick_s": "s",
            "pick_custom": "t",
            "pick_remove": "r",
        }
        self._plt_drag = None
        self._current_filter = None
        # Init stations
        self._initStations()  # defines list self._stations
        self._stationCycle = cycle(self._stations)
        self._streamStation(self._stationCycle.next())
        # Init QtGui
        QtGui.QMainWindow.__init__(self)
        self.setupUI()
        # exec QtApp
        qApp.exec_()

    def setupUI(self):
        """
        Setup the UI
        """
        self.main_widget = QtGui.QWidget(self)
        # Init parts of the UI
        self._initMenu()
        self._createStatusBar()
        self._initPlots()
        self._wadatiPlt = None

        # Define layout
        l = QtGui.QVBoxLayout(self.main_widget)
        l.addLayout(self.btnbar)
        l.addWidget(self.canvas)

        self.setCentralWidget(self.main_widget)
        self.setGeometry(300, 300, 1200, 800)
        self.setWindowTitle("obspy.core.Stream-Picker")
        self.show()

    def _initPlots(self):
        self.fig = Figure(facecolor=".86", dpi=72, frameon=True)
        # Change facecolor
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
        # Draw the matplotlib figure
        self._drawFig()
        # Connect the events
        self.fig.canvas.mpl_connect("scroll_event", self._pltOnScroll)
        self.fig.canvas.mpl_connect("motion_notify_event", self._pltOnDrag)
        self.fig.canvas.mpl_connect("button_release_event", self._pltOnButtonRelease)
        self.fig.canvas.mpl_connect("button_press_event", self._pltOnButtonPress)

    def _initMenu(self):
        # Next and Prev Button
        nxt = QtGui.QPushButton("Next >>", shortcut=self._shortcuts["st_next"])
        nxt.clicked.connect(self._pltNextStation)
        nxt.setToolTip("shortcut <b>c</d>")
        nxt.setMaximumWidth(150)
        prv = QtGui.QPushButton("<< Prev", shortcut=self._shortcuts["st_previous"])
        prv.clicked.connect(self._pltPrevStation)
        prv.setToolTip("shortcut <b>x</d>")
        prv.setMaximumWidth(150)

        # Stations drop-down
        self.stcb = QtGui.QComboBox(self)
        for st in self._stations:
            self.stcb.addItem(st)
        self.stcb.activated.connect(self._pltStation)
        self.stcb.setMaximumWidth(100)
        self.stcb.setMinimumWidth(80)

        # Filter buttons
        self.fltrbtn = QtGui.QPushButton("Filter Trace", shortcut=self._shortcuts["filter_apply"])
        self.fltrbtn.setToolTip("shortcut <b>f</b>")
        self.fltrbtn.setCheckable(True)
        # self.fltrbtn.setAutoFillBackground(True)
        self.fltrbtn.setStyleSheet(QtCore.QString("QPushButton:checked {background-color: lightgreen;}"))
        self.fltrbtn.clicked.connect(self._appFilter)

        self.fltrcb = QtGui.QComboBox(self)
        self.fltrcb.activated.connect(self._changeFilter)
        self.fltrcb.setMaximumWidth(170)
        self.fltrcb.setMinimumWidth(150)
        self._updateFilterCB()  # fill QComboBox

        # edit/delete filer buttons
        fltredit = QtGui.QPushButton("Edit")
        fltredit.resize(fltredit.sizeHint())
        fltredit.clicked.connect(self._editFilter)

        fltrdel = QtGui.QPushButton("Delete")
        fltrdel.resize(fltrdel.sizeHint())
        fltrdel.clicked.connect(self._deleteFilter)

        btnstyle = QtGui.QFrame(fltredit)
        btnstyle.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)
        btnstyle = QtGui.QFrame(fltrdel)
        btnstyle.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)

        # onset type
        _radbtn = []
        for _o in self.onset_types:
            _radbtn.append(QtGui.QRadioButton(str(_o[0].upper())))
            _radbtn[-1].setToolTip("Onset " + _o)
            _radbtn[-1].clicked.connect(self._drawPicks)
            if _o == "impulsive":
                _radbtn[-1].setChecked(True)
        self.onsetGrp = QtGui.QButtonGroup()
        self.onsetGrp.setExclusive(True)
        onsetbtns = QtGui.QHBoxLayout()
        for _i, _btn in enumerate(_radbtn):
            self.onsetGrp.addButton(_btn, _i)
            onsetbtns.addWidget(_btn)

        # Arrange buttons
        vline = QtGui.QFrame()
        vline.setFrameStyle(QtGui.QFrame.VLine | QtGui.QFrame.Raised)
        self.btnbar = QtGui.QHBoxLayout()
        self.btnbar.addWidget(prv)
        self.btnbar.addWidget(nxt)
        self.btnbar.addWidget(QtGui.QLabel("Station"))
        self.btnbar.addWidget(self.stcb)
        ##
        self.btnbar.addWidget(vline)
        self.btnbar.addWidget(self.fltrbtn)
        self.btnbar.addWidget(self.fltrcb)
        self.btnbar.addWidget(fltredit)
        self.btnbar.addWidget(fltrdel)
        ##
        self.btnbar.addWidget(vline)
        self.btnbar.addWidget(QtGui.QLabel("Pick Onset: "))
        self.btnbar.addLayout(onsetbtns)
        self.btnbar.addStretch(3)

        # Menubar
        menubar = self.menuBar()
        fileMenu = menubar.addMenu("&File")
        fileMenu.addAction(QtGui.QIcon().fromTheme("document-save"), "Save", self._saveCatalog)
        fileMenu.addAction(QtGui.QIcon().fromTheme("document-save"), "Save as QuakeML File", self._saveCatalogDlg)
        fileMenu.addAction(QtGui.QIcon().fromTheme("document-open"), "Load QuakeML File", self._openCatalogDlg)
        fileMenu.addSeparator()
        fileMenu.addAction("Save Plot", self._savePlotDlg)
        fileMenu.addSeparator()
        fileMenu.addAction(QtGui.QIcon().fromTheme("application-exit"), "Exit", self.close)
        # windowMenu = menubar.addMenu('&Windows')
        # windowMenu.addAction('Wadati Diagram', self._opnWadatiPlot)
        aboutMenu = menubar.addMenu("&About")
        aboutMenu.addAction(QtGui.QIcon().fromTheme("info"), "Info", self._infoDlg)

    def _drawFig(self):
        """
        Draws all matplotlib figures
        """
        num_plots = len(self._current_st)
        self.fig.clear()
        self._appFilter(draw=False)
        for _i, tr in enumerate(self._current_st):
            ax = self.fig.add_subplot(num_plots, 1, _i)
            ax.plot(tr.data, "k", antialiased=True, rasterized=True, lod=False)
            ax.axhline(0, color="k", alpha=0.05)
            ax.set_xlim([0, tr.data.size])
            ax.text(0.02, 0.925, self._current_st[_i].id, transform=ax.transAxes, va="top", ha="left", alpha=0.75)
            ax.channel = tr.stats.channel
            if _i == 0:
                ax.set_xlabel("Seconds")

        # plot picks
        self._drawPicks(draw=False)
        self.fig.suptitle(
            "%s - %s - %s / %.1f Hz / %d samples per chanel"
            % (
                self._current_st[-1].stats.network,
                self._current_st[-1].stats.station,
                self._current_st[-1].stats.starttime.isoformat(),
                1.0 / self._current_st[-1].stats.delta,
                self._current_st[-1].stats.npts,
            ),
            x=0.2,
        )
        self._updateSB()
        self._canvasDraw()

    def _initStations(self):
        """
        Creates a list holding unique station names
        """
        self._stations = []
        for _tr in self.st:
            if _tr.stats.station not in self._stations:
                self._stations.append(_tr.stats.station)
        self._stations.sort()

    def _getPhases(self):
        """
        Creates a list holding unique phase names
        """
        phases = []
        for _pick in self._picks:
            if _pick.phase_hint not in phases:
                phases.append(_pick.phase_hint)
        return phases

    def _streamStation(self, station):
        """
        Copies the current stream object from self.st through
        obspy.stream.select(station=)
        """
        if station not in self._stations:
            return
        self._current_st = self.st.select(station=station).copy()
        self._current_stname = station
        self._current_network = self._current_st[0].stats.network
        # Sort and detrend streams
        self._current_st.sort(["channel"])
        self._current_st.detrend("linear")

    def _setPick(self, xdata, phase, channel, polarity="undecideable", overwrite_existing=False):
        """
        Write obspy.core.event.Pick into self._picks list
        """
        picktime = self._current_st[0].stats.starttime + (xdata * self._current_st[0].stats.delta)

        this_pick = event.Pick()
        overwrite = True
        # Overwrite existing phase's picktime
        if overwrite_existing:
            for _pick in self._getPicks():
                if _pick.phase_hint == phase and _pick.waveform_id.channel_code == channel:
                    this_pick = _pick
                    overwrite = False
                    break

        creation_info = event.CreationInfo(author="ObsPy.StreamPick", creation_time=UTCDateTime())
        # Create new event.Pick()
        this_pick.time = picktime
        this_pick.phase_hint = phase
        this_pick.waveform_id = event.WaveformStreamID(
            network_code=self._current_st[0].stats.network,
            station_code=self._current_st[0].stats.station,
            location_code=self._current_st[0].stats.location,
            channel_code=channel,
        )
        this_pick.evaluation_mode = "manual"
        this_pick.creation_info = creation_info
        this_pick.onset = self.onset_types[self.onsetGrp.checkedId()]
        this_pick.evaluation_status = "preliminary"
        this_pick.polarity = polarity
        # if self._current_filter is not None:
        #    this_pick.comments.append(event.Comment(
        #                text=str(self.bpfilter[self.fltrcb.currentIndex()])))
        if overwrite:
            self._picks.append(this_pick)

    def _delPicks(self, network, station, channel):
        """
        Deletes pick from catalog
        """
        for _i, _pick in enumerate(self._picks):
            if (
                _pick.waveform_id.network_code == network
                and _pick.waveform_id.station_code == station
                and _pick.waveform_id.channel_code == channel
            ):
                self._picks.remove(_pick)

    def _getPicks(self):
        """
        Create a list of picks for the current plot
        """
        this_st_picks = []
        for _i, pick in enumerate(self._picks):
            if (
                pick.waveform_id.station_code == self._current_stname
                and self._current_st[0].stats.starttime < pick.time < self._current_st[0].stats.endtime
            ):
                this_st_picks.append(_i)
        return [self._picks[i] for i in this_st_picks]

    def _getPickXPosition(self, picks):
        """
        Convert picktimes into relative positions along x-axis
        """
        xpicks = []
        for _pick in picks:
            xpicks.append((_pick.time - self._current_st[0].stats.starttime) / self._current_st[0].stats.delta)
        return np.array(xpicks)

    def _drawPicks(self, draw=True):
        """
        Draw picklines onto axes
        """
        picks = self._getPicks()
        xpicks = self._getPickXPosition(picks)

        for _ax in self.fig.get_axes():
            lines = []
            labels = []
            points = []
            transOffset = offset_copy(_ax.transData, fig=self.fig, x=5, y=0, units="points")
            for _i, _xpick in enumerate(xpicks):
                if picks[_i].phase_hint == "S":
                    color = "r"
                elif picks[_i].phase_hint == "P":
                    color = "g"
                else:
                    color = "b"
                if _ax.channel != picks[_i].waveform_id.channel_code:
                    alpha = 0.2
                else:
                    alpha = 0.8

                lines.append(
                    matplotlib.lines.Line2D(
                        [_xpick, _xpick],
                        [_ax.get_ylim()[0] * 0.9, _ax.get_ylim()[1] * 0.8],
                        color=color,
                        alpha=alpha,
                        rasterized=True,
                    )
                )
                lines[-1].obspy_pick = picks[_i]

                points.append(
                    matplotlib.lines.Line2D(
                        [_xpick],
                        [_ax.lines[0].get_ydata()[int(_xpick)]],
                        marker="o",
                        mfc=color,
                        mec=color,
                        alpha=alpha,
                        ms=5,
                    )
                )

                labels.append(
                    matplotlib.text.Text(
                        _xpick,
                        _ax.get_ylim()[0] * 0.8,
                        text=picks[_i].phase_hint,
                        color=color,
                        size=10,
                        alpha=alpha,
                        transform=transOffset,
                    )
                )

            # delete all artists
            del _ax.artists[0:]
            # add updated objects
            for li, la, po in zip(lines, labels, points):
                _ax.add_artist(li)
                _ax.add_artist(la)
                _ax.add_artist(po)

        if draw:
            self._canvasDraw()

    # Plot Controls
    def _pltOnScroll(self, event):
        """
        Scrolls/Redraws the plots along x axis
        """
        if event.inaxes is None:
            return

        if event.key == "control":
            axes = [event.inaxes]
        else:
            axes = self.fig.get_axes()

        for _ax in axes:
            left = _ax.get_xlim()[0]
            right = _ax.get_xlim()[1]
            extent = right - left
            dzoom = 0.2 * extent
            aspect_left = (event.xdata - _ax.get_xlim()[0]) / extent
            aspect_right = (_ax.get_xlim()[1] - event.xdata) / extent

            if event.button == "up":
                left += dzoom * aspect_left
                right -= dzoom * aspect_right
            elif event.button == "down":
                left -= dzoom * aspect_left
                right += dzoom * aspect_right
            else:
                return
            _ax.set_xlim([left, right])
        self._canvasDraw()

    def _pltOnDrag(self, event):
        """
        Drags/Redraws the plot upon drag
        """
        if event.inaxes is None:
            return

        if event.key == "control":
            axes = [event.inaxes]
        else:
            axes = self.fig.get_axes()

        if event.button == 2:
            if self._plt_drag is None:
                self._plt_drag = event.xdata
                return
            for _ax in axes:
                _ax.set_xlim(
                    [
                        _ax.get_xlim()[0] + (self._plt_drag - event.xdata),
                        _ax.get_xlim()[1] + (self._plt_drag - event.xdata),
                    ]
                )
        else:
            return
        self._canvasDraw()

    def _pltOnButtonRelease(self, event):
        """
        On Button Release Reset drag variable
        """
        self._plt_drag = None

    def _pltOnButtonPress(self, event):
        """
        This Function is evoked when the user picks
        """
        print event.key
        if event.key is not None:
            event.key = event.key.lower()
        if event.inaxes is None:
            return
        channel = event.inaxes.channel
        tr_amp = (
            event.inaxes.lines[0].get_ydata()[int(event.xdata) + 3]
            - event.inaxes.lines[0].get_ydata()[int(event.xdata)]
        )
        if tr_amp < 0:
            polarity = "negative"
        elif tr_amp > 0:
            polarity = "positive"
        else:
            polarity = "undecideable"

        if event.key == self._shortcuts["pick_p"] and event.button == 1:
            self._setPick(event.xdata, phase="P", channel=channel, polarity=polarity)
        elif event.key == self._shortcuts["pick_s"] and event.button == 1:
            self._setPick(event.xdata, phase="S", channel=channel, polarity=polarity)
        elif event.key == self._shortcuts["pick_custom"] and event.button == 1:
            text, ok = QtGui.QInputDialog.getItem(self, "Custom Phase", "Enter phase name:", self._getPhases())
            if ok:
                self._setPick(event.xdata, phase=text, channel=channel, polarity=polarity)
        elif event.key == self._shortcuts["pick_remove"]:
            self._delPicks(network=self._current_network, station=self._current_stname, channel=channel)
        else:
            return
        self._updateSB()
        self._drawPicks()

    def _pltNextStation(self):
        """
        Plot next station
        """
        self._streamStation(self._stationCycle.next())
        self._drawFig()

    def _pltPrevStation(self):
        """
        Plot previous station
        """
        for _i in range(len(self._stations) - 1):
            prevStation = self._stationCycle.next()
        self._streamStation(prevStation)
        self._drawFig()

    def _pltStation(self):
        """
        Plot station from DropDown Menu
        """
        _i = self.stcb.currentIndex()
        while self._stationCycle.next() != self._stations[_i]:
            pass
        self._streamStation(self._stations[_i])
        self._drawFig()

    # Filter functions
    def _appFilter(self, button=True, draw=True):
        """
        Apply bandpass filter
        """
        _i = self.fltrcb.currentIndex()
        self._streamStation(self._current_stname)
        if self.fltrbtn.isChecked() is False:
            self._current_filter = None
        else:
            self._current_st.filter(
                "bandpass",
                freqmin=self.bpfilter[_i]["freqmin"],
                freqmax=self.bpfilter[_i]["freqmax"],
                corners=self.bpfilter[_i]["corners"],
                zerophase=True,
            )
            self._current_filter = _i
        for _i, _ax in enumerate(self.fig.get_axes()):
            if len(_ax.lines) == 0:
                continue
            _ax.lines[0].set_ydata(self._current_st[_i].data)
            _ax.relim()
            _ax.autoscale_view()
        if draw is True:
            self._drawPicks(draw=False)
            self._canvasDraw()
        self._updateSB()

    def _newFilter(self):
        """
        Create new filter
        """
        newFilter = self.defFilter(self)
        if newFilter.exec_():
            self.bpfilter.append(newFilter.getValues())
            self._updateFilterCB()
            self.fltrcb.setCurrentIndex(len(self.bpfilter) - 1)
            self._appFilter()

    def _editFilter(self):
        """
        Edit existing filter
        """
        _i = self.fltrcb.currentIndex()
        this_filter = self.bpfilter[_i]
        editFilter = self.defFilter(self, this_filter)
        if editFilter.exec_():
            self.bpfilter[_i] = editFilter.getValues()
            self._updateFilterCB()
            self.fltrcb.setCurrentIndex(_i)
            self._appFilter()

    def _deleteFilter(self):
        """
        Delete filter
        """
        _i = self.fltrcb.currentIndex()
        self.fltrbtn.setChecked(False)
        self.bpfilter.pop(_i)
        self._updateFilterCB()
        self._appFilter()

    def _changeFilter(self, index):
        """
        Evoke this is filter in drop-down is changed
        """
        if index == len(self.bpfilter):
            return self._newFilter()
        else:
            return self._appFilter()

    def _updateFilterCB(self):
        """
        Update the filter QComboBox
        """
        self.fltrcb.clear()
        self.fltrcb.setCurrentIndex(-1)
        for _i, _f in enumerate(self.bpfilter):
            self.fltrcb.addItem("%s [%.2f - %.2f Hz]" % (_f["name"], _f["freqmin"], _f["freqmax"]))
        self.fltrcb.addItem("Create new Filter...")

    # Status bar functions
    def _createStatusBar(self):
        """
        Creates the status bar
        """
        sb = QtGui.QStatusBar()
        sb.setFixedHeight(18)
        self.setStatusBar(sb)
        self.statusBar().showMessage("Ready")

    def _updateSB(self, statustext=None):
        """
        Updates the statusbar text
        """
        if statustext is None:
            self.stcb.setCurrentIndex(self._stations.index(self._current_stname))
            msg = "Station %i/%i - %i Picks" % (
                self._stations.index(self._current_stname) + 1,
                len(self._stations),
                len(self._getPicks()),
            )
            if self._current_filter is not None:
                msg += " - Bandpass %s [%.2f - %.2f Hz]" % (
                    self.bpfilter[self._current_filter]["name"],
                    self.bpfilter[self._current_filter]["freqmin"],
                    self.bpfilter[self._current_filter]["freqmax"],
                )
            else:
                msg += " - Raw Data"
            self.statusBar().showMessage(msg)

    def _openCatalogDlg(self):
        filename = QtGui.QFileDialog.getOpenFileName(
            self, "Load QuakeML Picks", os.getcwd(), "QuakeML Format (*.xml)", "20"
        )
        if filename:
            self._openCatalog(str(filename))
            self.savefile = str(filename)

    def _openCatalog(self, filename):
        """
        Open existing QuakeML catalog
        """
        try:
            print "Opening QuakeML Catalog %s" % filename
            cat = event.readEvents(filename)
            self._picks = cat[0].picks
            self._drawPicks()
        except:
            msg = "Could not open QuakeML file %s" % (filename)
            raise IOError(msg)

    def _saveCatalogDlg(self):
        """
        Save catalog through QtDialog
        """
        self.savefile = QtGui.QFileDialog.getSaveFileName(
            self, "Save QuakeML Picks", os.getcwd(), "QuakeML Format (*.xml)"
        )
        if not self.savefile:
            self.savefile = None
            return
        self.savefile = str(self.savefile)
        if os.path.splitext(self.savefile)[1].lower() != ".xml":
            self.savefile += ".xml"
        self._saveCatalog()

    def _saveCatalog(self, filename=None):
        """
        Saves the catalog to filename
        """
        if self.savefile is None and filename is None:
            return self._saveCatalogDlg()
        if filename is not None:
            savefile = filename
        else:
            savefile = self.savefile
        cat = event.Catalog()
        cat.events.append(event.Event(picks=self._picks))
        cat.write(savefile, format="QUAKEML")
        print "Picks saved as %s" % savefile

    def _savePlotDlg(self):
        """
        Save Plot Image Qt Dialog and Matplotlib wrapper
        """
        filename = QtGui.QFileDialog.getSaveFileName(
            self, "Save Plot", os.getcwd(), "Image Format (*.png *.pdf *.ps *.svg *.eps)"
        )
        if not filename:
            return
        filename = str(filename)
        format = os.path.splitext(filename)[1][1:].lower()
        if format not in ["png", "pdf", "ps", "svg", "eps"]:
            format = "png"
            filename += "." + format
        self.fig.savefig(filename=filename, format=format, dpi=72)

    def getPicks(self):
        return self._picks

    def _opnWadatiPlot(self):
        self._wadatiPlt = QtGui.NewWindow()
        self._wadatiPlt.show()

    def _infoDlg(self):
        msg = """
                <h3><b>obspy.core.stream-Picker</b></h3>
                <br><br>
                <div>
                StreamPick is a lightweight seismological
                wave time picker for <code>obspy.core.Stream()</code>
                objects. It further utilises the <code>obspy.core.event</code>
                class to store picks in the QuakeML format.
                </div>
                <h4>Controls:</h4>
                <blockquote>
                <table>
                    <tr>
                        <td width=20><b>%s</b></td><td>Next station</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td><td>Previous station</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td><td>Toggle filter</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Set P-Phase pick at mouse position</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Set S-Phase pick at mouse position</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Set custom phase pick at mouse position</td>
                    </tr>
                    <tr>
                        <td width=20><b>%s</b></td>
                        <td>Remove last pick in trace</td>
                    </tr>
                </table>
                </blockquote>
                <h4>Plot Controls:</h4>
                <blockquote>
                Use mouse wheel to zoom in- and out. Middle mouse button moves
                plot along x-axis.<br>
                Hit <b>Ctrl</b> to manipulate a single plot.
                <br>
                </blockquote>
                <div>
                Programm stores filter parameters in <code>.pick_filter</code>
                and a backup of recent picks in
                <code>.picks-obspy.xml.bak</code>.<br><br>
                See <a href=http://www.github.org/miili/StreamPick>
                http://www.github.org/miili/StreamPick</a> and
                <a href=http://www.obspy.org>http://www.obspy.org</a>
                for further documentation.
                </div>
                """ % (
            self._shortcuts["st_next"],
            self._shortcuts["st_previous"],
            self._shortcuts["filter_apply"],
            self._shortcuts["pick_p"],
            self._shortcuts["pick_s"],
            self._shortcuts["pick_custom"],
            self._shortcuts["pick_remove"],
        )
        QtGui.QMessageBox.about(self, "About", msg)

    def _canvasDraw(self):
        """
        Redraws the canvas and re-sets mouse focus
        """
        for _i, _ax in enumerate(self.fig.get_axes()):
            _ax.set_xticklabels(_ax.get_xticks() * self._current_st[_i].stats.delta)
        self.canvas.draw_idle()
        self.canvas.flush_events()
        self.canvas.setFocus()
        return

    def closeEvent(self, evnt):
        """
        This function is called upon closing the QtGui
        """
        # Save Picks
        pickle.dump(self.bpfilter, open(".pick_filters", "w"))
        # Save Catalog
        if len(self._picks) > 0:
            self._saveCatalog(".picks-obspy.xml.bak")
        if self.savefile is None and len(self._picks) > 0:
            ask = QtGui.QMessageBox.question(
                self,
                "Save Picks?",
                "Do you want to save your picks?",
                QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel,
                QtGui.QMessageBox.Save,
            )
            if ask == QtGui.QMessageBox.Save:
                self._saveCatalog()
            elif ask == QtGui.QMessageBox.Cancel:
                evnt.ignore()
        print self._picks

    # Filter Dialog
    class defFilter(QtGui.QDialog):
        def __init__(self, parent=None, filtervalues=None):
            """
            Bandpass filter dialog... Qt layout and stuff
            """
            QtGui.QDialog.__init__(self, parent)
            self.setWindowTitle("Create new Bandpass-Filter")

            # Frequency QDoubleSpinBoxes
            self.frqmin = QtGui.QDoubleSpinBox(decimals=2, maximum=100, minimum=0.01, singleStep=0.1, value=0.1)
            self.frqmax = QtGui.QDoubleSpinBox(decimals=2, maximum=100, minimum=0.01, singleStep=0.1, value=10.0)

            # Radio buttons for corners
            _corners = [2, 4, 8]
            _radbtn = []
            for _c in _corners:
                _radbtn.append(QtGui.QRadioButton(str(_c)))
                if _c == 4:
                    _radbtn[-1].setChecked(True)

            self.corner = QtGui.QButtonGroup()
            self.corner.setExclusive(True)

            radiogrp = QtGui.QHBoxLayout()
            for _i, _r in enumerate(_radbtn):
                self.corner.addButton(_r, _corners[_i])
                radiogrp.addWidget(_radbtn[_i])

            # Filter name
            self.fltname = QtGui.QLineEdit("Filter Name")
            self.fltname.selectAll()

            # Make Layout
            grid = QtGui.QGridLayout()
            grid.addWidget(QtGui.QLabel("Filter Name"), 0, 0)
            grid.addWidget(self.fltname, 0, 1)
            grid.addWidget(QtGui.QLabel("Min. Frequency"), 1, 0)
            grid.addWidget(self.frqmin, 1, 1)
            grid.addWidget(QtGui.QLabel("Max. Frequency"), 2, 0)
            grid.addWidget(self.frqmax, 2, 1)
            grid.addWidget(QtGui.QLabel("Corners"), 3, 0)
            grid.addLayout(radiogrp, 3, 1)
            grid.setVerticalSpacing(10)

            btnbox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
            btnbox.accepted.connect(self.accept)
            btnbox.rejected.connect(self.reject)

            layout = QtGui.QVBoxLayout()
            layout.addWidget(
                QtGui.QLabel(
                    "Define a minimum and maximum"
                    + " frequency\nfor the bandpass filter.\nFunction utilises "
                    + "obspy.signal.filter (zerophase=True).\n"
                )
            )
            layout.addLayout(grid)
            layout.addWidget(btnbox)

            if filtervalues is not None:
                self.fltname.setText(filtervalues["name"])
                self.frqmin.setValue(filtervalues["freqmin"])
                self.frqmax.setValue(filtervalues["freqmax"])
                self.corner.button(filtervalues["corners"]).setChecked(True)

            self.setLayout(layout)
            self.setSizeGripEnabled(False)

        def getValues(self):
            """
            Return filter dialogs values as a dictionary
            """
            return dict(
                name=str(self.fltname.text()),
                freqmin=float(self.frqmin.cleanText()),
                freqmax=float(self.frqmax.cleanText()),
                corners=int(int(self.corner.checkedId())),
            )
예제 #15
0
class SecondUiClass(QtGui.QMainWindow):
    Log_pressure = False
    Import = False
    filepath = None
    import_filepath = None

    def __init__(self, parent=None):
        super(SecondUiClass, self).__init__(parent)
        # Create the window.
        self.main = QtGui.QWidget()
        self.setCentralWidget(self.main)
        self.layout = QtGui.QVBoxLayout(self.main)
        self.setGeometry(100, 100, 1000, 600)
        self.setWindowTitle('FHiRE Vacuum Controller - Graphing Window')

        # Set up the action menu.
        actionPressure = QtGui.QAction('Graph Pressure', self)
        actionLog_Pressure = QtGui.QAction('Graph Log Pressure', self)
        actionPressure.triggered.connect(self.PlotPressure)
        actionLog_Pressure.triggered.connect(self.PlotLogPressure)

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('&Options')
        fileMenu.addAction(actionPressure)
        fileMenu.addAction(actionLog_Pressure)

        # Set up the figure.
        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)
        self.layout.addWidget(self.canvas)
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolbar)

    # Main plotting process.
    def Plot(self, importing):
        # Set up the graph.
        self.ax = self.figure.add_subplot(111)
        self.ax.hold(False)

        #printInfo("self.filepath: %s" %self.filepath)
        #printInfo("self.import_filepath: %s" %self.import_filepath)

        # Check if importing or using live data.
        self.importing = importing
        if self.importing == False:
            open_file = self.filepath
        else:
            open_file = self.import_filepath
            if self.import_filepath == None:
                printInfo("Please import a pressure log file.")

        # Graph pressure vs. time.
        try:
            date, pressure = np.loadtxt(open_file, unpack=True, skiprows=1)
        except ValueError:
            printInfo("Error: Need more values to graph.")
            return
        self.ax.plot(date, pressure, 'r-')
        filename = open_file.split('/')[-1]

        # Format axes.
        self.ax.set_title("Graphing: %s" % filename)
        self.ax.set_xlabel('Time (h:m:s)')
        self.ax.set_ylabel('Pressure (mbar)')
        myFmt = mdates.DateFormatter('%H:%M:%S')
        self.ax.xaxis.set_major_formatter(myFmt)
        self.ax.xaxis.set_minor_locator(AutoMinorLocator())
        self.ax.yaxis.set_minor_locator(AutoMinorLocator())
        y_formatter = mtick.ScalarFormatter(useOffset=True)
        self.ax.yaxis.set_major_formatter(y_formatter)
        self.ax.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.3e'))
        self.ax.grid()

        # Display the graph.
        self.canvas.draw()
        self.canvas.flush_events()

    # Modify the plot to show pressure or log pressure.
    def PlotPressure(self):
        self.Log_pressure = False
        self.updateThread()

    def PlotLogPressure(self):
        self.Log_pressure = True
        self.updateThread()

    # This thread allows updates to be made to the graph after creation.
    # Used for updating y axis.
    def updateThread(self):
        update_thread = threading.Thread(target=self.UpdatePlot)
        update_thread.setDaemon(True)
        update_thread.start()

    # Update the graph. Used for autoplotting.
    def UpdatePlot(self):
        date, pressure = np.loadtxt(self.filepath, unpack=True, skiprows=1)

        if self.Log_pressure == True:
            pressure = np.log10(pressure)
            self.ax.set_ylabel('Log Pressure (mbar)')
        else:
            self.ax.set_ylabel('Pressure (mbar)')

        self.ax.plot(date, pressure, 'r-')
        filename = self.filepath.split('/')[-1]

        self.ax.set_title("Graphing: %s" % filename)
        self.ax.set_xlabel('Time (h:m:s)')
        myFmt = mdates.DateFormatter('%I:%M:%S')
        self.ax.xaxis.set_major_formatter(myFmt)
        self.ax.xaxis.set_minor_locator(AutoMinorLocator())

        self.ax.yaxis.set_minor_locator(AutoMinorLocator())
        y_formatter = mtick.ScalarFormatter(useOffset=True)
        self.ax.yaxis.set_major_formatter(y_formatter)
        self.ax.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.3e'))
        self.ax.grid()
        self.ax.relim()
        self.ax.autoscale_view()
        self.toolbar.update()

        self.canvas.draw()
        self.canvas.flush_events()
예제 #16
0
class mpl_widget(QWidget):
    def __init__(self, parent=None, mainWidget=None):
        self._SELECTEDCELLS = list()       # container for instances of selected cells, so we can delete them when we want
        self._SELECTEDCELLS_IJ = list()  # container for coords of selected cells, so we can delete them when we want
        self._SELECTEDCELLLINES = list()   # container for instances of selected cells, so we can delete them when we want
        self._GRIDLINES = None
        QWidget.__init__(self, parent)
        self.mainWidget = mainWidget
        self.create_main_frame()
        self.mpl_menu = mpl_menu(self)
        self.shift_is_held = False
        #self.connect(self.mpl_menu, QtCore.SIGNAL('mySignal'), self.mySlot)
        #print 'my parent is:', parent
        self.clear_selection()
        self.init_tooltips()

    def init_tooltips(self):
        self.canvas.setToolTip('If 2D plot => RMB click toggles menu <br> - RMB click selects cell <br> - selected cells are drawn with black border')
        self.grid_cb.setToolTip('If 2D plot => show computational grid <br> If 1D plot => show normal gridlines')
        self.cbar_button.setToolTip('If 2D plot => controls the color range. <br> Note: <br> - pressing UP and DOWN arrows cycles through colormaps <br> - dragging colorbar with RMB scales the color-range <br> - dragging colorbar with LMB shifts the color-range')
        self.mpl_toolbar.setToolTip('Shows coordinates (i,j, lat,lon) and data-value(z) under the cursor. <br> if you see <i>>>></i> coordinates are not visible. Enlarge the window')

    def create_main_frame(self):

        self.fig = Figure(dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.canvas.setFocusPolicy( Qt.ClickFocus )
        self.canvas.setFocus()

        self.mpl_toolbar = myNavigationToolbar(self.canvas, self)
        self.canvas.mpl_connect('button_press_event', self.on_click)
        self.canvas.mpl_connect('key_press_event', self.on_key_press)
        self.canvas.mpl_connect('key_release_event', self.on_key_release)
        #self.canvas.mpl_connect('button_press_event', self.disable_clicks)


        self.cbar_button = QPushButton("Color Range")
        self.cbar_button.setFocusPolicy( Qt.NoFocus )
        self.grid_cb = QCheckBox("Show Grid")
        self.grid_cb.setFocusPolicy( Qt.NoFocus )
        self.grid_cb.stateChanged.connect(self.showGrid)

        vbox = QVBoxLayout()
        hbox = QHBoxLayout()

        vbox.addWidget(self.canvas)  # the matplotlib canvas
        hbox.addWidget(self.mpl_toolbar)
        hbox.addWidget(self.cbar_button)
        hbox.addWidget(self.grid_cb)
        vbox.addLayout(hbox)
        self.setLayout(vbox)



    def on_click(self, event):
        if event.inaxes != self.get_axes()[0]: return
        #if self.get_axes()[0].format_coord(event.x, event.y) == 'outside data area': return
        if self.allow_menu():
            self.allow_popup_menu = True
            if self.shift_is_held:
                self.allow_popup_menu = False

            point = [int(event.xdata + .5), int(event.ydata + .5)]
            #print '>>>', point, '\t currently {0} selected'.format(len(self._SELECTEDCELLS))
            if event.button == 3 :  #if RMB is clicked

                # working with dialog for transect!
                if self.mainWidget.transect_dlg:
                    if self.mainWidget.transect_dlg.toogle_show_after_selected_cell:
                        realx, realy = self.get_real_xy(event.xdata, event.ydata, self.mainWidget.detect_variable_dimensions())
                        realpoint = [realy, realx]
                        #print 'real xy:', realpoint
                        if self.mainWidget.transect_dlg.toogle_show_after_selected_cell == 1:  # select point 1
                            self.allow_popup_menu = False
                            self.mainWidget.transect_dlg.data.set_p1(realpoint)
                        elif self.mainWidget.transect_dlg.toogle_show_after_selected_cell == 2:  # select point 2
                            self.allow_popup_menu = False
                            self.mainWidget.transect_dlg.data.set_p2(realpoint)

                        self.mainWidget.transect_dlg.update()
                        self.mainWidget.transect_dlg.show()
                
                # working with dialog for flux!
                if self.mainWidget.flux_dlg:
                    if self.mainWidget.flux_dlg.toogle_show_after_selected_cell:
                        if self.mainWidget.flux_dlg.toogle_show_after_selected_cell == 1:  # select point 1
                            self.allow_popup_menu = False
                            self.mainWidget.flux_dlg.data.set_p1(point)
                        elif self.mainWidget.flux_dlg.toogle_show_after_selected_cell == 2:  # select point 2
                            self.allow_popup_menu = False
                            self.mainWidget.flux_dlg.data.set_p2(point)

                        self.mainWidget.flux_dlg.update()
                        self.mainWidget.flux_dlg.show()



                if len(self._SELECTEDCELLS) == 0:  # if no cell is selected
                    self.add_selected_cell(point)


                else:  # if some cells are already selected
                    if self.mpl_menu.allow_rmb_select_cells() or self.shift_is_held:
                        # check if this point is already selected:
                        already_selected = False
                        for p in self._SELECTEDCELLS_IJ:
                            if (point[0] == p[0]) and (point[1] == p[1]):
                                already_selected = True
                                print 'cell already selected... is not added'

                        if not already_selected:
                            self.add_selected_cell(point)
                    else:
                        pass
                        #self.clear_selection()
                        #self.add_selected_cell(point)

    def cells_selected(self):
        if self._SELECTEDCELLS: return len(self._SELECTEDCELLS)
        else: return False

    def add_selected_cell(self, point):
        ''' point = [i, j]'''
        print 'selected cell:', point[0], point[1]
        c = self.draw_picked_cell(point)
        self._SELECTEDCELLS.append(c)
        self._SELECTEDCELLS_IJ.append(point)




    def get_selected_cells_ij(self):
        return self._SELECTEDCELLS_IJ

    def clear_selection(self):
        '''
        delete all graphical objects of selected cells
        redraw canvas
        '''
        print 'clearing stuff'
        if len(self._SELECTEDCELLLINES) > 0:
            for line in self._SELECTEDCELLLINES:
                l = line.pop(0)
                l.remove()
                del l
            del self._SELECTEDCELLLINES[:]
        #print 'cells ---- before:', len(self._SELECTEDCELLS)
        if len(self._SELECTEDCELLS) > 0:
            for cell in self._SELECTEDCELLS:
                for line in cell:
                    l = line.pop(0)
                    l.remove()
                    del l
            del self._SELECTEDCELLS[:]
        #print 'cells ---- left:', len(self._SELECTEDCELLS)


        #print 'cells-coords ----'
        #print len(self._SELECTEDCELLS_IJ)
        if self._SELECTEDCELLS_IJ:
            for cellcoords in self._SELECTEDCELLS_IJ:
                #cc = cellcoords.pop(0)
                #cellcoords.remove()
                del cellcoords
            del self._SELECTEDCELLS_IJ[:]
        #print 'cells ---- left,', len(self._SELECTEDCELLS_IJ)



        if len(self._SELECTEDCELLS) != 0:
            raise ValueError('List "self._SELECTEDCELLS" was not flushed')

        if len(self._SELECTEDCELLLINES) != 0:
            raise ValueError('List "self._SELECTEDCELLLINES" was not flushed')

        if len(self._SELECTEDCELLS_IJ) != 0:
            raise ValueError('List "self._SELECTEDCELLLINES" was not flushed')
        # update plot
        self.canvas.draw()
        #print 'finishing clear: cells left', len(self._SELECTEDCELLS)


    def showGrid(self, state):
        if self.fig.axes:
            current_plot = self.mainWidget.get_plotType()
            current_plot2D = self.mainWidget.get_plotType_for_timeseries()
            if state == Qt.Checked:
                if current_plot == '1D' or (current_plot2D =="2DZT"):
                    self.fig.axes[0].grid(True)
                elif current_plot == '2D' and (not current_plot2D =="2DZT"):
                    self.draw_pixel_grid(True)
            else:
                if current_plot == '1D' or (current_plot2D =="2DZT"):
                    self.fig.axes[0].grid(False)
                elif current_plot == '2D' and (not current_plot2D =="2DZT"):
                    self.draw_pixel_grid(False)
            self.canvas.draw()

    def draw_picked_cell(self, point):
        x = point[0]
        y = point[1]
        '''
        approach drawing a patch... not working
        cell_bnd = patches.Rectangle((x-.5, y-.5), 1, 1, fill=False, edgecolor="black", hatch=None, linewidth=1.)
        cell_instance = self.fig.axes[0].add_patch(cell_bnd)
        '''

        b_line = [(x-.5, x+.5), (y-.5, y-.5)]
        r_line = [(x+.5, x+.5), (y-.5, y+.5)]
        t_line = [(x-.5, x+.5), (y+.5, y+.5)]
        l_line = [(x-.5, x-.5), (y-.5, y+.5)]
        cell = [b_line, r_line, t_line, l_line]
        for i, l in enumerate(cell):
            ll = self.fig.axes[0].plot(l[0], l[1], 'k-', lw=.8)
            cell[i] = ll  # overwriting current Line2D object with object binded to an axes
        #self._SELECTEDCELLS.append(cell)  # collecting reference to this cell to be able to delete it
        #self._SELECTEDCELLS_IJ.append(point)  # collecting reference to this cell to be able to delete it

        self.canvas.draw()
        return cell


    def draw_line(self, point1, point2):
        line = [(point1[0], point2[0]), (point1[1], point2[1])]
        l = self.fig.axes[0].plot(line[0], line[1], 'k-', lw=2)
        return l

    def draw_pixel_grid(self, enable=True):
        if enable:
            dx = 1
            dy = 1
            x0 = -.5
            y0 = -.5

            if self.mainWidget.get_plotType_for_timeseries() == '2DXY':
                nx = self.mainWidget.get_nX()
                ny = self.mainWidget.get_nY()
            elif self.mainWidget.get_plotType_for_timeseries() == '2DZY':
                nx = self.mainWidget.get_nY()
                ny = self.mainWidget.get_nZ()
            elif self.mainWidget.get_plotType_for_timeseries() == '2DZX':
                nx = self.mainWidget.get_nX()
                ny = self.mainWidget.get_nZ()

            self._GRIDLINES = list()
            for n_hline in np.arange(ny+1):
                hline = [(x0, x0+nx), (y0+n_hline, y0+n_hline)]
                l = self.fig.axes[0].plot(hline[0], hline[1], 'k-', lw=.2)
                self._GRIDLINES.append(l)  # collecting reference to this line to be able to delete it

            for n_vline in np.arange(nx+1):
                vline = [(x0+n_vline, x0+n_vline), (y0, y0+ny)]
                l = self.fig.axes[0].plot(vline[0], vline[1], 'k-', lw=.2)
                self._GRIDLINES.append(l)  # collecting reference to this line to be able to delete it


        if not enable:
            #print 'deleting lines...'
            if self._GRIDLINES:  # if lines were created
                #print 'lines are here...'
                for line in self._GRIDLINES:
                    #print line
                    l = line.pop(0)
                    l.remove()
                    del l
            self.fig.canvas.draw()

    def on_key_press(self, event):
        #print 'key pressed:', event.key
        if event.key == 'shift':
            self.shift_is_held = True


    

    def on_key_release(self, event):
        #print 'key released:', event.key
        if event.key == 'shift':
            self.shift_is_held = False

        elif event.key == 'escape':
            self.clear_selection()


    def change_coordinate_formatter(self, ax, data2d,  bruteforce_flag=None, bruteforce_dims=None):
        ''' see http://stackoverflow.com/questions/14754931/matplotlib-values-under-cursor
        '''
        numrows, numcols = data2d.shape
        bruteforce_mode_on = False
        bruteforce_mode_on = (bruteforce_flag == '2DXY' and bruteforce_dims[-1] and bruteforce_dims[-2])


        def format_coord(x, y):
            col = int(x+0.5)
            row = int(y+0.5)

            if not bruteforce_mode_on:
                if col >= 0 and col < numcols and row >= 0 and row < numrows:
                    #z = data2d[row, col]
                    # sice we have artificially reversed y-coordinate axes, now reverse data!
                    # numrows-1, because if nrows=10 => row=[0:9]
                    z = data2d[numrows-1-row, col]
                    #return 'x=%1.1f y=%1.1f z=%1.6f' % (x, y, z)
                    return 'i=%d j=%d z=%.6f' % (col, row, z)
                else:
                    #return 'x=%1.4f, y=%1.4f' % (x, y)
                    return 'outside data area'

            elif bruteforce_flag == '2DXY' and bruteforce_dims[-1] and bruteforce_dims[-2]:
                '''
                our extend in X=[-0.5:numcols-0.5], Y=[-0.5:numrows-0.5], because col,row is cell center!
                '''
                if col >= 0 and col < numcols and row >= 0 and row < numrows:
                    #z = data2d[row, col]
                    # sice we have artificially reversed y-coordinate axes, now reverse data!
                    # numrows-1, because if nrows=10 => row=[0:9]
                    z = data2d[numrows-1-row, col]
                    real_x, real_y = self.get_real_xy(x, y, bruteforce_dims)

                    #return 'x=%1.1f y=%1.1f z=%1.6f' % (x, y, z)
                    #return 'i=%d j=%d z=%.3f x=%.4f y=%.4f' % (col, row, z, real_x, real_y)
                    return 'i=%d j=%d z=%.3f, %s=%.2f %s=%.2f' % (
                        col, row, z, bruteforce_dims[-1], real_x, bruteforce_dims[-2], real_y)
                else:
                    #return 'x=%1.4f, y=%1.4f' % (x, y)
                    return 'outside data area'
            else:
                raise ValueError('bruteforce_flag can be $None$ or $"2DXY"$. Passed %s' % bruteforce_flag)
        ax.format_coord = format_coord


    def allow_menu(self):
        allow = False
        #print "self.mainWidget.get_plotType():", self.mainWidget.get_plotType()
        #print "self.mainWidget.get_plotType_for_timeseries():", self.mainWidget.get_plotType_for_timeseries()
        if self.mainWidget.get_plotType() == "2D" and not self.mainWidget.get_plotType_for_timeseries() == "2DZT":
            allow = True
        return allow
    

    def get_real_xy(self, i, j, dimension_list):
        '''
        functions returns values of x,y based on passed indexes i, j

        '''
        if any(dimension_list[-2:-1]) is None:
            print 'Dimensions X,Y of current variable are not specified (variables that have same name as dimensions not found)'
            raise ValueError('Dimensions X,Y of current variable are not specified (variables that have same name as dimensions not found)')
        nc = self.mainWidget.get_selected_ncfile_instance()
        try:
            x_var = nc.variables[dimension_list[-1]]
            y_var = nc.variables[dimension_list[-2]]
            
        except:
            
            print ('Failed to load variables: {0}, {1}'.format(dimension_list[-1], dimension_list[-2]))
            raise ValueError('Failed to load variables: {0}, {1}'.format(dimension_list[-1], dimension_list[-2]))


        x_ratio = (x_var[-1]-x_var[0])/(len(x_var)-1)
        y_ratio = (y_var[-1]-y_var[0])/(len(y_var)-1)

        #x[i] = x_var[0]+x_ratio*i
        #y[j] = y_var[0]+y_ratio*j
        x = x_var[0] + x_ratio*i
        y = y_var[0] + y_ratio*j
        nc.close()
        return (x, y)

    def get_axes(self):
        return self.fig.get_axes()
    

    def fast_redraw(self, artist):
        background = [self.canvas.copy_from_bbox(self.get_axes()[0].bbox)]
        self.get_axes()[0].draw_artist(artist)
        self.canvas.restore_region(background)
        self.canvas.blit(self.get_axes()[0].bbox)
        self.canvas.update()
        self.canvas.flush_events()