def __init__(self,parent=None): self.parent = parent QtGui.QWidget.__init__(self,None,QtCore.Qt.WindowStaysOnTopHint) self.setupGUI() self.fWidget = TriplePlotWidget() self.phWidget = TriplePlotWidget() self.bWidget = BindingWidget(parents=[parent,self]) self.isWidget = InterpretationSettingsWidget() self.data = {'P':{},'Sx':{},'Sy':{}} self.currentShifts = {'P':0,'Sx':0,'Sy':0} self.connectPlotButtons() self.gEdit = GradientEditorWidget() self.gw = self.gEdit.sgw self.fgw = self.gEdit.fgw self.pgw = self.gEdit.pgw # sel self.gw.restoreState(Gradients['hot']) self.fgw.restoreState(Gradients['hot']) self.pgw.restoreState(Gradients['hot']) self.allParameters = [] self.yAxis = 'Track #' self.y = {} self.aTimes = {} # Connect everything self.showArrivalsButton.triggered.connect(self.parent.plotSonicData) self.pickArrivalsButton.triggered.connect(self.pickAllArrivals) self.invertYButton.triggered.connect(self.parent.plotSonicData) self.autoScaleButton.triggered.connect(self.autoScalePlots) self.editGradientsButton.triggered.connect(self.gEdit.show) self.gEdit.okButton.pressed.connect(self.parent.plotSonicData) self.showTableButton.triggered.connect(self.showTable) self.showForrierMagnitudeButton.triggered.connect(self.showFourrier) self.showForrierPhasesButton.triggered.connect(self.showPhases) # self.showArrivalsButton.triggered.connect(self.plot) self.waveFormButton.triggered.connect(lambda: self.setMode('WaveForms')) self.contourButton.triggered.connect(lambda: self.setMode('Contours')) self.moduliButton.triggered.connect(self.isWidget.show) self.isWidget.okButton.pressed.connect(self.runBindingWidget) self.filteringButton.triggered.connect(self.parent.plotSonicData) self.fWidget.sigRegionChanged.connect(self.plotFilteredData) # self.moduliButton.triggered.connect(self.bWidget.run) for wave in WaveTypes: self.params[wave].param('Arrival times').param('Mpoint').sigValueChanged.connect(self.recomputeArrivals) self.params[wave].param('Arrival times').param('BTA').sigValueChanged.connect(self.recomputeArrivals) self.params[wave].param('Arrival times').param('ATA').sigValueChanged.connect(self.recomputeArrivals) self.params[wave].param('Arrival times').param('DTA').sigValueChanged.connect(self.recomputeArrivals) self.plots[wave].vb.sigAltClick.connect(self.handPick)
class SonicViewer(QtGui.QWidget): ''' Has 3 plots stored in dict plots={'P':,'Sx':,'Sy':} has 3 modifuing parameter trees to operate data: Shift - shift the data along x axis Amplify ''' mode = 'Contours' autoShift = {'P':True,'Sx':True,'Sy':True} # flag to match 0 and transmission time arrivalsPicked = False updateQTable = True # don't need skipPlottingFAmpFlag = False skipPlottingFPhaseFlag = False def __init__(self,parent=None): self.parent = parent QtGui.QWidget.__init__(self,None,QtCore.Qt.WindowStaysOnTopHint) self.setupGUI() self.fWidget = TriplePlotWidget() self.phWidget = TriplePlotWidget() self.bWidget = BindingWidget(parents=[parent,self]) self.isWidget = InterpretationSettingsWidget() self.data = {'P':{},'Sx':{},'Sy':{}} self.currentShifts = {'P':0,'Sx':0,'Sy':0} self.connectPlotButtons() self.gEdit = GradientEditorWidget() self.gw = self.gEdit.sgw self.fgw = self.gEdit.fgw self.pgw = self.gEdit.pgw # sel self.gw.restoreState(Gradients['hot']) self.fgw.restoreState(Gradients['hot']) self.pgw.restoreState(Gradients['hot']) self.allParameters = [] self.yAxis = 'Track #' self.y = {} self.aTimes = {} # Connect everything self.showArrivalsButton.triggered.connect(self.parent.plotSonicData) self.pickArrivalsButton.triggered.connect(self.pickAllArrivals) self.invertYButton.triggered.connect(self.parent.plotSonicData) self.autoScaleButton.triggered.connect(self.autoScalePlots) self.editGradientsButton.triggered.connect(self.gEdit.show) self.gEdit.okButton.pressed.connect(self.parent.plotSonicData) self.showTableButton.triggered.connect(self.showTable) self.showForrierMagnitudeButton.triggered.connect(self.showFourrier) self.showForrierPhasesButton.triggered.connect(self.showPhases) # self.showArrivalsButton.triggered.connect(self.plot) self.waveFormButton.triggered.connect(lambda: self.setMode('WaveForms')) self.contourButton.triggered.connect(lambda: self.setMode('Contours')) self.moduliButton.triggered.connect(self.isWidget.show) self.isWidget.okButton.pressed.connect(self.runBindingWidget) self.filteringButton.triggered.connect(self.parent.plotSonicData) self.fWidget.sigRegionChanged.connect(self.plotFilteredData) # self.moduliButton.triggered.connect(self.bWidget.run) for wave in WaveTypes: self.params[wave].param('Arrival times').param('Mpoint').sigValueChanged.connect(self.recomputeArrivals) self.params[wave].param('Arrival times').param('BTA').sigValueChanged.connect(self.recomputeArrivals) self.params[wave].param('Arrival times').param('ATA').sigValueChanged.connect(self.recomputeArrivals) self.params[wave].param('Arrival times').param('DTA').sigValueChanged.connect(self.recomputeArrivals) self.plots[wave].vb.sigAltClick.connect(self.handPick) def handPick(self,sender,pos): if not self.handPickArrivalsButton.isChecked(): return else: # first find sender for wave in self.getActivePlots(): if self.plots[wave].vb == sender: break # now wave is the type sent the signal # find closest sonic track to the y position closest = abs(self.y[wave] - pos.y()).argmin() self.aTimes[wave][closest] = pos.x() self.parent.plotSonicData() def plotFilteredData(self): self.skipPlottingFAmpFlag = True self.parent.plotSonicData() def runBindingWidget(self): testconf = self.isWidget.testconf capsconf = self.isWidget.capsconf if testconf == None: return 0 dens = self.isWidget.dens length = self.isWidget.length atime = self.isWidget.atime self.bWidget.setConfig(testconf,capsconf,dens,length,atime) self.bWidget.run() def setData(self,data): ''' data is a dictionary with keys: P,Sx,Sy ''' for wave in WaveTypes: self.data[wave] = data[wave] self.createTable() self.getFourrierTransforms() self.arrivalsPicked = False def hasData(self): ''' check if the viewer has data to work with ''' for wave in WaveTypes: if len(self.data[wave])>0: return True return False def createTable(self): ''' store all data in one 3D np-array 1st dimension - time or amplitude 2nd dimension - number of file 3rd dimension - datapoints ''' if not self.hasData(): return 0 # if no data pass print 'Building sonic matrix' self.table = {} for wave in WaveTypes: self.table[wave] = get_table(self.data[wave]) self.y[wave] = np.arange(self.table[wave].shape[1]) def showFourrier(self): self.fWidget.show() self.fWidget.activateWindow() self.parent.plotSonicData() def showPhases(self): self.phWidget.show() self.phWidget.activateWindow() self.parent.plotSonicData() def getFourrierTransforms(self): if not self.hasData(): return 0 # if no data pass print 'Building Fourrier matrix' self.fft = {} # power self.fftamp = {} # power self.fftph = {} # phase for wave in WaveTypes: x = self.table[wave][0,:,:] y = self.table[wave][1,:,:] N = y.shape[1] h = x[0,1] - x[0,0] # yf = np.fft.fft(y).real[:,:N/2] ft = np.fft.fft(y) fft = ft[:,:N/2] fft = np.fft.fft(y)[:,:N/2] yf = np.absolute(fft) yp = np.arctan2(fft.imag,fft.real) xf0 = np.fft.fftfreq(N,h) xf = xf0[:N/2] xf = np.tile(xf,y.shape[0]) xf0 = np.tile(xf0,y.shape[0]) xf = xf.reshape(yf.shape[0],yf.shape[1]) xf0 = xf0.reshape(ft.shape[0],ft.shape[1]) self.fft[wave] = np.array((xf0,ft)) self.fftamp[wave] = np.array((xf,yf)) self.fftph[wave] = np.array((xf,yp)) def connectPlotButtons(self): for wave in WaveTypes: self.params[wave].param('Show').sigValueChanged.connect(self.changeLayout) def changeLayout(self): print 'changing layout' for wave in WaveTypes: try: self.sublayout.removeItem(self.plots[wave]) self.fWidget.sublayout.removeItem(self.fWidget.plots[wave]) except: pass for wave in self.getActivePlots(): if wave: self.sublayout.addItem(self.plots[wave]) self.fWidget.sublayout.addItem(self.fWidget.plots[wave]) self.sublayout.nextRow() self.fWidget.sublayout.nextRow() def autoScalePlots(self): if self.autoScaleButton.isChecked(): for wave in self.getActivePlots(): self.plots[wave].enableAutoRange() self.fWidget.plots[wave].enableAutoRange() self.phWidget.plots[wave].enableAutoRange() else: for wave in self.getActivePlots(): self.plots[wave].disableAutoRange() self.fWidget.plots[wave].disableAutoRange() self.phWidget.plots[wave].disableAutoRange() def getActivePlots(self): activePlots = [] for wave in WaveTypes: val = self.params[wave].param('Show').value() if val: activePlots.append(wave) return activePlots def pickAllArrivals(self) : pBar = QtGui.QProgressDialog(None,QtCore.Qt.WindowStaysOnTopHint) pBar.setWindowTitle("Picking first arrivals") pBar.setAutoClose(True) pBar.show() pBar.activateWindow() progress = 0 pBar.setValue(progress) for wave in WaveTypes: self.pickArrivals(wave) progress += 33 pBar.setValue(progress) pBar.setValue(100) self.arrivalsPicked = True self.showArrivalsButton.setDisabled(False) self.moduliButton.setDisabled(False) self.handPickArrivalsButton.setDisabled(False) self.showArrivalsButton.trigger() def getInverseFFT(self): ifft = {} interval = self.fWidget.interval() for wave in WaveTypes: x = self.table[wave][0,:,:] xf = self.fft[wave][0,:,:] yf = copy(self.fft[wave][1,:,:]) yf[abs(xf)<min(interval)] = 0 yf[abs(xf)>max(interval)] = 0 ift = np.fft.ifft(yf) ifft[wave] = np.array((x,ift.real)) return ifft def plot(self,indices=None,yarray=None,yindices=None, amplify=None,yAxisName='Track #'): ''' indices - number of sonic tracks to plot yarray - y values yindices - indices of yarray to plot ''' # print 1 for wave in self.getActivePlots(): plot = self.plots[wave] fplot = self.fWidget.plots[wave] phplot = self.phWidget.plots[wave] plot.clear(); if self.skipPlottingFAmpFlag: pass else: fplot.clear() fplot.getAxis('left').setLabel(yAxisName,**LabelStyle) fplot.getAxis('bottom').setLabel(fXAxisName,**LabelStyle) if self.autoScaleButton.isChecked(): fplot.enableAutoRange(enable=True) else: fplot.disableAutoRange() if self.skipPlottingFPhaseFlag: pass else: phplot.clear() phplot.getAxis('left').setLabel(yAxisName,**LabelStyle) phplot.getAxis('bottom').setLabel(fXAxisName,**LabelStyle) if self.autoScaleButton.isChecked(): phplot.enableAutoRange(enable=True) else: phplot.disableAutoRange() plot.getAxis('left').setLabel(yAxisName,**LabelStyle) plot.getAxis('bottom').setLabel(xAxisName,**LabelStyle) if self.autoScaleButton.isChecked(): plot.enableAutoRange(enable=True) else: plot.disableAutoRange() # Plot data in main sonic viewer if self.filteringButton.isChecked(): self.fWidget.show() # self.fWidget.activateWindow() ifft = self.getInverseFFT() if self.mode == 'WaveForms': self.plotDataWaveForms(ifft,self, indices,amplify,yAxisName) elif self.mode == 'Contours': self.plotDataContours(ifft, self, self.fgw, indices,yarray,yindices, amplify,yAxisName) else: if self.mode == 'WaveForms': self.plotWaveForms(indices,amplify,yAxisName) elif self.mode == 'Contours': self.plotContours(indices,yarray,yindices, amplify,yAxisName) # Plot fourrier transform amplitude data if not self.skipPlottingFAmpFlag: if self.fWidget.isVisible(): if self.filteringButton.isChecked(): self.fWidget.addRegions() if self.mode == 'WaveForms': self.plotDataWaveForms(self.fftamp,self.fWidget, indices,amplify,yAxisName) elif self.mode == 'Contours': self.plotDataContours(self.fftamp, self.fWidget, self.fgw, indices,yarray,yindices, amplify,yAxisName) # Plot fourrier transform phase data if not self.skipPlottingFPhaseFlag: if self.phWidget.isVisible(): if self.mode == 'WaveForms': self.plotDataWaveForms(self.fftph,self.pWidget, indices,amplify,yAxisName) elif self.mode == 'Contours': self.plotDataContours(self.fftph, self.phWidget, self.gw, indices,yarray,yindices, amplify,yAxisName) # Plot arrival times if self.showArrivalsButton.isChecked(): self.plotArrivals(indices,yarray,yindices, amplify,yAxisName) # print 6 self.skipPlottingFAmpFlag = False self.skipPlottingFPhaseFlag = False def plotWaveForms(self,indices=None, amplify=None,yAxisName=''): self.graphicPaths = {} if (amplify is None): amp=np.average(np.abs(np.diff(self.y['P']))) for wave in self.getActivePlots(): plot = self.plots[wave] if self.invertYButton.isChecked(): plot.invertY(True) else: plot.invertY(False) if indices: sind = indices[wave] else: sind = np.arange(self.table[wave].shape[1]) Nlines = len(self.y[wave]) y = amp*self.table[wave][1,sind,:] + self.y[wave].reshape(Nlines,1) # self.params[wave].param('Amplify').setValue(amp) if indices: self.graphicPaths[wave] = MultiLine(self.table[wave][0,sind,:],y) else: self.graphicPaths[wave] = MultiLine(self.table[wave][0,:,:],y) try: plot.addItem(self.graphicPaths[wave]) except: pass def plotDataWaveForms(self, data,widget,indices=None, amplify=None,yAxisName=''): paths = {} amp=np.average(np.abs(np.diff(self.y['P'])))/data['P'].max() for wave in self.getActivePlots(): plot = widget.plots[wave] if self.invertYButton.isChecked(): plot.invertY(True) else: plot.invertY(False) if indices: sind = indices[wave] else: sind = np.arange(data[wave].shape[1]) Nlines = len(self.y[wave]) y = amp*data[wave][1,sind,:] + self.y[wave].reshape(Nlines,1) if indices: paths[wave] = MultiLine(data[wave][0,sind,:],y) else: paths[wave] = MultiLine(data[wave][0,:,:],y) try: plot.addItem(paths[wave]) except: pass def plotDataContours(self,data,widget,gw, indices=None,yarray=None,yindices=None, amplify=None,yAxisName=''): images = {} k = 0 for wave in self.getActivePlots(): plot = widget.plots[wave] if self.invertYButton.isChecked(): plot.invertY(True) else: plot.invertY(False) images[wave] = pg.ImageItem() if indices: z = data[wave][1,indices[wave],:].T else: z = data[wave][1,:,:].T if k == 0: lut = gw.getLookupTable(z.shape[0], alpha=None) images[wave].setImage(z) plot.addItem(images[wave]) x = data[wave][0,0,:] shiftX0 = x[0] scaleX = (x[-1] - x[0])/x.shape[0] y = self.y[wave] ymax = y.max() ymin = y.min() shiftY0 = ymin scaleY = float(ymax - ymin)/y.shape[0] images[wave].translate(shiftX0,shiftY0) images[wave].scale(scaleX,scaleY) # set Colors images[wave].setLookupTable(lut, update=True) k += 1 def plotContours(self,indices=None,yarray=None,yindices=None, amplify=None,yAxisName=''): self.images = {} k = 0 for wave in self.getActivePlots(): plot = self.plots[wave] if self.invertYButton.isChecked(): plot.invertY(True) else: plot.invertY(False) self.images[wave] = pg.ImageItem() if indices: z = self.table[wave][1,indices[wave],:].T else: z = self.table[wave][1,:,:].T if k == 0: lut = self.gw.getLookupTable(z.shape[0], alpha=None) self.images[wave].setImage(z) plot.addItem(self.images[wave]) # scale and shift image x = self.table[wave][0,0,:] shiftX0 = x[0] scaleX = (x[-1] - x[0])/x.shape[0] y = self.y[wave] ymax = y.max() ymin = y.min() shiftY0 = ymin scaleY = float(ymax - ymin)/y.shape[0] self.images[wave].translate(shiftX0,shiftY0) self.images[wave].scale(scaleX,scaleY) # set Colors self.images[wave].setLookupTable(lut, update=True) k += 1 def plotArrivals(self,indices=None,yarray=None,yindices=None, amplify=None,yAxisName='Track #'): try: self.QTable.cellChanged.disconnect(self.editArrivals) except: pass tableLabels = get_list(yAxisName,WaveTypes) self.QTable.setHorizontalHeaderLabels(tableLabels) for wave in self.getActivePlots(): k = WaveTypes.index(wave) if yarray is None: x = self.aTimes[wave] y = np.arange(self.aTimes[wave].shape[0]) else: ind = yindices[wave] sind = indices[wave] y = yarray[ind] x = self.aTimes[wave][sind] if self.updateQTable: self.QTable.setColumn(y,k) self.QTable.setColumn(x,k+3) else: self.QTable.close() # otherwise it stalls plt = self.plots[wave] pen = pg.mkPen(color=(72,209,204), width=2) plt.plot(x,y,pen=pen) self.updateQTable = True self.QTable.cellChanged.connect(self.editArrivals) def setYAxisParameters(self,parameters): # we use setLimits because of weird implementation # in pyqtgraph self.allParameters = parameters self.yAxisMenu.clear() self.yAxisButtons = {} self.yAxisButtons['Track #'] = QtGui.QAction('Track #',self,checkable=True) self.yAxisButtons['Track #'].setActionGroup(self.yAxisGroup) self.yAxisMenu.addAction(self.yAxisButtons['Track #']) for p in parameters: if self.mode == 'Contours' and p!='Time': continue self.yAxisButtons[p] = QtGui.QAction(p,self,checkable=True) self.yAxisButtons[p].setActionGroup(self.yAxisGroup) self.yAxisMenu.addAction(self.yAxisButtons[p]) pass try: print 'Setting y axis to: Time' self.yAxisButtons['Time'].setChecked(True) self.yAxis = 'Time' except: print 'setting was not successful' def setMode(self,mode): ''' takes string arguments: WaveForms and Contours ''' self.mode = mode if mode == 'WaveForms': print 'Setting mode to Wave Forms' # self.modeMenu.setDefaultAction(self.waveFormButton) elif mode == 'Contours': print 'Setting mode to Contours' # self.modeMenu.setDefaultAction(self.contourButton) self.setYAxisParameters(self.allParameters) def setupGUI(self): self.setWindowTitle("Sonic Viewer") pg.setConfigOption('background', (255,255,255)) pg.setConfigOption('foreground',(0,0,0)) self.layout = QtGui.QVBoxLayout() self.layout.setContentsMargins(0,0,0,0) self.layout.setSpacing(0) self.setLayout(self.layout) ## setting up the menu bar self.menuBar = QtGui.QMenuBar() self.layout.setMenuBar(self.menuBar) self.viewMenu = self.menuBar.addMenu('View') self.modeMenu = self.menuBar.addMenu('Mode') self.transformMenu = self.menuBar.addMenu('Transform') self.intMenu = self.menuBar.addMenu('Interpretation') # VIEW MENU self.autoScaleButton = QtGui.QAction('Auto scale',self,checkable=True) self.autoScaleButton.setChecked(True) self.showArrivalsButton = QtGui.QAction('Arrivals',self,checkable=True) self.showArrivalsButton.setDisabled(True) self.showTableButton = QtGui.QAction('Table',self) self.yAxisMenu = self.viewMenu.addMenu('y axis') self.editGradientsButton = QtGui.QAction('Edit Gradients',self) self.invertYButton = QtGui.QAction('Invert y axis',self,checkable=True) self.viewMenu.addAction(self.autoScaleButton) self.viewMenu.addAction(self.showArrivalsButton) self.viewMenu.addAction(self.showTableButton) self.viewMenu.addAction(self.editGradientsButton) self.viewMenu.addAction(self.invertYButton) # MODE MENU self.modeGroup = QtGui.QActionGroup(self) self.waveFormButton = QtGui.QAction('Wave Forms',self,checkable=True) self.contourButton = QtGui.QAction('Contours',self,checkable=True) self.waveFormButton.setActionGroup(self.modeGroup) self.contourButton.setActionGroup(self.modeGroup) self.contourButton.setChecked(True) self.modeMenu.addAction(self.waveFormButton) self.modeMenu.addAction(self.contourButton) # INTERPRETATION MENU self.pickArrivalsButton = QtGui.QAction('Pick arrivals',self) self.handPickArrivalsButton = QtGui.QAction('Hand pick',self,checkable=True) self.moduliButton = QtGui.QAction('Elastic moduli',self) self.moduliButton.setDisabled(True) self.handPickArrivalsButton.setDisabled(True) self.intMenu.addAction(self.pickArrivalsButton) self.intMenu.addAction(self.handPickArrivalsButton) self.intMenu.addAction(self.moduliButton) # TRANSFORM MENU self.showForrierMagnitudeButton = QtGui.QAction('Fourrier magnitude',self) self.showForrierPhasesButton = QtGui.QAction('Fourrier phases',self) self.filteringButton = QtGui.QAction('Frequency filtering',self,checkable=True) self.transformMenu.addAction(self.showForrierMagnitudeButton) self.transformMenu.addAction(self.showForrierPhasesButton) self.transformMenu.addAction(self.filteringButton) # dict to store actions for y Axis self.yAxisButtons = {} self.yAxisGroup = QtGui.QActionGroup(self) self.yAxisButtons['Track #'] = QtGui.QAction('Track #',self,checkable=True) self.yAxisButtons['Track #'].setActionGroup(self.yAxisGroup) self.yAxisMenu.addAction(self.yAxisButtons['Track #']) self.yAxisButtons['Track #'].setChecked(True) # for wave in WaveTypes: # split main widget into plotting area and parameters area self.splitter = QtGui.QSplitter(QtCore.Qt.Horizontal) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.layout.addWidget(self.splitter) # split parameter area into 3 for each wave self.treeSplitter = QtGui.QSplitter() self.treeSplitter.setOrientation(QtCore.Qt.Vertical) self.splitter.addWidget(self.treeSplitter) # create parameter trees self.trees={} for wave in WaveTypes: self.trees[wave] = ParameterTree(showHeader=False) self.treeSplitter.addWidget(self.trees[wave]) # create layout for the plotting area self.sublayout = pg.GraphicsLayoutWidget() self.splitter.addWidget(self.sublayout) self.params = {} self.plots = {} for wave in WaveTypes: # create parameter instances self.params[wave] = Parameter.create(name=wave + ' wave', type='group',children=Parameters) self.trees[wave].setParameters(self.params[wave],showTop=True) # fill plotting area with 3 plots # self.plots[wave] = self.sublayout.addPlot() self.plots[wave] = self.sublayout.addPlot(viewBox=ViewBox()) setup_plot(self.plots[wave]) self.sublayout.nextRow() self.params['Sx'].param('Arrival times').param('BTA').setValue(36) self.params['Sx'].param('Arrival times').param('ATA').setValue(5) self.params['Sx'].param('Arrival times').param('DTA').setValue(20) self.params['Sy'].param('Arrival times').param('BTA').setValue(100) self.params['Sy'].param('Arrival times').param('ATA').setValue(5) self.params['Sy'].param('Arrival times').param('DTA').setValue(30) # create table widget to show arrival times self.QTable = TableWidget(['Number P','Number Sx','Number Sy','P','Sx','Sy']) # self.splitter.addWidget(self.QTable) self.QTable.setColumnCount(6) self.QTable.hide() self.splitter.setSizes([int(self.width()*0.30), int(self.width()*0.35), int(self.width()*0.35) ]) self.splitter.setStretchFactor(0, 0) self.splitter.setStretchFactor(1, 1) self.splitter.setStretchFactor(2, 0) def pickArrivals(self,wave): print 'Computing arrival times for %s wave'%(wave) win = [0,0,0] mpoint = self.params[wave].param('Arrival times').param('Mpoint').value() win[0] = self.params[wave].param('Arrival times').param('BTA').value() win[1] = self.params[wave].param('Arrival times').param('ATA').value() win[2] = self.params[wave].param('Arrival times').param('DTA').value() x = self.table[wave][0,:,:] y = self.table[wave][1,:,:] h = x[0,1] - x[0,0] r = multi_window(y,win) rx = np.arange(r.shape[1])*h + x[0,win[0]] mind = abs(rx-mpoint).argmin() #index of middle point sInd = r[:,:mind].argmax(axis=1) # sender indices sTimes = rx[sInd] # sender times rInd = r[:,mind:].argmax(axis=1) # receiver indices rTimes = rx[mind+rInd] self.aTimes[wave] = rTimes - sTimes # shift initial data so if self.autoShift[wave]: shift = np.mean(sTimes) self.table[wave][0,:,:] -= shift self.autoShift[wave] = False def editArrivals(self): data = self.QTable.getValues() indices = self.parent.trsIndices if self.yAxis == 'Track #': for wave in WaveTypes: indices[wave] = np.arange(len(self.parent.sTimes[wave])) pass self.aTimes['P'][indices['P']] = data[:,3] self.aTimes['Sx'][indices['Sx']] = data[:,4] self.aTimes['Sy'][indices['Sy']] = data[:,5] self.updateQTable = False self.parent.plotSonicData() def recomputeArrivals(self): parent = self.sender().parent().parent().name() wave = parent.split()[0] self.pickArrivals(wave) self.parent.plotSonicData() def showTable(self): # show = self.showTableButton.isChecked() self.QTable.show() self.QTable.activateWindow() def closeEvent(self,event): QtGui.QWidget.closeEvent(self,event) self.fWidget.close() self.phWidget.close() self.QTable.close() self.bWidget.close()