class PickPhaseMenu(): """ Plot a group of seismogram gathers. Set up axes attributes. Create Button Save to save SAC headers to files. """ def __init__(self, gsac, opts, axs): self.gsac = gsac self.opts = opts self.axs = axs self.axpp = axs['Seis'] self.initIndex() self.plotSeis() self.plotSpan() self.connect() pppara = opts.pppara pickLegend(self.axpp, pppara.npick, pppara.pickcolors, pppara.pickstyles) def plotSeis(self): self.plotWave() self.setLimits() self.setLabels() if self.opts.pick_on: self.plotPicks() self.labelSelection() def initIndex(self): """ Initialize indices for page navigation. """ opts = self.opts axs = self.axs selist = self.gsac.selist delist = self.gsac.delist nsel = len(selist) ndel = len(delist) maxsel, maxdel = opts.maxnum pagesize = maxsel + maxdel aipages, ayindex, aybases, ayticks = indexBaseTick(nsel, ndel, pagesize, maxsel) self.aipages = aipages self.ayindex = ayindex self.aybases = aybases self.ayticks = ayticks self.sedelist = [selist, delist] self.ipage = 0 def plotWave(self): """ Plot waveforms for this page. """ opts = self.opts axpp = self.axpp ipage = self.ipage ayindex, aybases, ayticks = self.ayindex, self.aybases, self.ayticks sedelist = self.sedelist plists = [ [ sedelist[j][k] for k in ayindex[ipage][j] ] for j in range(2)] pbases = [ [ k for k in aybases[ipage][j] ] for j in range(2)] pticks = [ [ k for k in ayticks[ipage][j] ] for j in range(2)] npsel = len(pbases[0]) npdel = len(pbases[1]) nsede = [npsel, npdel] # get colors from sacdh.selected colsel = opts.pppara.colorwave coldel = opts.pppara.colorwavedel colors = [[None,] * npsel , [None,] * npdel] for j in range(2): for k in range(nsede[j]): if plists[j][k].selected: colors[j][k] = colsel else: colors[j][k] = coldel # plot pps = [] for j in range(2): nsd = nsede[j] for k in range(nsd): linews = ones(nsd) alphas = ones(nsd) pp = PickPhase(plists[j][k], opts, axpp, pbases[j][k], colors[j][k]) pps.append(pp) self.pps = pps self.ybases = pbases[0] + pbases[1] self.yticks = pticks[0] + pticks[1] abases = pbases[1]+pbases[0] self.azylim = abases[-1]-1, abases[0]+1 def replot(self, ipage): """ Finish plotting of current page and move to prev/next. """ self.ipage = ipage if not self.ipage in self.aipages: print ('End of page.') return self.finish() #self.span.visible = False self.plotSeis() def plotSpan(self): """ Create a SpanSelector for zoom in and zoom out. """ axpp = self.axpp def on_select(xmin, xmax): """ Mouse event: select span. """ if self.span.visible: print 'span selected: %6.1f %6.1f ' % (xmin, xmax) xxlim = (xmin, xmax) axpp.set_xlim(xxlim) self.xzoom.append(xxlim) if self.opts.upylim_on: print ('upylim') for pp in self.pps: pp.updateY(xxlim) axpp.figure.canvas.draw() pppara = self.opts.pppara a, col = pppara.alphatwsele, pppara.colortwsele mspan = pppara.minspan * self.opts.delta self.span = TimeSelector(axpp, on_select, 'horizontal', minspan=mspan, useblit=False, rectprops=dict(alpha=a, facecolor=col)) def on_zoom(self, event): """ Zoom back to previous xlim when event is in event.inaxes. """ evkey = event.key axpp = self.axpp if not axpp.contains(event)[0] or evkey is None: return xzoom = self.xzoom if evkey.lower() == 'z' and len(xzoom) > 1: del xzoom[-1] axpp.set_xlim(xzoom[-1]) print 'Zoom back to: %6.1f %6.1f ' % tuple(xzoom[-1]) if self.opts.upylim_on: for pp in self.pps: del pp.ynorm[-1] setp(pp.lines[0], ydata=pp.ybase+pp.sacdh.data*pp.ynorm[-1]) axpp.figure.canvas.draw() def plotPicks(self): for pp in self.pps: pp.plotPicks() pppara = self.opts.pppara def setLabels(self): """ Set axes labels and page label""" axpp = self.axpp axpp.set_yticks(self.ybases) axpp.set_yticklabels(self.yticks) axpp.set_ylabel('Trace Number') axpp.axhline(y=0, lw=2, color='r') if self.opts.boundlines_on: for yy in range(self.azylim[0], self.azylim[1]): axpp.axhline(y=yy+0.5, color='black') reltime = self.opts.reltime if reltime >= 0: axpp.set_xlabel('Time - T%d [s]' % reltime) else: axpp.set_xlabel('Time [s]') trans = transforms.blended_transform_factory(axpp.transAxes, axpp.transAxes) page = 'Page {0:d} of [{1:d},{2:d}]'.format(self.ipage, self.aipages[0], self.aipages[-1]) self.pagelabel = axpp.text(1, -0.02, page, transform=trans, va='top', ha='right') def setLimits(self): """ Set axes limits """ axpp = self.axpp self.getXLimit() axpp.set_xlim(self.xzoom[0]) axpp.set_ylim(self.azylim) # plot time zero lines and set axis limit axpp.axvline(x=0, color='k', ls=':') if not self.opts.xlimit is None: axpp.set_xlim(self.opts.xlimit) def labelSelection(self): """ Label selection status with transform (transAxes, transData). """ axpp = self.axpp trans = transforms.blended_transform_factory(axpp.transAxes, axpp.transData) colsel = self.opts.pppara.colorwave coldel = self.opts.pppara.colorwavedel axpp.annotate('Selected', xy=(1.015, self.azylim[0]), xycoords=trans, xytext=(1.03, -0.17), size=10, va='top', color=colsel, bbox=dict(boxstyle="round,pad=.2", fc='w', ec=(1,.5,.5)), arrowprops=dict(arrowstyle="->",connectionstyle="angle,angleA=0,angleB=-90,rad=20",color=colsel, lw=2),) axpp.annotate('Deselected', xy=(1.015, self.azylim[1]), xycoords=trans, xytext=(1.03, 0.17), size=10, va='bottom', color=coldel, bbox=dict(boxstyle="round,pad=.2", fc='w', ec=(1,.5,.5)), arrowprops=dict(arrowstyle="->",connectionstyle="angle,angleA=0,angleB=-90,rad=20",color=coldel, lw=2),) def getXLimit(self): """ Get x limit (relative to reference time) """ pps = self.pps b = [ pp.time[0] - pp.sacdh.reftime for pp in pps ] e = [ pp.time[-1] - pp.sacdh.reftime for pp in pps ] npts = [ len(pp.time) for pp in pps ] self.bmin = min(b) self.bmax = max(b) self.emin = min(e) self.emax = max(e) mm = self.bmin, self.emax xxlim = axLimit(mm) self.xzoom = [xxlim,] def getYLimit(self): """ Get y limit """ saclist = self.gsac.saclist delta = saclist[0].delta data = array([ [min(sacdh.data), max(sacdh.data) ] for sacdh in saclist ]) self.dmin = data[:,0].min() self.dmax = data[:,1].max() def prev(self, event): self.replot(self.ipage-1) def next(self, event): self.replot(self.ipage+1) # return to the first page def fron(self, event): self.replot(0) def save(self, event): saveData(self.gsac, self.opts) def quit(self, event): self.finish() self.disconnect() close() def connect(self): self.axfron = self.axs['Fron'] self.axprev = self.axs['Prev'] self.axnext = self.axs['Next'] self.axsave = self.axs['Save'] self.axquit = self.axs['Quit'] self.bnfron = Button(self.axfron, 'Fron') self.bnprev = Button(self.axprev, 'Prev') self.bnnext = Button(self.axnext, 'Next') self.bnsave = Button(self.axsave, 'Save') self.bnquit = Button(self.axquit, 'Quit') # call the function to execute on clicking the button self.cidfron = self.bnfron.on_clicked(self.fron) self.cidprev = self.bnprev.on_clicked(self.prev) self.cidnext = self.bnnext.on_clicked(self.next) self.cidsave = self.bnsave.on_clicked(self.save) self.cidquit = self.bnquit.on_clicked(self.quit) self.cidpress = self.axpp.figure.canvas.mpl_connect('key_press_event', self.on_zoom) def disconnect(self): self.bnfron.disconnect(self.cidfron) self.bnprev.disconnect(self.cidprev) self.bnnext.disconnect(self.cidnext) self.bnsave.disconnect(self.cidsave) self.bnquit.disconnect(self.cidquit) self.axfron.cla() self.axprev.cla() self.axnext.cla() self.axsave.cla() self.axquit.cla() self.axpp.figure.canvas.mpl_disconnect(self.cidpress) self.span.visible = False def finish(self): for pp in self.pps: pp.disconnect() self.axpp.cla()
class PickPhaseMenu(): """ Plot a group of seismogram gathers. Set up axes attributes. Create Button Save to save SAC headers to files. """ def __init__(self, gsac, opts, axs): self.gsac = gsac self.opts = opts self.axs = axs self.axpp = axs['Seis'] self.initIndex() self.plotSeis() self.plotSpan() self.connect() pppara = opts.pppara pickLegend(self.axpp, pppara.npick, pppara.pickcolors, pppara.pickstyles) def plotSeis(self): self.plotWave() self.setLimits() self.setLabels() if self.opts.pick_on: self.plotPicks() self.labelSelection() def initIndex(self): """ Initialize indices for page navigation. """ opts = self.opts axs = self.axs selist = self.gsac.selist delist = self.gsac.delist nsel = len(selist) ndel = len(delist) maxsel, maxdel = opts.maxnum pagesize = maxsel + maxdel aipages, ayindex, aybases, ayticks = indexBaseTick( nsel, ndel, pagesize, maxsel) self.aipages = aipages self.ayindex = ayindex self.aybases = aybases self.ayticks = ayticks self.sedelist = [selist, delist] self.ipage = 0 def plotWave(self): """ Plot waveforms for this page. """ opts = self.opts axpp = self.axpp ipage = self.ipage ayindex, aybases, ayticks = self.ayindex, self.aybases, self.ayticks sedelist = self.sedelist plists = [[sedelist[j][k] for k in ayindex[ipage][j]] for j in range(2)] pbases = [[k for k in aybases[ipage][j]] for j in range(2)] pticks = [[k for k in ayticks[ipage][j]] for j in range(2)] npsel = len(pbases[0]) npdel = len(pbases[1]) nsede = [npsel, npdel] # get colors from sacdh.selected colsel = opts.pppara.colorwave coldel = opts.pppara.colorwavedel colors = [[ None, ] * npsel, [ None, ] * npdel] for j in range(2): for k in range(nsede[j]): if plists[j][k].selected: colors[j][k] = colsel else: colors[j][k] = coldel # plot pps = [] for j in range(2): nsd = nsede[j] for k in range(nsd): linews = ones(nsd) alphas = ones(nsd) pp = PickPhase(plists[j][k], opts, axpp, pbases[j][k], colors[j][k]) pps.append(pp) self.pps = pps self.ybases = pbases[0] + pbases[1] self.yticks = pticks[0] + pticks[1] abases = pbases[1] + pbases[0] self.azylim = abases[-1] - 1, abases[0] + 1 def replot(self, ipage): """ Finish plotting of current page and move to prev/next. """ self.ipage = ipage if not self.ipage in self.aipages: print('End of page.') return self.finish() self.plotSeis() def on_select(self, xmin, xmax): """ Mouse event: select span. """ if self.span.visible: print 'span selected: %6.1f %6.1f ' % (xmin, xmax) xxlim = (xmin, xmax) self.axpp.set_xlim(xxlim) self.xzoom.append(xxlim) if self.opts.upylim_on: print('upylim') for pp in self.pps: pp.updateY(xxlim) self.axpp.figure.canvas.draw() # change window size in seismograms plot here def plotSpan(self): """ Create a SpanSelector for zoom in and zoom out. """ pppara = self.opts.pppara a, col = pppara.alphatwsele, pppara.colortwsele mspan = pppara.minspan * self.opts.delta self.span = TimeSelector(self.axpp, self.on_select, 'horizontal', minspan=mspan, useblit=False, rectprops=dict(alpha=a, facecolor=col)) def on_zoom(self, event): """ Zoom back to previous xlim when event is in event.inaxes. """ evkey = event.key axpp = self.axpp if not axpp.contains(event)[0] or evkey is None: return xzoom = self.xzoom if evkey.lower() == 'z' and len(xzoom) > 1: del xzoom[-1] axpp.set_xlim(xzoom[-1]) print 'Zoom back to: %6.1f %6.1f ' % tuple(xzoom[-1]) if self.opts.upylim_on: for pp in self.pps: del pp.ynorm[-1] setp(pp.lines[0], ydata=pp.ybase + pp.sacdh.data * pp.ynorm[-1]) axpp.figure.canvas.draw() def plotPicks(self): for pp in self.pps: pp.plotPicks() pppara = self.opts.pppara def setLabels(self): """ Set axes labels and page label""" axpp = self.axpp axpp.set_yticks(self.ybases) axpp.set_yticklabels(self.yticks) axpp.set_ylabel('Trace Number') axpp.axhline(y=0, lw=2, color='r') if self.opts.boundlines_on: for yy in range(self.azylim[0], self.azylim[1]): axpp.axhline(y=yy + 0.5, color='black') reltime = self.opts.reltime if reltime >= 0: axpp.set_xlabel('Time - T%d [s]' % reltime) else: axpp.set_xlabel('Time [s]') trans = transforms.blended_transform_factory(axpp.transAxes, axpp.transAxes) page = 'Page {0:d} of [{1:d},{2:d}]'.format(self.ipage, self.aipages[0], self.aipages[-1]) self.pagelabel = axpp.text(1, -0.02, page, transform=trans, va='top', ha='right') def setLimits(self): """ Set axes limits """ axpp = self.axpp self.getXLimit() axpp.set_xlim(self.xzoom[0]) axpp.set_ylim(self.azylim) # plot time zero lines and set axis limit axpp.axvline(x=0, color='k', ls=':') if not self.opts.xlimit is None: axpp.set_xlim(self.opts.xlimit) def labelSelection(self): """ Label selection status with transform (transAxes, transData). """ axpp = self.axpp trans = transforms.blended_transform_factory(axpp.transAxes, axpp.transData) colsel = self.opts.pppara.colorwave coldel = self.opts.pppara.colorwavedel axpp.annotate( 'Selected', xy=(1.015, self.azylim[0]), xycoords=trans, xytext=(1.03, -0.17), size=10, va='top', color=colsel, bbox=dict(boxstyle="round,pad=.2", fc='w', ec=(1, .5, .5)), arrowprops=dict(arrowstyle="->", connectionstyle="angle,angleA=0,angleB=-90,rad=20", color=colsel, lw=2), ) axpp.annotate( 'Deselected', xy=(1.015, self.azylim[1]), xycoords=trans, xytext=(1.03, 0.17), size=10, va='bottom', color=coldel, bbox=dict(boxstyle="round,pad=.2", fc='w', ec=(1, .5, .5)), arrowprops=dict(arrowstyle="->", connectionstyle="angle,angleA=0,angleB=-90,rad=20", color=coldel, lw=2), ) def getXLimit(self): """ Get x limit (relative to reference time) """ pps = self.pps b = [pp.time[0] - pp.sacdh.reftime for pp in pps] e = [pp.time[-1] - pp.sacdh.reftime for pp in pps] npts = [len(pp.time) for pp in pps] self.bmin = min(b) self.bmax = max(b) self.emin = min(e) self.emax = max(e) mm = self.bmin, self.emax xxlim = axLimit(mm) self.xzoom = [ xxlim, ] def getYLimit(self): """ Get y limit """ saclist = self.gsac.saclist delta = saclist[0].delta data = array([[min(sacdh.data), max(sacdh.data)] for sacdh in saclist]) self.dmin = data[:, 0].min() self.dmax = data[:, 1].max() def fron(self, event): self.bnfron.label.set_text('Wait...') self.axpp.get_figure().canvas.draw() self.replot(0) self.bnfron.label.set_text('Front') self.axpp.get_figure().canvas.draw() # zoom back to original screen size def zoba(self, event): self.bnzoba.label.set_text('Wait...') self.axpp.get_figure().canvas.draw() self.replot(self.ipage) self.bnzoba.label.set_text('Zoom\nBack') self.axpp.get_figure().canvas.draw() def prev(self, event): self.bnprev.label.set_text('Wait...') self.axpp.get_figure().canvas.draw() self.replot(self.ipage - 1) self.bnprev.label.set_text('Prev') self.axpp.get_figure().canvas.draw() def next(self, event): self.bnnext.label.set_text('Wait...') self.axpp.get_figure().canvas.draw() self.replot(self.ipage + 1) self.bnnext.label.set_text('Next') self.axpp.get_figure().canvas.draw() # ---------------------------- SAVE HEADERS FILES ------------------------------- # def save(self, event): self.getSaveAxes() self.save_connect() def getSaveAxes(self): saveFigure = figure(figsize=(8, 1)) saveFigure.clf() # size of save buttons rect_saveHeaders = [0.04, 0.2, 0.2, 0.6] rect_saveHeadersFilterParams = [0.28, 0.2, 0.2, 0.6] rect_saveHeadersOverride = [0.52, 0.2, 0.2, 0.6] rect_saveQuit = [0.76, 0.2, 0.2, 0.6] #initalize axes saveAxs = {} saveAxs['saveHeaders'] = saveFigure.add_axes(rect_saveHeaders) saveAxs['saveHeadersFilterParams'] = saveFigure.add_axes( rect_saveHeadersFilterParams) saveAxs['saveHeadersOverride'] = saveFigure.add_axes( rect_saveHeadersOverride) saveAxs['saveQuit'] = saveFigure.add_axes(rect_saveQuit) self.saveAxs = saveAxs self.saveFigure = saveFigure self.save_connect() show() def save_connect(self): #set buttons self.bn_saveHeaders = Button(self.saveAxs['saveHeaders'], 'Save\nHeaders\nOnly') self.bn_saveHeadersFilterParams = Button( self.saveAxs['saveHeadersFilterParams'], 'Save Headers &\n Filter Parameters') self.bn_saveHeadersOverride = Button( self.saveAxs['saveHeadersOverride'], 'Save Headers &\nOverride Data') self.bn_saveQuit = Button(self.saveAxs['saveQuit'], 'Quit') #connect buttons to functions they trigger self.cid_saveHeaders = self.bn_saveHeaders.on_clicked( self.save_headers) self.cid_savedHeadersFilterParams = self.bn_saveHeadersFilterParams.on_clicked( self.save_headers_filterParams) self.cid_saveHeadersOverride = self.bn_saveHeadersOverride.on_clicked( self.save_headers_override) self.cid_saveQuit = self.bn_saveQuit.on_clicked(self.save_quit) def save_quit(self, event): self.save_disconnect() close(self.saveFigure) def save_disconnect(self): self.bn_saveHeaders.disconnect(self.cid_saveHeaders) self.bn_saveHeaders.disconnect(self.cid_savedHeadersFilterParams) self.bn_saveHeadersOverride.disconnect(self.cid_saveHeadersOverride) # self.saveAxs['saveHeaders'].cla() # self.saveAxs['saveHeadersOverride'].cla() # self.saveAxs['saveQuit'].cla() """save headers only""" def save_headers(self, event): saveData(self.gsac, self.opts) """save headers and override data with filtered data @lowFreq -> user0 @highFreq -> user1 @band -> kuser0 @order -> kuser1, need to convert to integer form alphanumeric """ def save_headers_filterParams(self, event): # write params to file for sacdh in self.gsac.saclist: sacdh.user0 = self.opts.filterParameters['lowFreq'] sacdh.user1 = self.opts.filterParameters['highFreq'] sacdh.kuser0 = self.opts.filterParameters['band'] sacdh.kuser1 = self.opts.filterParameters['order'] if 'stkdh' in self.gsac.__dict__: self.gsac.stkdh.user0 = self.opts.filterParameters['lowFreq'] self.gsac.stkdh.user1 = self.opts.filterParameters['highFreq'] self.gsac.stkdh.kuser0 = self.opts.filterParameters['band'] self.gsac.stkdh.kuser1 = self.opts.filterParameters['order'] # save saveData(self.gsac, self.opts) def save_headers_override(self, event): shouldRun = tkMessageBox.askokcancel( "Will Override Files!", "This will override the data in your files with the filtered data. \nAre you sure?" ) if shouldRun: for sacdh in self.gsac.saclist: sacdh.data = ftr.filtering_time_signal( sacdh.data, self.opts.delta, self.opts.filterParameters['lowFreq'], self.opts.filterParameters['highFreq'], self.opts.filterParameters['band'], self.opts.filterParameters['order']) if 'stkdh' in self.gsac.__dict__: self.gsac.stkdh.data = ftr.filtering_time_signal( self.gsac.stkdh.data, self.opts.delta, self.opts.filterParameters['lowFreq'], self.opts.filterParameters['highFreq'], self.opts.filterParameters['band'], self.opts.filterParameters['order']) saveData(self.gsac, self.opts) # ---------------------------- SAVE HEADERS FILES ------------------------------- # def quit(self, event): self.finish() self.disconnect(event.canvas) close('all') def connect(self): self.axfron = self.axs['Fron'] self.axprev = self.axs['Prev'] self.axnext = self.axs['Next'] self.axzoba = self.axs['Zoba'] self.axsave = self.axs['Save'] self.axquit = self.axs['Quit'] self.bnfron = Button(self.axfron, 'Front') self.bnprev = Button(self.axprev, 'Prev') self.bnnext = Button(self.axnext, 'Next') self.bnzoba = Button(self.axzoba, 'Zoom \n Back') self.bnsave = Button(self.axsave, 'Save') self.bnquit = Button(self.axquit, 'Quit') self.cidfron = self.bnfron.on_clicked(self.fron) self.cidprev = self.bnprev.on_clicked(self.prev) self.cidnext = self.bnnext.on_clicked(self.next) self.cidzoba = self.bnzoba.on_clicked(self.zoba) self.cidsave = self.bnsave.on_clicked(self.save) self.cidquit = self.bnquit.on_clicked(self.quit) self.cidpress = self.axpp.figure.canvas.mpl_connect( 'key_press_event', self.on_zoom) def disconnect(self, canvas): # self.bnfron.disconnect(self.cidfron) # self.bnprev.disconnect(self.cidprev) # self.bnnext.disconnect(self.cidnext) # self.bnzoba.disconnect(self.cidzoba) # self.bnsave.disconnect(self.cidsave) self.axfron.cla() self.axprev.cla() self.axnext.cla() self.axzoba.cla() self.axsave.cla() self.axquit.cla() canvas.mpl_disconnect(self.cidpress) self.span.visible = False def finish(self): for pp in self.pps: pp.disconnect() self.axpp.cla()
class PickPhaseMenu(): """ Plot a group of seismogram gathers. Set up axes attributes. Create Button Save to save SAC headers to files. """ def __init__(self, gsac, opts, axs): self.gsac = gsac self.opts = opts self.axs = axs self.axpp = axs['Seis'] self.initIndex() self.plotSeis() self.plotSpan() self.connect() pppara = opts.pppara pickLegend(self.axpp, pppara.npick, pppara.pickcolors, pppara.pickstyles) def plotSeis(self): self.plotWave() self.setLimits() self.setLabels() if self.opts.pick_on: self.plotPicks() self.labelSelection() def initIndex(self): """ Initialize indices for page navigation. """ opts = self.opts #axs = self.axs selist = self.gsac.selist delist = self.gsac.delist nsel = len(selist) ndel = len(delist) maxsel, maxdel = opts.maxnum pagesize = maxsel + maxdel aipages, ayindex, aybases, ayticks = indexBaseTick(nsel, ndel, pagesize, maxsel) self.aipages = aipages self.ayindex = ayindex self.aybases = aybases self.ayticks = ayticks self.sedelist = [selist, delist] self.ipage = 0 def plotWave(self): """ Plot waveforms for this page. """ opts = self.opts axpp = self.axpp ipage = self.ipage ayindex, aybases, ayticks = self.ayindex, self.aybases, self.ayticks sedelist = self.sedelist plists = [ [ sedelist[j][k] for k in ayindex[ipage][j] ] for j in list(range(2)) ] pbases = [ [ k for k in aybases[ipage][j] ] for j in list(range(2)) ] pticks = [ [ k for k in ayticks[ipage][j] ] for j in list(range(2)) ] npsel = len(pbases[0]) npdel = len(pbases[1]) nsede = [npsel, npdel] # get colors from sacdh.selected colsel = opts.pppara.colorwave coldel = opts.pppara.colorwavedel colors = [[None,] * npsel , [None,] * npdel] for j in list(range(2)): for k in list(range(nsede[j])): if plists[j][k].selected: colors[j][k] = colsel else: colors[j][k] = coldel # plot pps = [] for j in list(range(2)): nsd = nsede[j] for k in list(range(nsd)): #linews = np.ones(nsd) #alphas = np.ones(nsd) pp = PickPhase(plists[j][k], opts, axpp, pbases[j][k], colors[j][k]) pps.append(pp) self.pps = pps self.ybases = pbases[0] + pbases[1] self.yticks = pticks[0] + pticks[1] abases = pbases[1]+pbases[0] self.azylim = abases[-1]-1, abases[0]+1 def replot(self, ipage): """ Finish plotting of current page and move to prev/next. """ self.ipage = ipage if not self.ipage in self.aipages: print ('End of page.') return self.finish() self.plotSeis() def on_select(self, xmin, xmax): """ Mouse event: select span. """ if self.span.visible: print('span selected: {:6.1f} {:6.1f} '.format(xmin, xmax)) xxlim = (xmin, xmax) self.axpp.set_xlim(xxlim) self.xzoom.append(xxlim) if self.opts.upylim_on: print ('upylim') for pp in self.pps: pp.updateY(xxlim) self.axpp.figure.canvas.draw() # change window size in seismograms plot here def plotSpan(self): """ Create a SpanSelector for zoom in and zoom out. """ pppara = self.opts.pppara a, col = pppara.alphatwsele, pppara.colortwsele mspan = pppara.minspan * self.opts.delta self.span = TimeSelector(self.axpp, self.on_select, 'horizontal', minspan=mspan, useblit=False, rectprops=dict(alpha=a, facecolor=col)) def on_zoom(self, event): """ Zoom back to previous xlim when event is in event.inaxes. """ evkey = event.key axpp = self.axpp if not axpp.contains(event)[0] or evkey is None: return xzoom = self.xzoom if evkey.lower() == 'z' and len(xzoom) > 1: del xzoom[-1] axpp.set_xlim(xzoom[-1]) print('Zoom back to: {:6.1f} {:6.1f) '.format(tuple(xzoom[-1]))) if self.opts.upylim_on: for pp in self.pps: del pp.ynorm[-1] plt.setp(pp.lines[0], ydata=pp.ybase+pp.sacdh.data*pp.ynorm[-1]) axpp.figure.canvas.draw() def plotPicks(self): for pp in self.pps: pp.plotPicks() #pppara = self.opts.pppara def setLabels(self): """ Set axes labels and page label""" axpp = self.axpp axpp.set_yticks(self.ybases) axpp.set_yticklabels(self.yticks) axpp.set_ylabel('Trace Number') axpp.axhline(y=0, lw=2, color='r') if self.opts.boundlines_on: for yy in list(range(self.azylim[0], self.azylim[1])): axpp.axhline(y=yy+0.5, color='black') reltime = self.opts.reltime if reltime >= 0: axpp.set_xlabel('Time - T%d [s]' % reltime) else: axpp.set_xlabel('Time [s]') trans = transforms.blended_transform_factory(axpp.transAxes, axpp.transAxes) page = 'Page {0:d} of [{1:d},{2:d}]'.format(self.ipage, self.aipages[0], self.aipages[-1]) self.pagelabel = axpp.text(1, -0.02, page, transform=trans, va='top', ha='right') def setLimits(self): """ Set axes limits """ axpp = self.axpp self.getXLimit() axpp.set_xlim(self.xzoom[0]) axpp.set_ylim(self.azylim) # plot time zero lines and set axis limit axpp.axvline(x=0, color='k', ls=':') if not self.opts.xlimit is None: axpp.set_xlim(self.opts.xlimit) def labelSelection(self): """ Label selection status with transform (transAxes, transData). """ axpp = self.axpp trans = transforms.blended_transform_factory(axpp.transAxes, axpp.transData) colsel = self.opts.pppara.colorwave coldel = self.opts.pppara.colorwavedel axpp.annotate('Selected', xy=(1.015, self.azylim[0]), xycoords=trans, xytext=(1.03, -0.17), size=10, va='top', color=colsel, bbox=dict(boxstyle="round,pad=.2", fc='w', ec=(1,.5,.5)), arrowprops=dict(arrowstyle="->",connectionstyle="angle,angleA=0,angleB=-90,rad=20",color=colsel, lw=2),) axpp.annotate('Deselected', xy=(1.015, self.azylim[1]), xycoords=trans, xytext=(1.03, 0.17), size=10, va='bottom', color=coldel, bbox=dict(boxstyle="round,pad=.2", fc='w', ec=(1,.5,.5)), arrowprops=dict(arrowstyle="->",connectionstyle="angle,angleA=0,angleB=-90,rad=20",color=coldel, lw=2),) def getXLimit(self): """ Get x limit (relative to reference time) """ pps = self.pps b = [ pp.time[0] - pp.sacdh.reftime for pp in pps ] e = [ pp.time[-1] - pp.sacdh.reftime for pp in pps ] #npts = [ len(pp.time) for pp in pps ] self.bmin = min(b) self.bmax = max(b) self.emin = min(e) self.emax = max(e) mm = self.bmin, self.emax xxlim = axLimit(mm) self.xzoom = [xxlim,] def getYLimit(self): """ Get y limit """ saclist = self.gsac.saclist #delta = saclist[0].delta data = np.array([ [min(sacdh.data), max(sacdh.data) ] for sacdh in saclist ]) self.dmin = data[:,0].min() self.dmax = data[:,1].max() def fron(self, event): self.bnfron.label.set_text('Wait...') self.axpp.get_figure().canvas.draw() self.replot(0) self.bnfron.label.set_text('Front') self.axpp.get_figure().canvas.draw() # zoom back to original screen size def zoba(self, event): self.bnzoba.label.set_text('Wait...') self.axpp.get_figure().canvas.draw() self.replot(self.ipage) self.bnzoba.label.set_text('Zoom\nBack') self.axpp.get_figure().canvas.draw() def prev(self, event): self.bnprev.label.set_text('Wait...') self.axpp.get_figure().canvas.draw() self.replot(self.ipage-1) self.bnprev.label.set_text('Prev') self.axpp.get_figure().canvas.draw() def next(self, event): self.bnnext.label.set_text('Wait...') self.axpp.get_figure().canvas.draw() self.replot(self.ipage+1) self.bnnext.label.set_text('Next') self.axpp.get_figure().canvas.draw() def last(self, event): self.bnlast.label.set_text('Wait...') self.axpp.get_figure().canvas.draw() self.replot(self.aipages[-1]) self.bnlast.label.set_text('Last') self.axpp.get_figure().canvas.draw() # ---------------------------- SAVE HEADERS FILES ------------------------------- # """save headers only""" def shdo(self, event): saveData(self.gsac, self.opts) """save headers and override data with filtered data @lowFreq -> user0 @highFreq -> user1 @band -> kuser0 @order -> kuser1, need to convert to integer form alphanumeric """ def shfp(self, event): # write params to file for sacdh in self.gsac.saclist: sacdh.user0 = self.opts.filterParameters['lowFreq'] sacdh.user1 = self.opts.filterParameters['highFreq'] sacdh.kuser0 = self.opts.filterParameters['band'] sacdh.kuser1 = self.opts.filterParameters['order'] if 'stkdh' in self.gsac.__dict__: self.gsac.stkdh.user0 = self.opts.filterParameters['lowFreq'] self.gsac.stkdh.user1 = self.opts.filterParameters['highFreq'] self.gsac.stkdh.kuser0 = self.opts.filterParameters['band'] self.gsac.stkdh.kuser1 = self.opts.filterParameters['order'] # save saveData(self.gsac, self.opts) """save headers and override""" def shod(self, event): shouldRun = messagebox.askokcancel("Will Override Files!","This will override the data in your files with the filtered data. \nAre you sure?") if shouldRun: for sacdh in self.gsac.saclist: sacdh.data = ftr.filtering_time_signal(sacdh.data, self.opts.delta, self.opts.filterParameters['lowFreq'], self.opts.filterParameters['highFreq'], self.opts.filterParameters['band'], self.opts.filterParameters['order']) if 'stkdh' in self.gsac.__dict__: self.gsac.stkdh.data = ftr.filtering_time_signal(self.gsac.stkdh.data, self.opts.delta, self.opts.filterParameters['lowFreq'], self.opts.filterParameters['highFreq'], self.opts.filterParameters['band'], self.opts.filterParameters['order']) saveData(self.gsac, self.opts) # ---------------------------- SAVE HEADERS FILES ------------------------------- # def quit(self, event): self.finish() self.disconnect(event.canvas) plt.close('all') def connect(self): self.axfron = self.axs['Fron'] self.axprev = self.axs['Prev'] self.axnext = self.axs['Next'] self.axlast = self.axs['Last'] self.axzoba = self.axs['Zoba'] self.axshdo = self.axs['Shdo'] self.axshfp = self.axs['Shfp'] self.axshod = self.axs['Shod'] self.axquit = self.axs['Quit'] self.bnfron = Button(self.axfron, 'Front') self.bnprev = Button(self.axprev, 'Prev') self.bnnext = Button(self.axnext, 'Next') self.bnlast = Button(self.axlast, 'Last') self.bnzoba = Button(self.axzoba, 'Zoom \n Back') self.bnshdo = Button(self.axshdo, 'Save') self.bnshfp = Button(self.axshfp, 'Save \n Params') self.bnshod = Button(self.axshod, 'Save \n Override') self.bnquit = Button(self.axquit, 'Quit') self.cidfron = self.bnfron.on_clicked(self.fron) self.cidprev = self.bnprev.on_clicked(self.prev) self.cidnext = self.bnnext.on_clicked(self.next) self.cidlast = self.bnlast.on_clicked(self.last) self.cidzoba = self.bnzoba.on_clicked(self.zoba) self.cidshdo = self.bnshdo.on_clicked(self.shdo) self.cidshfp = self.bnshfp.on_clicked(self.shfp) self.cidshod = self.bnshod.on_clicked(self.shod) self.cidquit = self.bnquit.on_clicked(self.quit) self.cidpress = self.axpp.figure.canvas.mpl_connect('key_press_event', self.on_zoom) def disconnect(self, canvas): self.bnfron.disconnect(self.cidfron) self.bnprev.disconnect(self.cidprev) self.bnnext.disconnect(self.cidnext) self.bnlast.disconnect(self.cidlast) self.bnzoba.disconnect(self.cidzoba) self.bnshdo.disconnect(self.cidshdo) self.bnshfp.disconnect(self.cidshfp) self.bnshod.disconnect(self.cidshod) self.axfron.cla() self.axprev.cla() self.axnext.cla() self.axlast.cla() self.axzoba.cla() self.axshdo.cla() self.axshfp.cla() self.axshod.cla() self.axquit.cla() canvas.mpl_disconnect(self.cidpress) self.span.visible = False def finish(self): for pp in self.pps: pp.disconnect() self.axpp.cla()
class PickPhaseMenuMore: """ Pick phase for multiple seismograms and array stack Button: Sync """ def __init__(self, gsac, opts, axs): self.gsac = gsac self.opts = opts self.axs = axs self.axstk = self.axs['Fstk'] if not 'stkdh' in gsac.__dict__: if opts.filemode == 'sac' and os.path.isfile(opts.fstack): gsac.stkdh = SacDataHdrs(opts.fstack, opts.delta) else: hdrini, hdrmed, hdrfin = opts.qcpara.ichdrs self.cchdrs = [hdrini, hdrmed] self.twcorr = opts.ccpara.twcorr # check data coverage opts.ipick = hdrini opts.twcorr = opts.ccpara.twcorr checkCoverage(gsac, opts) gsac.selist = gsac.saclist self.ccStack() self.initPlot() self.plotStack() self.addEarthquakeInfo() self.setLabels() self.connect() def initPlot(self): """ Plot waveforms """ gsac = self.gsac opts = self.opts sortSeis(gsac, opts) self.ppm = PickPhaseMenu(gsac, opts, self.axs) # make the legend box invisible if self.opts.pick_on: self.ppm.axpp.get_legend().set_visible(False) def addEarthquakeInfo(self): """ Set Earthquake Info * Magnitude * Location (Lat and Long) * Depth """ gsac = self.gsac # get required parameters locationLat = round(gsac.event[6],2) locationLon = round(gsac.event[7],2) depth = round(gsac.event[8],2) magnitude = round(gsac.event[9],2) all_gcarc = [] [all_gcarc.append(hdr.gcarc) for hdr in gsac.selist ] avg_gcarc = round(np.mean(all_gcarc),2) infoaxis = self.axs['Info'] # remove axes markings infoaxis.axes.get_xaxis().set_ticks([]) infoaxis.axes.get_yaxis().set_visible(False) # write the info into the axis plot infoaxis.text(0.1,0.85,'Magnitude: '+str(magnitude)) infoaxis.text(0.1,0.65,'Lat: '+str(locationLat)) infoaxis.text(0.1,0.45,'Lon: '+str(locationLon)) infoaxis.text(0.1,0.25,'Depth: '+str(depth)) infoaxis.text(0.1,0.05,'Gcarc: '+str(avg_gcarc)) def setLabels(self): """ Set plot attributes """ self.ppm.axpp.set_title('Seismograms') if self.opts.filemode == 'pkl': axstk = self.axstk trans = transforms.blended_transform_factory(axstk.transAxes, axstk.transAxes) axstk.text(1,1.01,self.opts.pklfile,transform=trans, va='bottom', ha='right',color='k') axpp = self.ppm.axpp trans = transforms.blended_transform_factory(axpp.transAxes, axpp.transData) font = FontProperties() font.set_family('monospace') axpp.text(1.025, 0, ' '*8+'qual= CCC/SNR/COH', transform=trans, va='center', color='k', fontproperties=font) def plotStack(self): """ Plot array stack and span """ colorwave = self.opts.pppara.colorwave stkybase = 0 ppstk = PickPhase(self.gsac.stkdh, self.opts, self.axstk, stkybase, colorwave, 1) ppstk.plotPicks() ppstk.disconnectPick() self.ppstk = ppstk self.axstk.set_title('Array Stack') self.ppstk.stalabel.set_visible(False) if self.opts.ynorm == 1.0: self.axstk.set_ylim(stkybase-0.5, stkybase+0.5) self.axstk.set_yticks([stkybase]) self.axstk.set_yticklabels([]) self.axstk.axvline(x=0, color='k', ls=':') # plot legend pppara = self.opts.pppara pickLegend(self.axstk, pppara.npick, pppara.pickcolors, pppara.pickstyles, False) self.plotSpan() def plotSpan(self): """ Span for array stack """ axstk = self.axstk self.xzoom = [axstk.get_xlim(),] def on_select(xmin, xmax): """ Mouse event: select span. """ if self.span.visible: print 'span selected: %6.1f %6.1f ' % (xmin, xmax) xxlim = (xmin, xmax) axstk.set_xlim(xxlim) self.xzoom.append(xxlim) if self.opts.upylim_on: print ('upylim') ppstk.updateY(xxlim) axstk.figure.canvas.draw() pppara = self.opts.pppara a, col = pppara.alphatwsele, pppara.colortwsele mspan = pppara.minspan * self.opts.delta self.span = TimeSelector(axstk, on_select, 'horizontal', minspan=mspan, useblit=False, rectprops=dict(alpha=a, facecolor=col)) #self.replot() #self.ppm.axpp.figure.canvas.draw() # -------------------------------- SORTING ---------------------------------- # # Sort seismograms by # -------------- # * | file indices | # -------------- # ----- ----- ----- ----- # * quality factor | all | ccc | snr | coh | # ----- ----- ----- ----- # ---- ----- ------ # * given header | az | baz | dist | ... # ---- ----- ------ def sorting(self, event): """ Sort the seismograms in particular order """ self.getSortAxes() self.summarize_sort() self.sort_connect() show() def getSortAxes(self): figsort = figure('SortSeismograms',figsize=(15, 12)) x0 = 0.05 xx = 0.10 yy = 0.04 xm = 0.02 dy = 0.15 dx = 0.12 y0 = 0.90 """Allocating size of buttons""" # file indices (filenames) rectfile = [x0, y0-dy*1, xx, yy] # quality rectqall = [x0+dx*0, y0-2*dy, xx, yy] rectqccc = [x0+dx*1, y0-2*dy, xx, yy] rectqsnr = [x0+dx*2, y0-2*dy, xx, yy] rectqcoh = [x0+dx*3, y0-2*dy, xx, yy] # headers recthnpts = [x0+dx*0, y0-3*dy, xx, yy] recthb = [x0+dx*1, y0-3*dy, xx, yy] recthe = [x0+dx*2, y0-3*dy, xx, yy] recthdelta = [x0+dx*3, y0-3*dy, xx, yy] recthstla = [x0+dx*0, y0-3.5*dy, xx, yy] recthstlo = [x0+dx*1, y0-3.5*dy, xx, yy] recthdist = [x0+dx*2, y0-3.5*dy, xx, yy] recthaz = [x0+dx*3, y0-3.5*dy, xx, yy] recthbaz = [x0+dx*0, y0-4*dy, xx, yy] recthgcarc = [x0+dx*1, y0-4*dy, xx, yy] # quit rectquit = [0.2, y0-5*dy, 0.2, yy] """writing buttons to axis""" sortAxs = {} figsort.text(0.1,y0-dy*0.5,'Sort by file Index Name: ') sortAxs['file'] = figsort.add_axes(rectfile) figsort.text(0.1,y0-dy*1.5,'Sort by Quality: ') sortAxs['qall'] = figsort.add_axes(rectqall) sortAxs['qccc'] = figsort.add_axes(rectqccc) sortAxs['qsnr'] = figsort.add_axes(rectqsnr) sortAxs['qcoh'] = figsort.add_axes(rectqcoh) figsort.text(0.1,y0-dy*2.5,'Sort by Header: ') sortAxs['hnpts'] = figsort.add_axes(recthnpts) sortAxs['hb'] = figsort.add_axes(recthb) sortAxs['he'] = figsort.add_axes(recthe) sortAxs['hdelta'] = figsort.add_axes(recthdelta) sortAxs['hstla'] = figsort.add_axes(recthstla) sortAxs['hstlo'] = figsort.add_axes(recthstlo) sortAxs['hdist'] = figsort.add_axes(recthdist) sortAxs['haz'] = figsort.add_axes(recthaz) sortAxs['hbaz'] = figsort.add_axes(recthbaz) sortAxs['hgcarc'] = figsort.add_axes(recthgcarc) sortAxs['quit'] = figsort.add_axes(rectquit) """ size of text summary box """ rectsumm = [0.55, 0.05, 0.40, 0.90] sortAxs['summary'] = figsort.add_axes(rectsumm) # remove axes markings on summary field sortAxs['summary'].get_xaxis().set_ticks([]) sortAxs['summary'].get_yaxis().set_visible([]) self.sortAxs = sortAxs self.figsort = figsort def summarize_sort(self): sortAxs = self.sortAxs # define constants x0 = 0.03 x1 = 0.20 y0 = 0.95 dy = 0.03 # explain what the summaries are sortAxs['summary'].text(x0,y0-dy*0,'FILENAMES') sortAxs['summary'].text(x0,y0-dy*1,'File: ') sortAxs['summary'].text(x1,y0-dy*1,'Sort in alphabetical order by filename') sortAxs['summary'].text(x0,y0-dy*3,'QUALITY:') sortAxs['summary'].text(x0,y0-dy*4,'All: ') sortAxs['summary'].text(x1,y0-dy*4,'Weighted Ratio of all quality measures') sortAxs['summary'].text(x0,y0-dy*5,'CCC: ') sortAxs['summary'].text(x1,y0-dy*5,'Cross-coefficient Coefficient') sortAxs['summary'].text(x0,y0-dy*6,'SNR: ') sortAxs['summary'].text(x1,y0-dy*6,'Signal-to-noise Ratio') sortAxs['summary'].text(x0,y0-dy*7,'COH: ') sortAxs['summary'].text(x1,y0-dy*7,'time domain coherence') sortAxs['summary'].text(x0,y0-dy*9,'OTHER HEADERS:') sortAxs['summary'].text(x0,y0-dy*10,'NPTS: ') sortAxs['summary'].text(x1,y0-dy*10,'Number of points per data component') sortAxs['summary'].text(x0,y0-dy*11,'B: ') sortAxs['summary'].text(x1,y0-dy*11,'Beginning value of the independent variable') sortAxs['summary'].text(x0,y0-dy*12,'E: ') sortAxs['summary'].text(x1,y0-dy*12,'Ending value of the independent variable') sortAxs['summary'].text(x0,y0-dy*13,'Delta: ') sortAxs['summary'].text(x1,y0-dy*13,'Increment between evenly spaced samples') sortAxs['summary'].text(x0,y0-dy*14,'STLA: ') sortAxs['summary'].text(x1,y0-dy*14,'Station latitude (deg, north positive)') sortAxs['summary'].text(x0,y0-dy*15,'STLO: ') sortAxs['summary'].text(x1,y0-dy*15,'Station longitude (deg, east positive)') sortAxs['summary'].text(x0,y0-dy*16,'DIST: ') sortAxs['summary'].text(x1,y0-dy*16,'Station to event distance (km)') sortAxs['summary'].text(x0,y0-dy*17,'AZ: ') sortAxs['summary'].text(x1,y0-dy*17,'Event to station azimuth (deg)') sortAxs['summary'].text(x0,y0-dy*18,'BAZ: ') sortAxs['summary'].text(x1,y0-dy*18,'Station to event azimuth (deg)') sortAxs['summary'].text(x0,y0-dy*19,'GCARC: ') sortAxs['summary'].text(x1,y0-dy*19,'Station to event great circle arc length (deg)') """ Connect button events. """ def sort_connect(self): """write the position for the buttons into self""" self.axfile = self.sortAxs['file'] self.axqall = self.sortAxs['qall'] self.axqccc = self.sortAxs['qccc'] self.axqsnr = self.sortAxs['qsnr'] self.axqcoh = self.sortAxs['qcoh'] self.axqcoh = self.sortAxs['qcoh'] self.axhnpts = self.sortAxs['hnpts'] self.axhb = self.sortAxs['hb'] self.axhe = self.sortAxs['he'] self.axhdelta = self.sortAxs['hdelta'] self.axhstla = self.sortAxs['hstla'] self.axhstlo = self.sortAxs['hstlo'] self.axhdist = self.sortAxs['hdist'] self.axhaz = self.sortAxs['haz'] self.axhbaz = self.sortAxs['hbaz'] self.axhgcarc = self.sortAxs['hgcarc'] self.axquit = self.sortAxs['quit'] """add a button to the correct place as defined by the axes Also label the buttons here, as seen in the GUI """ self.bnfile = Button(self.axfile, 'File') self.bnqall = Button(self.axqall, 'All') self.bnqccc = Button(self.axqccc, 'CCC') self.bnqsnr = Button(self.axqsnr, 'SNR') self.bnqcoh = Button(self.axqcoh, 'COH') self.bnhnpts = Button(self.axhnpts, 'NPTS') self.bnhb = Button(self.axhb, 'B') self.bnhe = Button(self.axhe, 'E') self.bnhdelta = Button(self.axhdelta, 'Delta') self.bnhstla = Button(self.axhstla, 'STLA') self.bnhstlo = Button(self.axhstlo, 'STLO') self.bnhdist = Button(self.axhdist, 'Dist') self.bnhaz = Button(self.axhaz, 'AZ') self.bnhbaz = Button(self.axhbaz, 'BAZ') self.bnhgcarc = Button(self.axhgcarc, 'GCARC') self.bnquit = Button(self.axquit, 'Waiting for User input') """ each button changes the way the seismograms are sorted """ self.cidfile = self.bnfile.on_clicked(self.sort_file) self.cidqall = self.bnqall.on_clicked(self.sort_qall) self.cidqccc = self.bnqccc.on_clicked(self.sort_qccc) self.cidqsnr = self.bnqsnr.on_clicked(self.sort_qsnr) self.cidqcoh = self.bnqcoh.on_clicked(self.sort_qcoh) self.cidhnpts = self.bnhnpts.on_clicked(self.sort_hnpts) self.cidhb = self.bnhb.on_clicked(self.sort_hb) self.cidhe = self.bnhe.on_clicked(self.sort_he) self.cidhdelta = self.bnhdelta.on_clicked(self.sort_hdelta) self.cidhstla = self.bnhstla.on_clicked(self.sort_hstla) self.cidhstlo = self.bnhstlo.on_clicked(self.sort_hstlo) self.cidhdist = self.bnhdist.on_clicked(self.sort_hdist) self.cidhaz = self.bnhaz.on_clicked(self.sort_haz) self.cidhbaz = self.bnhbaz.on_clicked(self.sort_hbaz) self.cidhgcarc = self.bnhgcarc.on_clicked(self.sort_hgcarc) # dismiss window when done self.bnquit.on_clicked(self.dismiss_sort) def sort_disconnect(self): self.bnfile.disconnect(self.cidfile) self.bnqall.disconnect(self.cidqall) self.bnqccc.disconnect(self.cidqccc) self.bnqsnr.disconnect(self.cidqsnr) self.bnqcoh.disconnect(self.cidqcoh) self.bnhnpts.disconnect(self.cidhnpts) self.bnhb.disconnect(self.cidhb) self.bnhe.disconnect(self.cidhe) self.bnhdelta.disconnect(self.cidhdelta) self.bnhstla.disconnect(self.cidhstla) self.bnhstlo.disconnect(self.cidhstlo) self.bnhdist.disconnect(self.cidhdist) self.bnhaz.disconnect(self.cidhaz) self.bnhbaz.disconnect(self.cidhbaz) self.bnhgcarc.disconnect(self.cidhgcarc) def sort_file(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'i'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_qall(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'all'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_qccc(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = '1'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_qsnr(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = '2'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_qcoh(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = '3'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hnpts(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'npts'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hb(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'b'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_he(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'e'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hdelta(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'delta'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hkstnm(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'kstnm'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hstla(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'stla'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hstlo(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'stlo'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hdist(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'dist'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_haz(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'az'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hbaz(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'baz'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hgcarc(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'gcarc'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def dismiss_sort(self, event): """Dismiss the sorting selection popup Window""" self.sort_disconnect() close() # -------------------------------- SORTING ---------------------------------- # # --------------------------------- Filtering ------------------------------- # # Implement Butterworth filter # def filtering(self,event): filterAxes = self.getFilterAxes() self.spreadButter() self.filter_connect() show() def filter_connect(self): # user to change default parameters self.cidSelectFreq = self.filterAxs['amVfreq'].get_figure().canvas.mpl_connect('button_press_event', self.getBandpassFreq) # get order self.bnorder = RadioButtons(self.filterAxs['ordr'], (1,2,3,4), active=1) self.cidorder = self.bnorder.on_clicked(self.getButterOrder) # get type of filter to use self.bnband = RadioButtons(self.filterAxs['band'], ('bandpass','lowpass','highpass')) self.cidband = self.bnband.on_clicked(self.getBandtype) # get reverse pass option self.bnreversepass = RadioButtons(self.filterAxs['reversepass'], ('yes', 'no'), active=1) self.cidreversepass = self.bnreversepass.on_clicked(self.getReversePassOption) #add apply button. causes the filtered data to be applied self.bnapply = Button(self.filterAxs['apply'], 'Apply') self.cidapply = self.bnapply.on_clicked(self.applyFilter) #add unapply button. causes the filtered data to be applied self.bnunapply = Button(self.filterAxs['unapply'], 'Unapply') self.cidunapply = self.bnunapply.on_clicked(self.unapplyFilter) def getReversePassOption(self, event): if event == 'yes': self.opts.filterParameters['reversepass'] = True else: self.opts.filterParameters['reversepass'] = False self.spreadButter() def getBandtype(self, event): self.opts.filterParameters['band'] = event if event=='bandpass': self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) # set defaults self.opts.filterParameters['lowFreq'] = 0.05 self.opts.filterParameters['highFreq'] = 0.25 self.opts.filterParameters['advance'] = False self.spreadButter() #execute self.cidSelectFreq = self.filterAxs['amVfreq'].get_figure().canvas.mpl_connect('button_press_event', self.getBandpassFreq) elif event=='lowpass': self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) # set defaults self.opts.filterParameters['lowFreq'] = 0.05 self.opts.filterParameters['highFreq'] = nan self.opts.filterParameters['advance'] = False self.spreadButter() #execute self.cidSelectFreq = self.filterAxs['amVfreq'].get_figure().canvas.mpl_connect('button_press_event', self.getLowFreq) elif event=='highpass': self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) # set defaults self.opts.filterParameters['lowFreq'] = nan self.opts.filterParameters['highFreq'] = 0.25 self.opts.filterParameters['advance'] = False self.spreadButter() #execute self.cidSelectFreq = self.filterAxs['amVfreq'].get_figure().canvas.mpl_connect('button_press_event', self.getHighFreq) def getLowFreq(self, event): if event.inaxes == self.filterAxs['amVfreq']: self.opts.filterParameters['lowFreq'] = event.xdata self.spreadButter() def getHighFreq(self, event): if event.inaxes == self.filterAxs['amVfreq']: self.opts.filterParameters['highFreq'] = event.xdata self.spreadButter() def getButterOrder(self, event): self.opts.filterParameters['order'] = int(event) self.spreadButter() def getBandpassFreq(self,event): if event.inaxes == self.filterAxs['amVfreq']: if self.opts.filterParameters['advance']: # low and high frequencies recorded self.opts.filterParameters['highFreq'] = event.xdata if self.opts.filterParameters['lowFreq']<self.opts.filterParameters['highFreq']: self.opts.filterParameters['advance'] = False self.spreadButter() else: print 'Value chose must be higher than lower frequency of %f' % self.opts.filterParameters['lowFreq'] else: self.opts.filterParameters['lowFreq'] = event.xdata self.opts.filterParameters['advance'] = True def modifyFilterTextLabels(self): self.filterAxs['Info'].clear() self.filterAxs['Info'].text(0.1,0.7,'Low Freq: '+str(self.opts.filterParameters['lowFreq'])) self.filterAxs['Info'].text(0.1,0.4,'High Freq: '+str(self.opts.filterParameters['highFreq'])) self.filterAxs['Info'].text(0.1,0.1,'Order: '+str(self.opts.filterParameters['order'])) """Apply the butterworth filter to the data """ def spreadButter(self): # clear axes self.filterAxs['amVtime'].clear() self.filterAxs['amVfreq'].clear() #set axes limit self.filterAxs['amVtime'].set_xlim(-30,30) self.filterAxs['amVfreq'].set_xlim(0,1.50) self.modifyFilterTextLabels() originalTime = self.ppstk.time - self.ppstk.sacdh.reftime originalSignalTime = self.ppstk.sacdh.data originalFreq, originalSignalFreq = ftr.time_to_freq(originalTime, originalSignalTime, self.opts.delta) filteredSignalTime, filteredSignalFreq, adjusted_w, adjusted_h = ftr.filtering_time_freq(originalTime, originalSignalTime, self.opts.delta, self.opts.filterParameters['band'], self.opts.filterParameters['highFreq'], self.opts.filterParameters['lowFreq'], self.opts.filterParameters['order'], self.opts.filterParameters['reversepass']) # PLOT TIME self.filterAxs['amVtime'].plot(originalTime, originalSignalTime, label='Original') self.filterAxs['amVtime'].plot(originalTime, filteredSignalTime, label='Filtered') self.filterAxs['amVtime'].legend(loc="upper right") self.filterAxs['amVtime'].set_title('Signal vs Time') self.filterAxs['amVtime'].set_xlabel('Time (s)', fontsize = 12) self.filterAxs['amVtime'].set_ylabel('Signal', fontsize = 12) # PLOT FREQUENCY self.filterAxs['amVfreq'].plot(originalFreq, np.abs(originalSignalFreq), label='Original') self.filterAxs['amVfreq'].plot(originalFreq, np.abs(filteredSignalFreq), label='Filtered') self.filterAxs['amVfreq'].plot(adjusted_w, adjusted_h, label='Butterworth Filter') self.filterAxs['amVfreq'].legend(loc="upper right") self.filterAxs['amVfreq'].set_title('Amplitude vs frequency') self.filterAxs['amVfreq'].set_xlabel('Frequency (Hz)', fontsize = 12) self.filterAxs['amVfreq'].set_ylabel('Amplitude Signal', fontsize = 12) # redraw the plots on the popup window self.figfilter.canvas.draw() def applyFilter(self, event): #should we write filtered data for individual seismograms self.opts.filterParameters['apply'] = True # replot filtered stuff self.axstk.clear() self.ppm.axpp.clear() self.axs['Fron'].clear() self.axs['Prev'].clear() self.axs['Next'].clear() self.axs['Last'].clear() self.axs['Zoba'].clear() self.axs['Shdo'].clear() self.axs['Shfp'].clear() self.axs['Shod'].clear() self.axs['Quit'].clear() self.ppm = PickPhaseMenu(self.gsac, self.opts, self.axs) # make the legend box invisible if self.opts.pick_on: self.ppm.axpp.get_legend().set_visible(False) self.plotStack() # redraw figures self.ppm.axpp.figure.canvas.draw() self.axstk.figure.canvas.draw() # disconnect self.bnorder.disconnect(self.cidorder) self.bnunapply.disconnect(self.cidunapply) self.bnband.disconnect(self.cidband) self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) close() def unapplyFilter(self, event): # do not write filtered data for individual seismograms self.opts.filterParameters['apply'] = False #reset back to original defaults self.opts.filterParameters['band'] = 'bandpass' self.opts.filterParameters['lowFreq'] = 0.05 self.opts.filterParameters['highFreq'] = 0.25 self.opts.filterParameters['order'] = 2 # replot filtered stuff self.axstk.clear() self.ppm.axpp.clear() self.axs['Fron'].clear() self.axs['Prev'].clear() self.axs['Next'].clear() self.axs['Last'].clear() self.axs['Zoba'].clear() self.axs['Shdo'].clear() self.axs['Shfp'].clear() self.axs['Shod'].clear() self.axs['Quit'].clear() self.initPlot() self.plotStack() # redraw figures self.ppm.axpp.figure.canvas.draw() self.axstk.figure.canvas.draw() # disconnect self.bnorder.disconnect(self.cidorder) self.bnapply.disconnect(self.cidapply) self.bnband.disconnect(self.cidband) self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) close() def getFilterAxes(self): figfilter = figure(figsize=(15, 12)) self.figfilter = figfilter rect_amVtime = [0.10, 0.50, 0.80, 0.35] rect_amVfreq = [0.10, 0.07, 0.80, 0.35] rectinfo = [0.8, 0.86, 0.15, 0.10] rectordr = [0.3, 0.86, 0.10, 0.10] rectunapply = [0.42, 0.90, 0.07, 0.04] rectapply = [0.5, 0.90, 0.05, 0.04] rectband = [0.6, 0.86, 0.10, 0.10] rectreversepass = [0.72, 0.86, 0.07, 0.10] filterAxs = {} self.figfilter.text(0.03,0.95,'Butterworth Filter', {'weight':'bold', 'size':21}) filterAxs['amVtime'] = figfilter.add_axes(rect_amVtime) filterAxs['amVfreq'] = figfilter.add_axes(rect_amVfreq) filterAxs['ordr'] = figfilter.add_axes(rectordr) filterAxs['unapply'] = figfilter.add_axes(rectunapply) filterAxs['apply'] = figfilter.add_axes(rectapply) filterAxs['band'] = figfilter.add_axes(rectband) filterAxs['reversepass'] = figfilter.add_axes(rectreversepass) self.figfilter.text(0.3, 0.97, 'Order:') self.figfilter.text(0.6, 0.97, 'Filter Type:') self.figfilter.text(0.72, 0.97, 'Run Reverse:') # frequencies used to compute butterworth filter displayed here filterAxs['Info'] = figfilter.add_axes(rectinfo) filterAxs['Info'].axes.get_xaxis().set_visible(False) filterAxs['Info'].axes.get_yaxis().set_visible(False) self.filterAxs = filterAxs # --------------------------------- Filtering ------------------------------- # def plot_stations(self, event): event_name = 'event' if hasattr(self.opts, 'pklfile'): event_name = self.opts.pklfile PlotStations(event_name, self.gsac) def on_zoom(self, event): """ Zoom back to previous xlim when event is in event.inaxes. """ evkey = event.key axstk = self.axstk if not axstk.contains(event)[0] or evkey is None: return xzoom = self.xzoom if evkey.lower() == 'z' and len(xzoom) > 1: del xzoom[-1] axstk.set_xlim(xzoom[-1]) print 'Zoom back to: %6.1f %6.1f ' % tuple(xzoom[-1]) if self.opts.upylim_on: for pp in self.pps: del pp.ynorm[-1] setp(pp.lines[0], ydata=pp.ybase+pp.sacdh.data*pp.ynorm[-1]) axstk.figure.canvas.draw() def replot_seismograms(self): """ Replot seismograms and array stack after running iccs. """ sortSeis(self.gsac, self.opts) self.ppm.initIndex() self.ppm.replot(0) self.setLabels() def replot(self): """ Replot seismograms and array stack after running iccs. """ self.ppstk.disconnect() self.ppstk.axpp.cla() self.plotStack() sortSeis(self.gsac, self.opts) self.ppm.initIndex() self.ppm.replot(0) self.setLabels() def connect(self): """ Connect button events. """ # write the position for the buttons into self self.axccim = self.axs['CCIM'] self.axccff = self.axs['CCFF'] self.axsync = self.axs['Sync'] self.axmccc = self.axs['MCCC'] self.axsac2 = self.axs['SAC2'] self.axsort = self.axs['Sort'] self.axfilter = self.axs['Filter'] self.axplotsta = self.axs['plotsta'] # name the buttons self.bnccim = Button(self.axccim, 'Align') self.bnccff = Button(self.axccff, 'Refine') self.bnsync = Button(self.axsync, 'Sync') self.bnmccc = Button(self.axmccc, 'Finalize') self.bnsac2 = Button(self.axsac2, 'SAC P2') self.bnsort = Button(self.axsort, 'Sort') self.bnfilter = Button(self.axfilter, 'Filter') self.bnplotsta = Button(self.axplotsta, 'Map of\n stations') self.cidccim = self.bnccim.on_clicked(self.ccim) self.cidccff = self.bnccff.on_clicked(self.ccff) self.cidsync = self.bnsync.on_clicked(self.sync) self.cidmccc = self.bnmccc.on_clicked(self.mccc) self.cidsac2 = self.bnsac2.on_clicked(self.plot2) self.cidsort = self.bnsort.on_clicked(self.sorting) self.cidfilter = self.bnfilter.on_clicked(self.filtering) self.cidplotsta = self.bnplotsta.on_clicked(self.plot_stations) self.cidpress = self.axstk.figure.canvas.mpl_connect('key_press_event', self.on_zoom) def disconnect(self): """ Disconnect button events. """ self.bnccim.disconnect(self.cidccim) self.bnccff.disconnect(self.cidccff) self.bnsync.disconnect(self.cidsync) self.bnmccc.disconnect(self.cidmccc) self.bnsac2.disconnect(self.cidsac2) self.bnsort.disconnect(self.cidsort) self.bnfilter.disconnect(self.cidfilter) self.axccim.cla() self.axccff.cla() self.axsync.cla() self.axmccc.cla() self.axsac2.cla() self.axsort.cla() self.axfilter.cla() def syncPick(self): """ Sync final time pick hdrfin from array stack to all traces. """ self.getPicks() tshift = self.tfin - self.tmed hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs for sacdh in self.gsac.saclist: tfin = sacdh.gethdr(hdrmed) + tshift sacdh.sethdr(hdrfin, tfin) def syncWind(self): """ Sync time window relative to hdrfin from array stack to all traces. Times saved to twhdrs are alway absolute. """ wh0, wh1 = self.opts.qcpara.twhdrs hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs self.getWindow(hdrfin) twfin = self.twcorr for sacdh in self.gsac.saclist: tfin = sacdh.gethdr(hdrfin) th0 = tfin + twfin[0] th1 = tfin + twfin[1] sacdh.sethdr(wh0, th0) sacdh.sethdr(wh1, th1) def sync(self, event): """ Sync final time pick and time window from array stack to each trace and update current page. """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs wh0, wh1 = self.opts.qcpara.twhdrs if self.ppstk.sacdh.gethdr(hdrfin) == -12345.: print '*** hfinal %s is not defined. Pick at array stack first! ***' % hdrfin return self.syncPick() self.syncWind() twfin = self.twcorr for pp in self.ppm.pps: sacdh = pp.sacdh tfin = sacdh.gethdr(hdrfin) ipk = int(hdrfin[1]) tpk = tfin - sacdh.reftime pp.timepicks[ipk].set_xdata(tpk) th0 = tfin + twfin[0] th1 = tfin + twfin[1] pp.twindow = [th0, th1] pp.resetWindow() print '--> Sync final time picks and time window... You can now run CCFF to refine final picks.' def getWindow(self, hdr): """ Get time window twcorr (relative to hdr) from array stack, which is from last run. """ ppstk = self.ppstk tw0, tw1 = ppstk.twindow t0 = ppstk.sacdh.gethdr(hdr) if t0 == -12345.: print ('Header {0:s} not defined'.format(hdr)) return twcorr = [tw0-t0, tw1-t0] self.twcorr = twcorr def getPicks(self): """ Get time picks of stack """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs self.tini = self.gsac.stkdh.gethdr(hdrini) self.tmed = self.gsac.stkdh.gethdr(hdrmed) self.tfin = self.gsac.stkdh.gethdr(hdrfin) def ccim(self, event): # running ICCS-A will erase everything you did. Make sure the user did not hit it by mistake shouldRun = tkMessageBox.askokcancel("Will Erase Work!","This will erase any picks past t1. \nAre you sure?") if shouldRun: """ Run iccs with time window from final stack. Time picks: hdrini, hdrmed. """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs self.cchdrs = hdrini, hdrmed self.getWindow(self.cchdrs[0]) self.ccStack() self.getPicks() self.replot() def ccff(self, event): """ Run iccs with time window from final stack. Time picks: hdrfin, hdrfin. """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs if self.gsac.stkdh.gethdr(hdrfin) == -12345.: print '*** hfinal %s is not defined. Sync first! ***' % hdrfin return """running ICCS-B will erase everything you did. Make sure the user did not hit it by mistake""" shouldRun = tkMessageBox.askokcancel("Will Erase Work!","This will erase any picks past t2 and will recalculate all t2 values. \nAre you sure?") if shouldRun: self.cchdrs = hdrfin, hdrfin self.getWindow(self.cchdrs[0]) self.getPicks() self.ccStack() stkdh = self.gsac.stkdh stkdh.sethdr(hdrini, self.tini) stkdh.sethdr(hdrmed, self.tmed) self.replot() def ccStack(self): """ Call iccs.ccWeightStack. Change reference time pick to the input pick before ICCS and to the output pick afterwards. """ opts = self.opts ccpara = opts.ccpara opts.ccpara.twcorr = self.twcorr ccpara.cchdrs = self.cchdrs hdr0, hdr1 = int(ccpara.cchdrs[0][1]), int(ccpara.cchdrs[1][1]) stkdh, stkdata, quas = ccWeightStack(self.gsac.selist, self.opts) stkdh.selected = True stkdh.sethdr(opts.qcpara.hdrsel, 'True ') self.gsac.stkdh = stkdh if opts.reltime != hdr1: out = '\n--> change opts.reltime from %i to %i' print out % (opts.reltime, hdr1) opts.reltime = hdr1 def mccc(self, event): """ Run mccc.py """ gsac = self.gsac mcpara = self.opts.mcpara rcfile = mcpara.rcfile ipick = mcpara.ipick wpick = mcpara.wpick self.getWindow(ipick) timewindow = self.twcorr tw = timewindow[1]-timewindow[0] taperwindow = taperWindow(timewindow, mcpara.taperwidth) mcpara.timewindow = timewindow mcpara.taperwindow = taperwindow evline, mcname = eventListName(gsac.event, mcpara.phase) mcpara.evline = evline mcpara.mcname = mcname mcpara.kevnm = gsac.kevnm solution, solist_LonLat, delay_times = mccc(gsac, mcpara) self.gsac.solist_LonLat = solist_LonLat self.gsac.delay_times = delay_times wpk = int(wpick[1]) if self.opts.reltime != wpk: out = '\n--> change opts.reltime from %i to %i' print out % (self.opts.reltime, wpk) self.opts.reltime = wpk self.replot() def plot2(self, event): """ Plot P2 stack of seismograms for defined time picks (ichdrs + wpick). """ opts = copy.copy(self.opts) twin_on = opts.twin_on pick_on = opts.pick_on reltime = opts.reltime ynorm = opts.ynorm fill = opts.fill selist = self.gsac.selist tpicks = opts.qcpara.ichdrs + [opts.mcpara.wpick,] npick = len(tpicks) tlabs = 'ABCDE' fig2 = figure(figsize=(9,12)) fig2.clf() subplots_adjust(bottom=.05, top=0.96, left=.1, right=.97, wspace=.5, hspace=.24) opts.twin_on = False opts.pick_on = False ax0 = fig2.add_subplot(npick,1,1) axsacs = [ ax0 ] + [ fig2.add_subplot(npick,1,i+1, sharex=ax0) for i in range(1, npick) ] for i in range(npick): opts.reltime = int(tpicks[i][1]) ax = axsacs[i] sacp2(selist, opts, ax) tt = '(' + tlabs[i] + ')' trans = transforms.blended_transform_factory(ax.transAxes, ax.transAxes) ax.text(-.05, 1, tt, transform=trans, va='center', ha='right', size=16) opts.ynorm = ynorm opts.twin_on = twin_on opts.pick_on = pick_on opts.reltime = reltime opts.fill = fill opts.zero_on = False show()
class PickPhaseMenuMore: """ Pick phase for multiple seismograms and array stack Button: Sync """ def __init__(self, gsac, opts, axs): self.gsac = gsac self.opts = opts self.axs = axs self.axstk = self.axs['Fstk'] if not 'stkdh' in gsac.__dict__: if opts.filemode == 'sac' and os.path.isfile(opts.fstack): gsac.stkdh = SacDataHdrs(opts.fstack, opts.delta) else: hdrini, hdrmed, hdrfin = opts.qcpara.ichdrs self.cchdrs = [hdrini, hdrmed] self.twcorr = opts.ccpara.twcorr # check data coverage opts.ipick = hdrini opts.twcorr = opts.ccpara.twcorr checkCoverage(gsac, opts) gsac.selist = gsac.saclist self.ccStack() self.initPlot() self.plotStack() self.setLabels() self.connect() def initPlot(self): """ Plot waveforms """ gsac = self.gsac opts = self.opts sortSeis(gsac, opts) self.ppm = PickPhaseMenu(gsac, opts, self.axs) # make the legend box invisible if self.opts.pick_on: self.ppm.axpp.get_legend().set_visible(False) def setLabels(self): """ Set plot attributes """ self.ppm.axpp.set_title('Seismograms') if self.opts.filemode == 'pkl': axstk = self.axstk trans = transforms.blended_transform_factory(axstk.transAxes, axstk.transAxes) axstk.text(1,1.01,self.opts.pklfile,transform=trans, va='bottom', ha='right',color='k') axpp = self.ppm.axpp trans = transforms.blended_transform_factory(axpp.transAxes, axpp.transData) font = FontProperties() font.set_family('monospace') axpp.text(1.025, 0, ' '*8+'qual= CCC/SNR/COH', transform=trans, va='center', color='k', fontproperties=font) def plotStack(self): """ Plot array stack and span """ colorwave = self.opts.pppara.colorwave stkybase = 0 ppstk = PickPhase(self.gsac.stkdh, self.opts,self.axstk, stkybase, colorwave, 1) ppstk.plotPicks() ppstk.disconnectPick() self.ppstk = ppstk self.axstk.set_title('Array Stack') self.ppstk.stalabel.set_visible(False) if self.opts.ynorm == 1.0: self.axstk.set_ylim(stkybase-0.5, stkybase+0.5) self.axstk.set_yticks([stkybase]) self.axstk.set_yticklabels([]) self.axstk.axvline(x=0, color='k', ls=':') # plot legend pppara = self.opts.pppara pickLegend(self.axstk, pppara.npick, pppara.pickcolors, pppara.pickstyles, False) self.plotSpan() def plotSpan(self): """ Span for array stack """ axstk = self.axstk self.xzoom = [axstk.get_xlim(),] def on_select(xmin, xmax): """ Mouse event: select span. """ if self.span.visible: print 'span selected: %6.1f %6.1f ' % (xmin, xmax) xxlim = (xmin, xmax) axstk.set_xlim(xxlim) self.xzoom.append(xxlim) if self.opts.upylim_on: print ('upylim') ppstk.updateY(xxlim) axstk.figure.canvas.draw() pppara = self.opts.pppara a, col = pppara.alphatwsele, pppara.colortwsele mspan = pppara.minspan * self.opts.delta self.span = TimeSelector(axstk, on_select, 'horizontal', minspan=mspan, useblit=False, rectprops=dict(alpha=a, facecolor=col)) def on_zoom(self, event): """ Zoom back to previous xlim when event is in event.inaxes. """ evkey = event.key axstk = self.axstk if not axstk.contains(event)[0] or evkey is None: return xzoom = self.xzoom if evkey.lower() == 'z' and len(xzoom) > 1: del xzoom[-1] axstk.set_xlim(xzoom[-1]) print 'Zoom back to: %6.1f %6.1f ' % tuple(xzoom[-1]) if self.opts.upylim_on: for pp in self.pps: del pp.ynorm[-1] setp(pp.lines[0], ydata=pp.ybase+pp.sacdh.data*pp.ynorm[-1]) axstk.figure.canvas.draw() def replot(self): """ Replot seismograms and array stack after running iccs. """ self.ppstk.disconnect() self.ppstk.axpp.cla() self.plotStack() opts = self.opts sortSeis(self.gsac, self.opts) self.ppm.initIndex() self.ppm.replot(0) self.setLabels() def connect(self): """ Connect button events. """ self.axccim = self.axs['CCIM'] self.axccff = self.axs['CCFF'] self.axsync = self.axs['Sync'] self.axmccc = self.axs['MCCC'] self.axsac2 = self.axs['SAC2'] self.bnccim = Button(self.axccim, 'ICCS-A') self.bnccff = Button(self.axccff, 'ICCS-B') self.bnsync = Button(self.axsync, 'Sync') self.bnmccc = Button(self.axmccc, 'MCCC') self.bnsac2 = Button(self.axsac2, 'SAC P2') self.cidccim = self.bnccim.on_clicked(self.ccim) self.cidccff = self.bnccff.on_clicked(self.ccff) self.cidsync = self.bnsync.on_clicked(self.sync) self.cidmccc = self.bnmccc.on_clicked(self.mccc) self.cidsac2 = self.bnsac2.on_clicked(self.plot2) self.cidpress = self.axstk.figure.canvas.mpl_connect('key_press_event', self.on_zoom) def disconnect(self): """ Disconnect button events. """ self.bnccim.disconnect(self.cidccim) self.bnccff.disconnect(self.cidccff) self.bnsync.disconnect(self.cidsync) self.bnmccc.disconnect(self.cidmccc) self.bnsac1.disconnect(self.cidsac1) self.bnsac2.disconnect(self.cidsac2) self.axccim.cla() self.axccff.cla() self.axsync.cla() self.axmccc.cla() self.axsac1.cla() self.axsac2.cla() def syncPick(self): """ Sync final time pick hdrfin from array stack to all traces. """ self.getPicks() tshift = self.tfin - self.tmed hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs for sacdh in self.gsac.saclist: tfin = sacdh.gethdr(hdrmed) + tshift sacdh.sethdr(hdrfin, tfin) def syncWind(self): """ Sync time window relative to hdrfin from array stack to all traces. Times saved to twhdrs are alway absolute. """ wh0, wh1 = self.opts.qcpara.twhdrs hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs self.getWindow(hdrfin) twfin = self.twcorr for sacdh in self.gsac.saclist: tfin = sacdh.gethdr(hdrfin) th0 = tfin + twfin[0] th1 = tfin + twfin[1] sacdh.sethdr(wh0, th0) sacdh.sethdr(wh1, th1) def sync(self, event): """ Sync final time pick and time window from array stack to each trace and update current page. """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs wh0, wh1 = self.opts.qcpara.twhdrs if self.ppstk.sacdh.gethdr(hdrfin) == -12345.: print '*** hfinal %s is not defined. Pick at array stack first! ***' % hdrfin return self.syncPick() self.syncWind() twfin = self.twcorr for pp in self.ppm.pps: sacdh = pp.sacdh tfin = sacdh.gethdr(hdrfin) ipk = int(hdrfin[1]) tpk = tfin - sacdh.reftime pp.timepicks[ipk].set_xdata(tpk) th0 = tfin + twfin[0] th1 = tfin + twfin[1] pp.twindow = [th0, th1] pp.resetWindow() print '--> Sync final time picks and time window... You can now run CCFF to refine final picks.' def getWindow(self, hdr): """ Get time window twcorr (relative to hdr) from array stack, which is from last run. """ ppstk = self.ppstk tw0, tw1 = ppstk.twindow t0 = ppstk.sacdh.gethdr(hdr) if t0 == -12345.: print ('Header {0:s} not defined'.format(hdr)) return twcorr = [tw0-t0, tw1-t0] self.twcorr = twcorr def getPicks(self): """ Get time picks of stack """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs self.tini = self.gsac.stkdh.gethdr(hdrini) self.tmed = self.gsac.stkdh.gethdr(hdrmed) self.tfin = self.gsac.stkdh.gethdr(hdrfin) def ccim(self, event): # running ICCS-A will erase everything you did. Make sure the user did not hit it by mistake tkMessageBox.showwarning("Will Erase Work!","This will erase everything you manually selected. \nAre you sure?") """ Run iccs with time window from final stack. Time picks: hdrini, hdrmed. """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs self.cchdrs = hdrini, hdrmed self.getWindow(self.cchdrs[0]) self.ccStack() self.getPicks() self.replot() def ccff(self, event): """ Run iccs with time window from final stack. Time picks: hdrfin, hdrfin. """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs if self.gsac.stkdh.gethdr(hdrfin) == -12345.: print '*** hfinal %s is not defined. Sync first! ***' % hdrfin return # running ICCS-B will erase everything you did. Make sure the user did not hit it by mistake tkMessageBox.showwarning("Will Erase Work!","This will erase everything you manually selected. \nAre you sure?") self.cchdrs = hdrfin, hdrfin self.getWindow(self.cchdrs[0]) self.getPicks() self.ccStack() stkdh = self.gsac.stkdh stkdh.sethdr(hdrini, self.tini) stkdh.sethdr(hdrmed, self.tmed) self.replot() def ccStack(self): """ Call iccs.ccWeightStack. Change reference time pick to the input pick before ICCS and to the output pick afterwards. """ opts = self.opts ccpara = opts.ccpara opts.ccpara.twcorr = self.twcorr ccpara.cchdrs = self.cchdrs hdr0, hdr1 = int(ccpara.cchdrs[0][1]), int(ccpara.cchdrs[1][1]) stkdh, stkdata, quas = ccWeightStack(self.gsac.selist, self.opts) stkdh.selected = True stkdh.sethdr(opts.qcpara.hdrsel, 'True ') self.gsac.stkdh = stkdh if opts.reltime != hdr1: out = '\n--> change opts.reltime from %i to %i' print out % (opts.reltime, hdr1) opts.reltime = hdr1 def mccc(self, event): """ Run mccc.py """ gsac = self.gsac mcpara = self.opts.mcpara rcfile = mcpara.rcfile ipick = mcpara.ipick wpick = mcpara.wpick self.getWindow(ipick) timewindow = self.twcorr tw = timewindow[1]-timewindow[0] taperwindow = taperWindow(timewindow, mcpara.taperwidth) mcpara.timewindow = timewindow mcpara.taperwindow = taperwindow evline, mcname = eventListName(gsac.event, mcpara.phase) mcpara.evline = evline mcpara.mcname = mcname mcpara.kevnm = gsac.kevnm #rcwrite(ipick, timewindow, taperwindow, rcfile) solution = mccc(gsac, mcpara) wpk = int(wpick[1]) if self.opts.reltime != wpk: out = '\n--> change opts.reltime from %i to %i' print out % (self.opts.reltime, wpk) self.opts.reltime = wpk self.replot() def plot2(self, event): """ Plot P2 stack of seismograms for defined time picks (ichdrs + wpick). """ opts = copy.copy(self.opts) twin_on = opts.twin_on pick_on = opts.pick_on reltime = opts.reltime ynorm = opts.ynorm fill = opts.fill selist = self.gsac.selist tpicks = opts.qcpara.ichdrs + [opts.mcpara.wpick,] print ('SAC Plot2') npick = len(tpicks) tlabs = 'ABCDE' fig2 = figure(figsize=(9,12)) fig2.clf() subplots_adjust(bottom=.05, top=0.96, left=.1, right=.97, wspace=.5, hspace=.24) opts.twin_on = False opts.pick_on = False ax0 = fig2.add_subplot(npick,1,1) axsacs = [ ax0 ] + [ fig2.add_subplot(npick,1,i+1, sharex=ax0) for i in range(1, npick) ] for i in range(npick): opts.reltime = int(tpicks[i][1]) ax = axsacs[i] sacp2(selist, opts, ax) tt = '(' + tlabs[i] + ')' trans = transforms.blended_transform_factory(ax.transAxes, ax.transAxes) ax.text(-.05, 1, tt, transform=trans, va='center', ha='right', size=16) opts.ynorm = ynorm opts.twin_on = twin_on opts.pick_on = pick_on opts.reltime = reltime opts.fill = fill opts.zero_on = False show()
class PickPhaseMenuMore: """ Pick phase for multiple seismograms and array stack Button: Sync """ def __init__(self, gsac, opts, axs): self.gsac = gsac self.opts = opts self.axs = axs self.axstk = self.axs['Fstk'] if not 'stkdh' in gsac.__dict__: if opts.filemode == 'sac' and os.path.isfile(opts.fstack): gsac.stkdh = SacDataHdrs(opts.fstack, opts.delta) else: hdrini, hdrmed, hdrfin = opts.qcpara.ichdrs self.cchdrs = [hdrini, hdrmed] self.twcorr = opts.ccpara.twcorr # check data coverage opts.ipick = hdrini opts.twcorr = opts.ccpara.twcorr checkCoverage(gsac, opts) gsac.selist = gsac.saclist self.ccStack() self.initPlot() self.plotStack() self.addEarthquakeInfo() self.setLabels() self.connect() def initPlot(self): """ Plot waveforms """ gsac = self.gsac opts = self.opts sortSeis(gsac, opts) self.ppm = PickPhaseMenu(gsac, opts, self.axs) # make the legend box invisible if self.opts.pick_on: self.ppm.axpp.get_legend().set_visible(False) def addEarthquakeInfo(self): """ Set Earthquake Info * Magnitude * Location (Lat and Long) * Depth """ gsac = self.gsac # get required parameters locationLat = round(gsac.event[6],2) locationLon = round(gsac.event[7],2) depth = round(gsac.event[8],2) magnitude = round(gsac.event[9],2) all_gcarc = [] [all_gcarc.append(hdr.gcarc) for hdr in gsac.selist ] avg_gcarc = round(np.mean(all_gcarc),2) infoaxis = self.axs['Info'] # remove axes markings infoaxis.axes.get_xaxis().set_ticks([]) infoaxis.axes.get_yaxis().set_visible(False) # write the info into the axis plot infoaxis.text(0.1,0.85,'Magnitude: '+str(magnitude)) infoaxis.text(0.1,0.65,'Lat: '+str(locationLat)) infoaxis.text(0.1,0.45,'Lon: '+str(locationLon)) infoaxis.text(0.1,0.25,'Depth: '+str(depth)) infoaxis.text(0.1,0.05,'Gcarc: '+str(avg_gcarc)) def setLabels(self): """ Set plot attributes """ self.ppm.axpp.set_title('Seismograms') if self.opts.filemode == 'pkl': axstk = self.axstk trans = transforms.blended_transform_factory(axstk.transAxes, axstk.transAxes) axstk.text(1,1.01,self.opts.pklfile,transform=trans, va='bottom', ha='right',color='k') axpp = self.ppm.axpp trans = transforms.blended_transform_factory(axpp.transAxes, axpp.transData) font = FontProperties() font.set_family('monospace') axpp.text(1.025, 0, ' '*8+'qual= CCC/SNR/COH', transform=trans, va='center', color='k', fontproperties=font) def plotStack(self): """ Plot array stack and span """ colorwave = self.opts.pppara.colorwave stkybase = 0 ppstk = PickPhase(self.gsac.stkdh, self.opts, self.axstk, stkybase, colorwave, 1) ppstk.plotPicks() ppstk.disconnectPick() self.ppstk = ppstk self.axstk.set_title('Array Stack') self.ppstk.stalabel.set_visible(False) if self.opts.ynorm == 1.0: self.axstk.set_ylim(stkybase-0.5, stkybase+0.5) self.axstk.set_yticks([stkybase]) self.axstk.set_yticklabels([]) self.axstk.axvline(x=0, color='k', ls=':') # plot legend pppara = self.opts.pppara pickLegend(self.axstk, pppara.npick, pppara.pickcolors, pppara.pickstyles, False) self.plotSpan() def plotSpan(self): """ Span for array stack """ axstk = self.axstk self.xzoom = [axstk.get_xlim(),] def on_select(xmin, xmax): """ Mouse event: select span. """ if self.span.visible: print('span selected: %6.1f %6.1f ' % (xmin, xmax)) xxlim = (xmin, xmax) axstk.set_xlim(xxlim) self.xzoom.append(xxlim) if self.opts.upylim_on: print ('upylim') self.ppstk.updateY(xxlim) ## axstk.figure.canvas.draw() pppara = self.opts.pppara a, col = pppara.alphatwsele, pppara.colortwsele mspan = pppara.minspan * self.opts.delta self.span = TimeSelector(axstk, on_select, 'horizontal', minspan=mspan, useblit=False, rectprops=dict(alpha=a, facecolor=col)) #self.replot() #self.ppm.axpp.figure.canvas.draw() # -------------------------------- SORTING ---------------------------------- # # Sort seismograms by # -------------- # * | file indices | # -------------- # ----- ----- ----- ----- # * quality factor | all | ccc | snr | coh | # ----- ----- ----- ----- # ---- ----- ------ # * given header | az | baz | dist | ... # ---- ----- ------ def sorting(self, event): """ Sort the seismograms in particular order """ self.getSortAxes() self.summarize_sort() self.sort_connect() plt.show() def getSortAxes(self): figsort = plt.figure('SortSeismograms',figsize=(15, 12)) x0 = 0.05 xx = 0.10 yy = 0.04 #xm = 0.02 dy = 0.15 dx = 0.12 y0 = 0.90 """Allocating size of buttons""" # file indices (filenames) rectfile = [x0, y0-dy*1, xx, yy] # quality rectqall = [x0+dx*0, y0-2*dy, xx, yy] rectqccc = [x0+dx*1, y0-2*dy, xx, yy] rectqsnr = [x0+dx*2, y0-2*dy, xx, yy] rectqcoh = [x0+dx*3, y0-2*dy, xx, yy] # headers recthnpts = [x0+dx*0, y0-3*dy, xx, yy] recthb = [x0+dx*1, y0-3*dy, xx, yy] recthe = [x0+dx*2, y0-3*dy, xx, yy] recthdelta = [x0+dx*3, y0-3*dy, xx, yy] recthstla = [x0+dx*0, y0-3.5*dy, xx, yy] recthstlo = [x0+dx*1, y0-3.5*dy, xx, yy] recthdist = [x0+dx*2, y0-3.5*dy, xx, yy] recthaz = [x0+dx*3, y0-3.5*dy, xx, yy] recthbaz = [x0+dx*0, y0-4*dy, xx, yy] recthgcarc = [x0+dx*1, y0-4*dy, xx, yy] # quit rectquit = [0.2, y0-5*dy, 0.2, yy] """writing buttons to axis""" sortAxs = {} figsort.text(0.1,y0-dy*0.5,'Sort by file Index Name: ') sortAxs['file'] = figsort.add_axes(rectfile) figsort.text(0.1,y0-dy*1.5,'Sort by Quality: ') sortAxs['qall'] = figsort.add_axes(rectqall) sortAxs['qccc'] = figsort.add_axes(rectqccc) sortAxs['qsnr'] = figsort.add_axes(rectqsnr) sortAxs['qcoh'] = figsort.add_axes(rectqcoh) figsort.text(0.1,y0-dy*2.5,'Sort by Header: ') sortAxs['hnpts'] = figsort.add_axes(recthnpts) sortAxs['hb'] = figsort.add_axes(recthb) sortAxs['he'] = figsort.add_axes(recthe) sortAxs['hdelta'] = figsort.add_axes(recthdelta) sortAxs['hstla'] = figsort.add_axes(recthstla) sortAxs['hstlo'] = figsort.add_axes(recthstlo) sortAxs['hdist'] = figsort.add_axes(recthdist) sortAxs['haz'] = figsort.add_axes(recthaz) sortAxs['hbaz'] = figsort.add_axes(recthbaz) sortAxs['hgcarc'] = figsort.add_axes(recthgcarc) sortAxs['quit'] = figsort.add_axes(rectquit) """ size of text summary box """ rectsumm = [0.55, 0.05, 0.40, 0.90] sortAxs['summary'] = figsort.add_axes(rectsumm) # remove axes markings on summary field sortAxs['summary'].get_xaxis().set_ticks([]) sortAxs['summary'].get_yaxis().set_visible([]) self.sortAxs = sortAxs self.figsort = figsort def summarize_sort(self): sortAxs = self.sortAxs # define constants x0 = 0.03 x1 = 0.20 y0 = 0.95 dy = 0.03 # explain what the summaries are sortAxs['summary'].text(x0,y0-dy*0,'FILENAMES') sortAxs['summary'].text(x0,y0-dy*1,'File: ') sortAxs['summary'].text(x1,y0-dy*1,'Sort in alphabetical order by filename') sortAxs['summary'].text(x0,y0-dy*3,'QUALITY:') sortAxs['summary'].text(x0,y0-dy*4,'All: ') sortAxs['summary'].text(x1,y0-dy*4,'Weighted Ratio of all quality measures') sortAxs['summary'].text(x0,y0-dy*5,'CCC: ') sortAxs['summary'].text(x1,y0-dy*5,'Cross-coefficient Coefficient') sortAxs['summary'].text(x0,y0-dy*6,'SNR: ') sortAxs['summary'].text(x1,y0-dy*6,'Signal-to-noise Ratio') sortAxs['summary'].text(x0,y0-dy*7,'COH: ') sortAxs['summary'].text(x1,y0-dy*7,'time domain coherence') sortAxs['summary'].text(x0,y0-dy*9,'OTHER HEADERS:') sortAxs['summary'].text(x0,y0-dy*10,'NPTS: ') sortAxs['summary'].text(x1,y0-dy*10,'Number of points per data component') sortAxs['summary'].text(x0,y0-dy*11,'B: ') sortAxs['summary'].text(x1,y0-dy*11,'Beginning value of the independent variable') sortAxs['summary'].text(x0,y0-dy*12,'E: ') sortAxs['summary'].text(x1,y0-dy*12,'Ending value of the independent variable') sortAxs['summary'].text(x0,y0-dy*13,'Delta: ') sortAxs['summary'].text(x1,y0-dy*13,'Increment between evenly spaced samples') sortAxs['summary'].text(x0,y0-dy*14,'STLA: ') sortAxs['summary'].text(x1,y0-dy*14,'Station latitude (deg, north positive)') sortAxs['summary'].text(x0,y0-dy*15,'STLO: ') sortAxs['summary'].text(x1,y0-dy*15,'Station longitude (deg, east positive)') sortAxs['summary'].text(x0,y0-dy*16,'DIST: ') sortAxs['summary'].text(x1,y0-dy*16,'Station to event distance (km)') sortAxs['summary'].text(x0,y0-dy*17,'AZ: ') sortAxs['summary'].text(x1,y0-dy*17,'Event to station azimuth (deg)') sortAxs['summary'].text(x0,y0-dy*18,'BAZ: ') sortAxs['summary'].text(x1,y0-dy*18,'Station to event azimuth (deg)') sortAxs['summary'].text(x0,y0-dy*19,'GCARC: ') sortAxs['summary'].text(x1,y0-dy*19,'Station to event great circle arc length (deg)') """ Connect button events. """ def sort_connect(self): """write the position for the buttons into self""" self.axfile = self.sortAxs['file'] self.axqall = self.sortAxs['qall'] self.axqccc = self.sortAxs['qccc'] self.axqsnr = self.sortAxs['qsnr'] self.axqcoh = self.sortAxs['qcoh'] self.axqcoh = self.sortAxs['qcoh'] self.axhnpts = self.sortAxs['hnpts'] self.axhb = self.sortAxs['hb'] self.axhe = self.sortAxs['he'] self.axhdelta = self.sortAxs['hdelta'] self.axhstla = self.sortAxs['hstla'] self.axhstlo = self.sortAxs['hstlo'] self.axhdist = self.sortAxs['hdist'] self.axhaz = self.sortAxs['haz'] self.axhbaz = self.sortAxs['hbaz'] self.axhgcarc = self.sortAxs['hgcarc'] self.axquit = self.sortAxs['quit'] """add a button to the correct place as defined by the axes Also label the buttons here, as seen in the GUI """ self.bnfile = Button(self.axfile, 'File') self.bnqall = Button(self.axqall, 'All') self.bnqccc = Button(self.axqccc, 'CCC') self.bnqsnr = Button(self.axqsnr, 'SNR') self.bnqcoh = Button(self.axqcoh, 'COH') self.bnhnpts = Button(self.axhnpts, 'NPTS') self.bnhb = Button(self.axhb, 'B') self.bnhe = Button(self.axhe, 'E') self.bnhdelta = Button(self.axhdelta, 'Delta') self.bnhstla = Button(self.axhstla, 'STLA') self.bnhstlo = Button(self.axhstlo, 'STLO') self.bnhdist = Button(self.axhdist, 'Dist') self.bnhaz = Button(self.axhaz, 'AZ') self.bnhbaz = Button(self.axhbaz, 'BAZ') self.bnhgcarc = Button(self.axhgcarc, 'GCARC') self.bnquit = Button(self.axquit, 'Waiting for User input') """ each button changes the way the seismograms are sorted """ self.cidfile = self.bnfile.on_clicked(self.sort_file) self.cidqall = self.bnqall.on_clicked(self.sort_qall) self.cidqccc = self.bnqccc.on_clicked(self.sort_qccc) self.cidqsnr = self.bnqsnr.on_clicked(self.sort_qsnr) self.cidqcoh = self.bnqcoh.on_clicked(self.sort_qcoh) self.cidhnpts = self.bnhnpts.on_clicked(self.sort_hnpts) self.cidhb = self.bnhb.on_clicked(self.sort_hb) self.cidhe = self.bnhe.on_clicked(self.sort_he) self.cidhdelta = self.bnhdelta.on_clicked(self.sort_hdelta) self.cidhstla = self.bnhstla.on_clicked(self.sort_hstla) self.cidhstlo = self.bnhstlo.on_clicked(self.sort_hstlo) self.cidhdist = self.bnhdist.on_clicked(self.sort_hdist) self.cidhaz = self.bnhaz.on_clicked(self.sort_haz) self.cidhbaz = self.bnhbaz.on_clicked(self.sort_hbaz) self.cidhgcarc = self.bnhgcarc.on_clicked(self.sort_hgcarc) # dismiss window when done self.bnquit.on_clicked(self.dismiss_sort) def sort_disconnect(self): self.bnfile.disconnect(self.cidfile) self.bnqall.disconnect(self.cidqall) self.bnqccc.disconnect(self.cidqccc) self.bnqsnr.disconnect(self.cidqsnr) self.bnqcoh.disconnect(self.cidqcoh) self.bnhnpts.disconnect(self.cidhnpts) self.bnhb.disconnect(self.cidhb) self.bnhe.disconnect(self.cidhe) self.bnhdelta.disconnect(self.cidhdelta) self.bnhstla.disconnect(self.cidhstla) self.bnhstlo.disconnect(self.cidhstlo) self.bnhdist.disconnect(self.cidhdist) self.bnhaz.disconnect(self.cidhaz) self.bnhbaz.disconnect(self.cidhbaz) self.bnhgcarc.disconnect(self.cidhgcarc) def sort_file(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'i'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_qall(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'all'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_qccc(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = '1'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_qsnr(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = '2'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_qcoh(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = '3'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hnpts(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'npts'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hb(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'b'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_he(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'e'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hdelta(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'delta'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hkstnm(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'kstnm'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hstla(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'stla'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hstlo(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'stlo'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hdist(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'dist'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_haz(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'az'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hbaz(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'baz'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def sort_hgcarc(self, event): self.bnquit.label.set_text('Processing...') event.canvas.draw() self.opts.sortby = 'gcarc'; self.replot_seismograms() self.ppm.axpp.figure.canvas.draw() self.bnquit.label.set_text('Done! Click to Exit.') event.canvas.draw() return def dismiss_sort(self, event): """Dismiss the sorting selection popup Window""" self.sort_disconnect() close() # -------------------------------- SORTING ---------------------------------- # # --------------------------------- Filtering ------------------------------- # # Implement Butterworth filter # def filtering(self,event): filterAxes = self.getFilterAxes() self.spreadButter() self.filter_connect() plt.show() def filter_connect(self): # user to change default parameters self.cidSelectFreq = self.filterAxs['amVfreq'].get_figure().canvas.mpl_connect('button_press_event', self.getBandpassFreq) # get order self.bnorder = RadioButtons(self.filterAxs['ordr'], (1,2,3,4), active=1) self.cidorder = self.bnorder.on_clicked(self.getButterOrder) # get type of filter to use self.bnband = RadioButtons(self.filterAxs['band'], ('bandpass','lowpass','highpass')) self.cidband = self.bnband.on_clicked(self.getBandtype) # get reverse pass option self.bnreversepass = RadioButtons(self.filterAxs['reversepass'], ('yes', 'no'), active=1) self.cidreversepass = self.bnreversepass.on_clicked(self.getReversePassOption) #add apply button. causes the filtered data to be applied self.bnapply = Button(self.filterAxs['apply'], 'Apply') self.cidapply = self.bnapply.on_clicked(self.applyFilter) #add unapply button. causes the filtered data to be applied self.bnunapply = Button(self.filterAxs['unapply'], 'Unapply') self.cidunapply = self.bnunapply.on_clicked(self.unapplyFilter) def getReversePassOption(self, event): if event == 'yes': self.opts.filterParameters['reversepass'] = True else: self.opts.filterParameters['reversepass'] = False self.spreadButter() def getBandtype(self, event): self.opts.filterParameters['band'] = event if event=='bandpass': self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) # set defaults self.opts.filterParameters['lowFreq'] = 0.05 self.opts.filterParameters['highFreq'] = 0.25 self.opts.filterParameters['advance'] = False self.spreadButter() #execute self.cidSelectFreq = self.filterAxs['amVfreq'].get_figure().canvas.mpl_connect('button_press_event', self.getBandpassFreq) elif event=='lowpass': self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) # set defaults self.opts.filterParameters['lowFreq'] = 0.05 self.opts.filterParameters['highFreq'] = np.nan self.opts.filterParameters['advance'] = False self.spreadButter() #execute self.cidSelectFreq = self.filterAxs['amVfreq'].get_figure().canvas.mpl_connect('button_press_event', self.getLowFreq) elif event=='highpass': self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) # set defaults self.opts.filterParameters['lowFreq'] = np.nan self.opts.filterParameters['highFreq'] = 0.25 self.opts.filterParameters['advance'] = False self.spreadButter() #execute self.cidSelectFreq = self.filterAxs['amVfreq'].get_figure().canvas.mpl_connect('button_press_event', self.getHighFreq) def getLowFreq(self, event): if event.inaxes == self.filterAxs['amVfreq']: self.opts.filterParameters['lowFreq'] = event.xdata self.spreadButter() def getHighFreq(self, event): if event.inaxes == self.filterAxs['amVfreq']: self.opts.filterParameters['highFreq'] = event.xdata self.spreadButter() def getButterOrder(self, event): self.opts.filterParameters['order'] = int(event) self.spreadButter() def getBandpassFreq(self,event): if event.inaxes == self.filterAxs['amVfreq']: if self.opts.filterParameters['advance']: # low and high frequencies recorded self.opts.filterParameters['highFreq'] = event.xdata if self.opts.filterParameters['lowFreq']<self.opts.filterParameters['highFreq']: self.opts.filterParameters['advance'] = False self.spreadButter() else: print('Value chose must be higher than lower frequency of %f' % self.opts.filterParameters['lowFreq']) else: self.opts.filterParameters['lowFreq'] = event.xdata self.opts.filterParameters['advance'] = True def modifyFilterTextLabels(self): self.filterAxs['Info'].clear() self.filterAxs['Info'].text(0.1,0.7,'Low Freq: '+str(self.opts.filterParameters['lowFreq'])) self.filterAxs['Info'].text(0.1,0.4,'High Freq: '+str(self.opts.filterParameters['highFreq'])) self.filterAxs['Info'].text(0.1,0.1,'Order: '+str(self.opts.filterParameters['order'])) """Apply the butterworth filter to the data """ def spreadButter(self): # clear axes self.filterAxs['amVtime'].clear() self.filterAxs['amVfreq'].clear() #set axes limit self.filterAxs['amVtime'].set_xlim(-30,30) self.filterAxs['amVfreq'].set_xlim(0,1.50) self.modifyFilterTextLabels() originalTime = self.ppstk.time - self.ppstk.sacdh.reftime originalSignalTime = self.ppstk.sacdh.data originalFreq, originalSignalFreq = ftr.time_to_freq(originalTime, originalSignalTime, self.opts.delta) filteredSignalTime, filteredSignalFreq, adjusted_w, adjusted_h = ftr.filtering_time_freq(originalTime, originalSignalTime, self.opts.delta, self.opts.filterParameters['band'], self.opts.filterParameters['highFreq'], self.opts.filterParameters['lowFreq'], self.opts.filterParameters['order'], self.opts.filterParameters['reversepass']) # PLOT TIME self.filterAxs['amVtime'].plot(originalTime, originalSignalTime, label='Original') self.filterAxs['amVtime'].plot(originalTime, filteredSignalTime, label='Filtered') self.filterAxs['amVtime'].legend(loc="upper right") self.filterAxs['amVtime'].set_title('Signal vs Time') self.filterAxs['amVtime'].set_xlabel('Time (s)', fontsize = 12) self.filterAxs['amVtime'].set_ylabel('Signal', fontsize = 12) # PLOT FREQUENCY self.filterAxs['amVfreq'].plot(originalFreq, np.abs(originalSignalFreq), label='Original') self.filterAxs['amVfreq'].plot(originalFreq, np.abs(filteredSignalFreq), label='Filtered') self.filterAxs['amVfreq'].plot(adjusted_w, adjusted_h, label='Butterworth Filter') self.filterAxs['amVfreq'].legend(loc="upper right") self.filterAxs['amVfreq'].set_title('Amplitude vs frequency') self.filterAxs['amVfreq'].set_xlabel('Frequency (Hz)', fontsize = 12) self.filterAxs['amVfreq'].set_ylabel('Amplitude Signal', fontsize = 12) # redraw the plots on the popup window self.figfilter.canvas.draw() def applyFilter(self, event): #should we write filtered data for individual seismograms self.opts.filterParameters['apply'] = True # replot filtered stuff self.axstk.clear() self.ppm.axpp.clear() self.axs['Fron'].clear() self.axs['Prev'].clear() self.axs['Next'].clear() self.axs['Last'].clear() self.axs['Zoba'].clear() self.axs['Shdo'].clear() self.axs['Shfp'].clear() self.axs['Shod'].clear() self.axs['Quit'].clear() self.ppm = PickPhaseMenu(self.gsac, self.opts, self.axs) # make the legend box invisible if self.opts.pick_on: self.ppm.axpp.get_legend().set_visible(False) self.plotStack() # redraw figures self.ppm.axpp.figure.canvas.draw() self.axstk.figure.canvas.draw() # disconnect self.bnorder.disconnect(self.cidorder) self.bnunapply.disconnect(self.cidunapply) self.bnband.disconnect(self.cidband) self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) plt.close() def unapplyFilter(self, event): # do not write filtered data for individual seismograms self.opts.filterParameters['apply'] = False #reset back to original defaults self.opts.filterParameters['band'] = 'bandpass' self.opts.filterParameters['lowFreq'] = 0.05 self.opts.filterParameters['highFreq'] = 0.25 self.opts.filterParameters['order'] = 2 # replot filtered stuff self.axstk.clear() self.ppm.axpp.clear() self.axs['Fron'].clear() self.axs['Prev'].clear() self.axs['Next'].clear() self.axs['Last'].clear() self.axs['Zoba'].clear() self.axs['Shdo'].clear() self.axs['Shfp'].clear() self.axs['Shod'].clear() self.axs['Quit'].clear() self.initPlot() self.plotStack() # redraw figures self.ppm.axpp.figure.canvas.draw() self.axstk.figure.canvas.draw() # disconnect self.bnorder.disconnect(self.cidorder) self.bnapply.disconnect(self.cidapply) self.bnband.disconnect(self.cidband) self.filterAxs['amVfreq'].figure.canvas.mpl_disconnect(self.cidSelectFreq) plt.close() def getFilterAxes(self): figfilter = plt.figure(figsize=(15, 12)) self.figfilter = figfilter rect_amVtime = [0.10, 0.50, 0.80, 0.35] rect_amVfreq = [0.10, 0.07, 0.80, 0.35] rectinfo = [0.8, 0.86, 0.15, 0.10] rectordr = [0.3, 0.86, 0.10, 0.10] rectunapply = [0.42, 0.90, 0.07, 0.04] rectapply = [0.5, 0.90, 0.05, 0.04] rectband = [0.6, 0.86, 0.10, 0.10] rectreversepass = [0.72, 0.86, 0.07, 0.10] filterAxs = {} self.figfilter.text(0.03,0.95,'Butterworth Filter', {'weight':'bold', 'size':21}) filterAxs['amVtime'] = figfilter.add_axes(rect_amVtime) filterAxs['amVfreq'] = figfilter.add_axes(rect_amVfreq) filterAxs['ordr'] = figfilter.add_axes(rectordr) filterAxs['unapply'] = figfilter.add_axes(rectunapply) filterAxs['apply'] = figfilter.add_axes(rectapply) filterAxs['band'] = figfilter.add_axes(rectband) filterAxs['reversepass'] = figfilter.add_axes(rectreversepass) self.figfilter.text(0.3, 0.97, 'Order:') self.figfilter.text(0.6, 0.97, 'Filter Type:') self.figfilter.text(0.72, 0.97, 'Run Reverse:') # frequencies used to compute butterworth filter displayed here filterAxs['Info'] = figfilter.add_axes(rectinfo) filterAxs['Info'].axes.get_xaxis().set_visible(False) filterAxs['Info'].axes.get_yaxis().set_visible(False) self.filterAxs = filterAxs # --------------------------------- Filtering ------------------------------- # def plot_stations(self, event): event_name = 'event' if hasattr(self.opts, 'pklfile'): event_name = self.opts.pklfile PlotStations(event_name, self.gsac) def on_zoom(self, event): """ Zoom back to previous xlim when event is in event.inaxes. """ evkey = event.key axstk = self.axstk if not axstk.contains(event)[0] or evkey is None: return xzoom = self.xzoom if evkey.lower() == 'z' and len(xzoom) > 1: del xzoom[-1] axstk.set_xlim(xzoom[-1]) print('Zoom back to: %6.1f %6.1f ' % tuple(xzoom[-1])) if self.opts.upylim_on: for pp in self.pps: del pp.ynorm[-1] plt.setp(pp.lines[0], ydata=pp.ybase+pp.sacdh.data*pp.ynorm[-1]) axstk.figure.canvas.draw() def replot_seismograms(self): """ Replot seismograms and array stack after running iccs. """ sortSeis(self.gsac, self.opts) self.ppm.initIndex() self.ppm.replot(0) self.setLabels() def replot(self): """ Replot seismograms and array stack after running iccs. """ self.ppstk.disconnect() self.ppstk.axpp.cla() self.plotStack() sortSeis(self.gsac, self.opts) self.ppm.initIndex() self.ppm.replot(0) self.setLabels() def connect(self): """ Connect button events. """ # write the position for the buttons into self self.axccim = self.axs['CCIM'] self.axccff = self.axs['CCFF'] self.axsync = self.axs['Sync'] self.axmccc = self.axs['MCCC'] self.axsac2 = self.axs['SAC2'] self.axsort = self.axs['Sort'] self.axfilter = self.axs['Filter'] self.axplotsta = self.axs['plotsta'] # name the buttons self.bnccim = Button(self.axccim, 'Align') self.bnccff = Button(self.axccff, 'Refine') self.bnsync = Button(self.axsync, 'Sync') self.bnmccc = Button(self.axmccc, 'Finalize') self.bnsac2 = Button(self.axsac2, 'SAC P2') self.bnsort = Button(self.axsort, 'Sort') self.bnfilter = Button(self.axfilter, 'Filter') self.bnplotsta = Button(self.axplotsta, 'Map of\n stations') self.cidccim = self.bnccim.on_clicked(self.ccim) self.cidccff = self.bnccff.on_clicked(self.ccff) self.cidsync = self.bnsync.on_clicked(self.sync) self.cidmccc = self.bnmccc.on_clicked(self.mccc) self.cidsac2 = self.bnsac2.on_clicked(self.plot2) self.cidsort = self.bnsort.on_clicked(self.sorting) self.cidfilter = self.bnfilter.on_clicked(self.filtering) self.cidplotsta = self.bnplotsta.on_clicked(self.plot_stations) self.cidpress = self.axstk.figure.canvas.mpl_connect('key_press_event', self.on_zoom) def disconnect(self): """ Disconnect button events. """ self.bnccim.disconnect(self.cidccim) self.bnccff.disconnect(self.cidccff) self.bnsync.disconnect(self.cidsync) self.bnmccc.disconnect(self.cidmccc) self.bnsac2.disconnect(self.cidsac2) self.bnsort.disconnect(self.cidsort) self.bnfilter.disconnect(self.cidfilter) self.axccim.cla() self.axccff.cla() self.axsync.cla() self.axmccc.cla() self.axsac2.cla() self.axsort.cla() self.axfilter.cla() def syncPick(self): """ Sync final time pick hdrfin from array stack to all traces. """ self.getPicks() tshift = self.tfin - self.tmed hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs for sacdh in self.gsac.saclist: tfin = sacdh.gethdr(hdrmed) + tshift sacdh.sethdr(hdrfin, tfin) def syncWind(self): """ Sync time window relative to hdrfin from array stack to all traces. Times saved to twhdrs are alway absolute. """ wh0, wh1 = self.opts.qcpara.twhdrs hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs self.getWindow(hdrfin) twfin = self.twcorr for sacdh in self.gsac.saclist: tfin = sacdh.gethdr(hdrfin) th0 = tfin + twfin[0] th1 = tfin + twfin[1] sacdh.sethdr(wh0, th0) sacdh.sethdr(wh1, th1) def sync(self, event): """ Sync final time pick and time window from array stack to each trace and update current page. """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs wh0, wh1 = self.opts.qcpara.twhdrs if self.ppstk.sacdh.gethdr(hdrfin) == -12345.: print('*** hfinal %s is not defined. Pick at array stack first! ***' % hdrfin) return self.syncPick() self.syncWind() twfin = self.twcorr for pp in self.ppm.pps: sacdh = pp.sacdh tfin = sacdh.gethdr(hdrfin) ipk = int(hdrfin[1]) tpk = tfin - sacdh.reftime pp.timepicks[ipk].set_xdata(tpk) th0 = tfin + twfin[0] th1 = tfin + twfin[1] pp.twindow = [th0, th1] pp.resetWindow() print('--> Sync final time picks and time window... You can now run CCFF to refine final picks.') def getWindow(self, hdr): """ Get time window twcorr (relative to hdr) from array stack, which is from last run. """ ppstk = self.ppstk tw0, tw1 = ppstk.twindow t0 = ppstk.sacdh.gethdr(hdr) if t0 == -12345.: print(('Header {0:s} not defined'.format(hdr))) return twcorr = [tw0-t0, tw1-t0] self.twcorr = twcorr def getPicks(self): """ Get time picks of stack """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs self.tini = self.gsac.stkdh.gethdr(hdrini) self.tmed = self.gsac.stkdh.gethdr(hdrmed) self.tfin = self.gsac.stkdh.gethdr(hdrfin) def ccim(self, event): # running ICCS-A will erase everything you did. Make sure the user did not hit it by mistake shouldRun = tkinter.messagebox.askokcancel("Will Erase Work!","This will erase any picks past t1. \nAre you sure?") if shouldRun: """ Run iccs with time window from final stack. Time picks: hdrini, hdrmed. """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs self.cchdrs = hdrini, hdrmed self.getWindow(self.cchdrs[0]) self.ccStack() self.getPicks() self.replot() def ccff(self, event): """ Run iccs with time window from final stack. Time picks: hdrfin, hdrfin. """ hdrini, hdrmed, hdrfin = self.opts.qcpara.ichdrs if self.gsac.stkdh.gethdr(hdrfin) == -12345.: print('*** hfinal %s is not defined. Sync first! ***' % hdrfin) return """running ICCS-B will erase everything you did. Make sure the user did not hit it by mistake""" shouldRun = tkinter.messagebox.askokcancel("Will Erase Work!","This will erase any picks past t2 and will recalculate all t2 values. \nAre you sure?") if shouldRun: self.cchdrs = hdrfin, hdrfin self.getWindow(self.cchdrs[0]) self.getPicks() self.ccStack() stkdh = self.gsac.stkdh stkdh.sethdr(hdrini, self.tini) stkdh.sethdr(hdrmed, self.tmed) self.replot() def ccStack(self): """ Call iccs.ccWeightStack. Change reference time pick to the input pick before ICCS and to the output pick afterwards. """ opts = self.opts ccpara = opts.ccpara opts.ccpara.twcorr = self.twcorr ccpara.cchdrs = self.cchdrs hdr0, hdr1 = int(ccpara.cchdrs[0][1]), int(ccpara.cchdrs[1][1]) stkdh, stkdata, quas = ccWeightStack(self.gsac.selist, self.opts) stkdh.selected = True stkdh.sethdr(opts.qcpara.hdrsel, b'True ') self.gsac.stkdh = stkdh if opts.reltime != hdr1: out = '\n--> change opts.reltime from %i to %i' print(out % (opts.reltime, hdr1)) opts.reltime = hdr1 def mccc(self, event): """ Run mccc.py """ gsac = self.gsac mcpara = self.opts.mcpara #rcfile = mcpara.rcfile ipick = mcpara.ipick wpick = mcpara.wpick self.getWindow(ipick) timewindow = self.twcorr #tw = timewindow[1]-timewindow[0] taperwindow = taperWindow(timewindow, mcpara.taperwidth) mcpara.timewindow = timewindow mcpara.taperwindow = taperwindow evline, mcname = eventListName(gsac.event, mcpara.phase) mcpara.evline = evline mcpara.mcname = mcname mcpara.kevnm = gsac.kevnm solution, solist_LonLat, delay_times = mccc(gsac, mcpara) self.gsac.solist_LonLat = solist_LonLat self.gsac.delay_times = delay_times wpk = int(wpick[1]) if self.opts.reltime != wpk: out = '\n--> change opts.reltime from %i to %i' print(out % (self.opts.reltime, wpk)) self.opts.reltime = wpk self.replot() def plot2(self, event): """ Plot P2 stack of seismograms for defined time picks (ichdrs + wpick). """ opts = copy.copy(self.opts) twin_on = opts.twin_on pick_on = opts.pick_on reltime = opts.reltime ynorm = opts.ynorm fill = opts.fill selist = self.gsac.selist tpicks = opts.qcpara.ichdrs + [opts.mcpara.wpick,] npick = len(tpicks) tlabs = 'ABCDE' fig2 = plt.figure(figsize=(9,12)) fig2.clf() plt.subplots_adjust(bottom=.05, top=0.96, left=.1, right=.97, wspace=.5, hspace=.24) opts.twin_on = False opts.pick_on = False ax0 = fig2.add_subplot(npick,1,1) axsacs = [ ax0 ] + [ fig2.add_subplot(npick,1,i+1, sharex=ax0) for i in list(range(1, npick)) ] for i in list(range(npick)): opts.reltime = int(tpicks[i][1]) ax = axsacs[i] sacp2(selist, opts, ax) tt = '(' + tlabs[i] + ')' trans = transforms.blended_transform_factory(ax.transAxes, ax.transAxes) ax.text(-.05, 1, tt, transform=trans, va='center', ha='right', size=16) opts.ynorm = ynorm opts.twin_on = twin_on opts.pick_on = pick_on opts.reltime = reltime opts.fill = fill opts.zero_on = False plt.show()
axButton1 = plt.axes([0.1, 0.1, 0.1, 0.1]) #left, bottom, width, height btn1 = Button( ax=axButton1, label='Green', # image=ICON_Python, color='teal', hovercolor='tomato') def color_green(event): p.set_color('green') plt.draw() btn1.on_clicked(color_green) axButton2 = plt.axes([0.3, 0.1, 0.1, 0.1]) btn2 = Button(axButton2, 'Red') def color_red(event): p.set_color('red') plt.draw() cid = btn2.on_clicked(color_red) btn2.disconnect(cid) plt.show()