def trigger_locations_inner(max_val, max_x, max_y, max_z, left_trig, right_trig, start_time, delta): """ Inner loop of the location process. :param max_val: Time-series of stack-max. :param max_x: Time-series of the x-positions corresponding to stack-max. :param max_y: Time-series of the y-positions corresponding to stack-max. :param max_z: Time-series of the z-positions corresponding to stack-max. :param left_trig: Amplitude for trigger-on. :param right_trig: Amplitude for trigger-off. :param start_time: UTCDateTime of the first point in the time-series. :param delta: Sampling interval of the time-series :returns: List of locations. Each location is a dictionary containing all the relevant information. """ locs = [] trigs = trigger.triggerOnset(np.array(max_val), left_trig, right_trig) logging.debug('Found %d triggers.' % len(trigs)) for trig in trigs: i_start = trig[0] i_end = trig[1] + 1 i_max_trig = np.argmax(max_val[i_start:i_end]) + i_start max_trig = max_val[i_max_trig] max_trig_95 = 0.95 * max_trig logging.debug('Max_trig = %.3f, max_trig_95 = %.3f' % (max_trig, max_trig_95)) trigs_95 = trigger.triggerOnset(max_val[i_start:i_end], max_trig_95, max_trig_95) for trig_95 in trigs_95: if i_max_trig >= trig_95[0]+i_start and \ i_max_trig <= trig_95[1]+i_start: loc_dict = {} loc_dict['max_trig'] = max_trig i_start_95 = trig_95[0] + i_start i_end_95 = trig_95[1] + 1 + i_start loc_dict['x_mean'] = np.mean(max_x[i_start_95:i_end_95]) loc_dict['x_sigma'] = np.std(max_x[i_start_95:i_end_95]) loc_dict['y_mean'] = np.mean(max_y[i_start_95:i_end_95]) loc_dict['y_sigma'] = np.std(max_y[i_start_95:i_end_95]) loc_dict['z_mean'] = np.mean(max_z[i_start_95:i_end_95]) loc_dict['z_sigma'] = np.std(max_z[i_start_95:i_end_95]) loc_dict['o_time'] = start_time + i_max_trig * delta loc_dict['o_err_left'] = (i_max_trig - i_start_95) * delta loc_dict['o_err_right'] = (i_end_95 - i_max_trig) * delta locs.append(loc_dict) return locs
def trigger_locations_inner(max_val, max_x, max_y, max_z, left_trig, right_trig, start_time, delta): """ Inner loop of the location process. :param max_val: Time-series of stack-max. :param max_x: Time-series of the x-positions corresponding to stack-max. :param max_y: Time-series of the y-positions corresponding to stack-max. :param max_z: Time-series of the z-positions corresponding to stack-max. :param left_trig: Amplitude for trigger-on. :param right_trig: Amplitude for trigger-off. :param start_time: UTCDateTime of the first point in the time-series. :param delta: Sampling interval of the time-series :returns: List of locations. Each location is a dictionary containing all the relevant information. """ locs = [] trigs = trigger.triggerOnset(np.array(max_val), left_trig, right_trig) logging.debug('Found %d triggers.' % len(trigs)) for trig in trigs: i_start = trig[0] i_end = trig[1]+1 i_max_trig = np.argmax(max_val[i_start:i_end])+i_start max_trig = max_val[i_max_trig] max_trig_95 = 0.95*max_trig logging.debug('Max_trig = %.3f, max_trig_95 = %.3f' % (max_trig, max_trig_95)) trigs_95 = trigger.triggerOnset(max_val[i_start:i_end], max_trig_95, max_trig_95) for trig_95 in trigs_95: if i_max_trig >= trig_95[0]+i_start and \ i_max_trig <= trig_95[1]+i_start: loc_dict = {} loc_dict['max_trig'] = max_trig i_start_95 = trig_95[0]+i_start i_end_95 = trig_95[1]+1+i_start loc_dict['x_mean'] = np.mean(max_x[i_start_95:i_end_95]) loc_dict['x_sigma'] = np.std(max_x[i_start_95:i_end_95]) loc_dict['y_mean'] = np.mean(max_y[i_start_95:i_end_95]) loc_dict['y_sigma'] = np.std(max_y[i_start_95:i_end_95]) loc_dict['z_mean'] = np.mean(max_z[i_start_95:i_end_95]) loc_dict['z_sigma'] = np.std(max_z[i_start_95:i_end_95]) loc_dict['o_time'] = start_time + i_max_trig*delta loc_dict['o_err_left'] = (i_max_trig-i_start_95)*delta loc_dict['o_err_right'] = (i_end_95-i_max_trig)*delta locs.append(loc_dict) return locs
def refTrigger(Waveform,Event,Meta): print Event name = ('%s.%s.%s.%s')%(Waveform[0].stats.network,Waveform[0].stats.station,Waveform[0].stats.location,Waveform[0].stats.channel) i = searchMeta(name,Meta) print i de = locations2degrees(float(Event.lat), float(Event.lon), float(i.lat), float(i.lon)) tt = getTravelTimes(delta=de, depth=float(Event.depth), model='ak135') ptime = 0 if tt[0]['phase_name'] == 'P': ptime = tt[0]['time'] tw = calculateTimeWindows (ptime, Event) stP = readWaveformsPicker (i, tw, Event, ptime) trP = stP[0] cft = recSTALTA(trP.data, int(1 * trP.stats.sampling_rate), int(10 * trP.stats.sampling_rate)) t = triggerOnset(cft,6,1.5) print len(trP),t,type(t) onset = t[0][0]/trP.stats.sampling_rate print 'TRIGGER ',trP.stats.starttime+onset print 'THEORETICAL: ',UTCDateTime(Event.time)+ptime tdiff = (trP.stats.starttime+onset)-(UTCDateTime(Event.time)+ptime) #plotTrigger(trP,cft,6,1.5) print tdiff return tdiff
def normalize(self, method='trace_max', **kwargs): """ Normalizes all trace in the stream. """ logging.info("Normalizing {:} traces with method '{:}'...", len(self.traces), method) if method == 'trace_max': ObspyStream.normalize(self, global_max=False) elif method == 'global_max': ObspyStream.normalize(self, global_max=True) elif method == 'onebit': for tr in self.traces: tr.data = np.sign(tr.data) elif method == 'stalta': _apply = kwargs.get('apply', True) sta = kwargs.get('sta', 3.) lta = kwargs.get('lta', 10.) trigger_on = kwargs.get('trigger_on', 1.1) trigger_off = kwargs.get('trigger_off', 1.0) for tr in self.traces: df = tr.stats['sampling_rate'] _sta = int(sta * df) _lta = int(lta * df) cft = trigger.recSTALTA(tr.data, _sta, _lta) tr.trg = trigger.triggerOnset(cft, trigger_on, trigger_off) if _apply: for on, off in tr.trg: tr.data[on:off] = 0 else: raise ValueError("Unknown method '{:}'".format(method))
def process_gaussian(self, threshold, mu=0.0, sigma=0.1): """ Replace local maxima by a series of dirac and convolve them with a gaussian distribution. Overwrites the waveform. Sets self.proc to 'Gaussian' :param threshold: value over which the convolution is applied :param mu: expected value of the gaussian distribution :param sigma: variance of the gaussian distribution :type threshold: float :type mu: float :type sigma: float """ logging.info("Convolving traces with a gaussian distribution\n") dt = self.dt y = compute_gauss(dt, mu, sigma) # process each trace independently for itr in range(self.stream.count()): tr = self.stream.traces[itr] tr_dirac = np.zeros(len(tr)) trigs = trigger.triggerOnset(tr.data, threshold, threshold) trig_prec = [0, 0] for trig in trigs: if trig[-1] - trig_prec[0] < 50: trig = [trig_prec[0], trig[-1]] istart = trig[0] iend = trig[-1] if istart != iend: imax = np.argmax(tr.data[istart:iend + 1]) + istart else: imax = istart tr_dirac[istart:iend] = 0 tr_dirac[imax] = np.max(tr.data[imax]) trig_prec = trig try: tr.data = np.append( np.convolve(tr_dirac, y, mode='same')[1:], 0) except ValueError: logging.warn('Empty data segment in gaussian convolution') self.stream.traces[itr] = tr self.proc = 'Gaussian'
def process_gaussian(self, threshold, mu=0.0, sigma=0.1): """ Replace local maxima by a series of dirac and convolve them with a gaussian distribution. Overwrites the waveform. Sets self.proc to 'Gaussian' :param threshold: value over which the convolution is applied :param mu: expected value of the gaussian distribution :param sigma: variance of the gaussian distribution :type threshold: float :type mu: float :type sigma: float """ logging.info("Convolving traces with a gaussian distribution\n") dt = self.dt y = compute_gauss(dt, mu, sigma) # process each trace independently for itr in range(self.stream.count()): tr = self.stream.traces[itr] tr_dirac = np.zeros(len(tr)) trigs = trigger.triggerOnset(tr.data, threshold, threshold) trig_prec = [0, 0] for trig in trigs: if trig[-1]-trig_prec[0] < 50: trig = [trig_prec[0], trig[-1]] istart = trig[0] iend = trig[-1] if istart != iend: imax = np.argmax(tr.data[istart:iend+1])+istart else: imax = istart tr_dirac[istart:iend] = 0 tr_dirac[imax] = np.max(tr.data[imax]) trig_prec = trig try: tr.data = np.append(np.convolve(tr_dirac, y, mode='same')[1:], 0) except ValueError: logging.warn('Empty data segment in gaussian convolution') self.stream.traces[itr] = tr self.proc = 'Gaussian'
def trigger(st, opt): """ Run triggering algorithm on a stream of data. st: OBSPy stream of data opt: Options object describing station/run parameters Returns triggered traces as OBSPy trace object """ # Filter the data for triggering st_f = st.copy() st_f = st_f.filter("bandpass", freqmin=opt.fmin, freqmax=opt.fmax, corners=2, zerophase=True) tr = st[0] tr_f = st_f[0] t = tr.stats.starttime cft = classicSTALTA(tr_f.data, opt.swin*opt.samprate, opt.lwin*opt.samprate) on_off = triggerOnset(cft, opt.trigon, opt.trigoff) if len(on_off) > 0: pick = on_off[:,0] # turned off AIC; too slow while testing #pick = np.zeros([len(on_off),1]) #for n in range(len(pick)): # pick[n] = aicpick(st_f, on_off[n, 0], opt) ttime = 0 ind = 0 # Slice out the raw data, not filtered except for highpass to reduce long period drift, # and save the maximum STA/LTA ratio value as trigs.maxratio for n in range(len(on_off)): if on_off[n, 0] > ttime + opt.mintrig*opt.samprate: if ttime is 0 and pick[n] > ttime + opt.ptrig*opt.samprate: ttime = pick[n] trigs = st.slice(t - opt.ptrig + ttime/opt.samprate, t + opt.atrig + ttime/opt.samprate) trigs[ind].stats.maxratio = np.amax(cft[on_off[n,0]:on_off[n,1]]) ind = ind+1 else: ttime = pick[n] if ttime < len(tr.data) - (opt.atrig + opt.ptrig)*opt.samprate: trigs = trigs.append(tr.slice( t - opt.ptrig + ttime/opt.samprate, t + opt.atrig + ttime/opt.samprate)) trigs[ind].stats.maxratio = np.amax(cft[on_off[n,0]:on_off[n,1]]) ind = ind+1 return trigs else: return []
def start_end(tr): """ Returns start and end times of signal using signal 2 noise ratio """ # set noise level as 5th percentile on envelope amplitudes env = envelope(tr.data) env = smooth(env, 100) noise_level = np.percentile(env, 5.0) # trigger t_list = triggerOnset(env, 1.5 * noise_level, 1.5 * noise_level) i_start = t_list[0][0] i_end = t_list[0][1] return i_start, i_end
def trigger( st, lwin=7.0, swin=0.8, trigon=3.0, trigoff=2.0, mintrig=10.0, ptrig=10.0, atrig=20.0): """ Run triggering algorithm on a stream of data. st: OBSPy stream of data lwin: Length of long window for STALTA (default 7.0 s) swin: Length of short window for STALTA (default 0.8 s) trigon: Cutoff ratio for triggering STALTA (default 3.0) trigoff: Cutoff ratio for ending STALTA trigger (default 2.0) mintrig: Minimum spacing between triggers (default 10.0 s) ptrig: Amount to cut prior to trigger (default 10.0 s) atrig: Amount to cut after trigger (default 20.0 s) Returns triggered traces as OBSPy trace object """ tr = st[0] srate = tr.stats.sampling_rate t = tr.stats.starttime cft = classicSTALTA(tr.data, swin*srate, lwin*srate) on_off = triggerOnset(cft, trigon, trigoff) ttime = 0 for n in range(len(on_off)): if on_off[n, 0] > ttime + mintrig*srate: if ttime is 0 and on_off[n, 0] > ttime + ptrig*srate: ttime = on_off[n, 0] trigs = st.slice(t - ptrig + ttime/srate, t + atrig + ttime/srate) else: ttime = on_off[n,0] if ttime < len(tr.data) - (atrig + ptrig)*srate: trigs = trigs.append(tr.slice( t - ptrig + ttime/srate, t + atrig + ttime/srate)) return trigs
def plot_trigger(tr, cft, thr1, thr2): df, npts = tr.stats.sampling_rate, tr.stats.npts t = np.arange(npts, dtype='float32') / df fig = plt.figure(1) #fig = plt.figure(1, figsize=(8, 4)) fig.clf() ax = fig.add_subplot(211) ax.plot(t, tr.data, 'black') ax2 = fig.add_subplot(212, sharex=ax) ax2.plot(t, cft, 'black') onof = np.array(triggerOnset(cft, thr1, thr2)) i, j = ax.get_ylim() try: ax.vlines(onof[:, 0] / df, i, j, color='red', lw=2) ax.vlines(onof[:, 1] / df, i, j, color='blue', lw=2) except IndexError: pass ax2.axhline(thr1, color='red', lw=1, ls='--') ax2.axhline(thr2, color='blue', lw=1, ls='--') fig.canvas.draw() plt.show()
def plot_trigger(tr, cft, thr1, thr2): df, npts = tr.stats.sampling_rate, tr.stats.npts t = np.arange(npts,dtype='float32')/df fig = plt.figure(1) #fig = plt.figure(1, figsize=(8, 4)) fig.clf() ax = fig.add_subplot(211) ax.plot(t, tr.data, 'black') ax2 = fig.add_subplot(212,sharex=ax) ax2.plot(t, cft, 'black') onof = np.array(triggerOnset(cft, thr1, thr2)) i,j = ax.get_ylim() try: ax.vlines(onof[:,0]/df, i, j, color='red', lw = 2) ax.vlines(onof[:,1]/df, i, j, color='blue', lw = 2) except IndexError: pass ax2.axhline(thr1, color='red', lw = 1, ls = '--') ax2.axhline(thr2, color='blue', lw = 1, ls = '--') fig.canvas.draw() plt.show()
from obspy.core import UTCDateTime from obspy.arclink import Client from obspy.signal.trigger import recSTALTA, triggerOnset import matplotlib.pyplot as plt import numpy as np # Retrieve waveforms via ArcLink client = Client(host="erde.geophysik.uni-muenchen.de", port=18001) t = UTCDateTime("2009-08-24 00:19:45") st = client.getWaveform('BW', 'RTSH', '', 'EHZ', t, t + 50) # For convenience tr = st[0] # only one trace in mseed volume df = tr.stats.sampling_rate # Characteristic function and trigger onsets cft = recSTALTA(tr.data, int(2.5 * df), int(10. * df)) on_of = triggerOnset(cft, 3.5, 0.5) # Plotting the results ax = plt.subplot(211) plt.plot(tr.data, 'k') ymin, ymax = ax.get_ylim() plt.vlines(on_of[:, 0], ymin, ymax, color='r', linewidth=2) plt.vlines(on_of[:, 1], ymin, ymax, color='b', linewidth=2) plt.subplot(212, sharex=ax) plt.plot(cft, 'k') plt.hlines([3.5, 0.5], 0, len(cft), color=['r', 'b'], linestyle='--') plt.axis('tight') plt.show()
def stalta_pick(stream, stalen, ltalen, trig_on, trig_off, freqmin=False, freqmax=False, debug=0, show=False): r"""Simple sta-lta (short-term average/long-term average) picker, using \ obspy's stalta routine to generate the characteristic function. Currently very basic quick wrapper, there are many other (better) options \ in obspy, found \ (here)[http://docs.obspy.org/packages/autogen/obspy.signal.trigger.html]. :type stream: obspy.Stream :param stream: The stream to pick on, can be any number of channels. :type stalen: float :param stalen: Length of the short-term average window in seconds. :type ltalen: float :param ltalen: Length of the long-term average window in seconds. :type trig_on: float :param trig_on: sta/lta ratio to trigger a detection/pick :type trig_off: float :param trig_off: sta/lta ratio to turn the trigger off - no further picks\ will be made between exceeding trig_on until trig_off is reached. :type freqmin: float :param freqmin: Low-cut frequency in Hz for bandpass filter :type freqmax: float :param freqmax: High-cut frequency in Hz for bandpass filter :type debug: int :param debug: Debug output level from 0-5. :type show: bool :param show: Show picks on waveform. :returns: list of pick class. """ from obspy.signal.trigger import classicSTALTA, triggerOnset, plotTrigger from Sfile_util import PICK import EQcorrscan_plotting as plotting picks = [] for tr in stream: # We are going to assume, for now, that if the pick is made on the # horizontal channel then it is an S, otherwise we will assume it is # a P-phase: obviously a bad assumption... if tr.stats.channel[-1] == 'Z': phase = 'P' else: phase = 'S' if freqmin and freqmax: tr.detrend('simple') tr.filter('bandpass', freqmin=freqmin, freqmax=freqmax, corners=3, zerophase=True) df = tr.stats.sampling_rate cft = classicSTALTA(tr.data, int(stalen * df), int(ltalen * df)) if debug > 3: plotTrigger(tr, cft, trig_on, trig_off) triggers = triggerOnset(cft, trig_on, trig_off) for trigger in triggers: on = tr.stats.starttime + (trigger[0] / df) # off = tr.stats.starttime + (trigger[1] / df) pick = PICK(station=tr.stats.station, channel=tr.stats.channel, time=on, phase=phase) if debug > 2: print('Pick made:') print(pick) picks.append(pick) # QC picks del pick pick_stations = list(set([pick.station for pick in picks])) for pick_station in pick_stations: station_picks = [pick for pick in picks if pick.station == pick_station] # If P-pick is after S-picks, remove it. p_time = [pick.time for pick in station_picks if pick.phase == 'P'] s_time = [pick.time for pick in station_picks if pick.phase == 'S'] if p_time > s_time: p_pick = [pick for pick in station_picks if pick.phase == 'P'] for pick in p_pick: print('P pick after S pick, removing P pick') picks.remove(pick) if show: plotting.pretty_template_plot(stream, picks=picks, title='Autopicks', size=(8, 9)) return picks
def plotWaves(tr,mode,kmrad,area,chan,nert,aziplot,cft,slta,outdir,rot): tr=decimateStream(tr,10) if slta!="None": tas = slta.split(' ') sta = eval(tas[0]) lta = eval(tas[1]) thrOn=eval(tas[2]) thrOff=eval(tas[3]) else: thrOn=0 thrOff=0 if len(tr) == 0: print "No traces to plot" sys.exit() # normalization to (kmrad[1]-kmrad[0])/len(tr) if(rot == "Y"): normlization=(kmrad[1]-kmrad[0]) / (float(len(tr))/2) * 6 else: normlization=(kmrad[1]-kmrad[0]) / (float(len(tr))/2) * 3 if mode ==2: for i in range(len(tr)): tr[i].data=(tr[i].data/max(abs(tr[i].data)))*normlization else: for i in range(len(tr)): tr[i].data=(tr[i].data/max(abs(tr[i].data))) #number of subplots nr_subpl = len(tr) #starting level for y_axe axe_y_lev=0 xpoM1 = 0 xpoM2 = 0 xpoM3 = 0 # create empty list mykmList=[None]*len(tr) (Amin,Amax)=aziplot.split(' ') Amin=eval(Amin) Amax=eval(Amax) #loop over nr_subpl # define figures to save fig1=plt.figure(1) if nert == "RT" or nert == "NE": fig2=plt.figure(2) fig3=plt.figure(3) for i in range(nr_subpl): # when --redo==Y: header valued of dist and az do not exist try: refaz = tr[i].stats['az'] except: refaz = 0 tr[i].stats['az']=refaz # define controller for plotting azimuth. This allows to plot #Â for example 20-50 or 330-20 cases pltAziController=0 if mode >= 1: if Amin<=Amax: if refaz >= Amin and refaz <= Amax: pltAziController=1 else: if refaz <= Amin and refaz >= Amax: pltAziController=0 else: pltAziController=1 if pltAziController==1: # y-axe # when --redo==Y: header valued of dist and az do not exist try: dist=tr[i].stats['dist'] except: dist= 10 tr[i].stats['dist']=dist # x- axe tBegin = 0 tEnd = tr[i].stats.endtime.timestamp \ - tr[i].stats.starttime.timestamp t = np.arange(tBegin,tEnd,tr[i].stats.delta) nt = len(t) ntr=len(tr[i].data) if nt == ntr: pass elif nt < ntr: tr[i].data=tr[i].data[:nt] elif ntr < nt: t=t[:ntr] # Labels and info xPosText = 0 kPosText = t[len(t)-1]+0 distanceToPlot = "%8.2f" % (dist) nametoPlot = "%-9s" % (tr[i].stats['station']) li = list(tr[i].stats['channel']) if mode == 2: axe_y_lev = dist dista = int(tr[i].stats['dist']) azimu = int(tr[i].stats['az']) textdist = r"$\Phi$ = " + `azimu` + u"\u00b0" xlab = "Time [s]" ylab = "Distance [km]" else: textdist = "" xlab = "Time [s]" ylab = "Nr Traces" # try: if slta!="None": onOff = np.array(triggerOnset(cft[i].data, thrOn, thrOff)) # except IndexError: # pass df = tr[i].stats.sampling_rate if mode == 1: pik=0.5 else: pik=5.0 if li[2] == "Z" and li[0] == chan: if mode == 1: axe_y_lev = xpoM1 plt.figure(1) plt.plot(t,tr[i].data+axe_y_lev,color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'],fontsize=10,backgroundcolor='#99FFFF') #99FFFF plt.text(kPosText, axe_y_lev,textdist ,fontsize=8, backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i=axe_y_lev-pik j=axe_y_lev+pik if slta!="None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM1 += 1 if nert == "RT": if li[2] == "T" and li[0] == chan: if mode == 1: axe_y_lev = xpoM2 plt.figure(2) plt.plot(t,tr[i].data+axe_y_lev,color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'],fontsize=10,backgroundcolor='#99FFFF') plt.text(kPosText, axe_y_lev,textdist ,fontsize=8,backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i=axe_y_lev-pik j=axe_y_lev+pik if slta!="None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM2 += 1 elif li[2] == "R" and li[0] == chan: if mode == 1: axe_y_lev = xpoM3 plt.figure(3) plt.plot(t,tr[i].data+axe_y_lev,color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'],fontsize=10,backgroundcolor='#99FFFF') plt.text(kPosText, axe_y_lev,textdist ,fontsize=8,backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i=axe_y_lev-pik j=axe_y_lev+pik if slta!="None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM3 += 1 else: pass elif nert == "NE": if li[2] == "N" and li[0] == chan: if mode == 1: axe_y_lev = xpoM2 plt.figure(2) plt.plot(t,tr[i].data+axe_y_lev,color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'],fontsize=8,backgroundcolor='#99FFFF') plt.text(kPosText, axe_y_lev,textdist ,fontsize=8,backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i=axe_y_lev-pik j=axe_y_lev+pik if slta!="None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM2 += 1 elif li[2] == "E" and li[0] == chan: if mode == 1: axe_y_lev = xpoM3 plt.figure(3) plt.plot(t,tr[i].data+axe_y_lev,color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'],fontsize=8,backgroundcolor='#99FFFF') plt.text(kPosText, axe_y_lev,textdist ,fontsize=8,backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i=axe_y_lev-pik j=axe_y_lev+pik if slta!="None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM3 += 1 else: pass fig1.savefig(outdir + os.sep + 'plotWavesZ.pdf') if nert == "NE": fig2.savefig(outdir + os.sep + 'plotWavesNS.pdf') fig3.savefig(outdir + os.sep + 'plotWavesEW.pdf') if nert == "RT": fig2.savefig(outdir + os.sep + 'plotWavesT.pdf') fig3.savefig(outdir + os.sep + 'plotWavesR.pdf') plt.show()
def freqtor(yr, mo, dy, hr, mn, sc, duration, ndays, datdir, freq1, freq2, thresholdv, deltaf, masktimes, madtimes, time_thres, distance_thres): #control plot behavior import matplotlib.pylab as plt plt.switch_backend("nbagg") plt.style.use('ggplot') plt.rcParams['figure.figsize'] = 18, 12 #width,then height plt.rcParams['savefig.dpi'] = 80 from obspy import UTCDateTime import numpy as np import matplotlib.dates as mdates import matplotlib.tri as tri from obspy.signal.trigger import recursive_sta_lta as recSTALTA from obspy.signal.trigger import trigger_onset as triggerOnset import copy, os, bisect, scipy, datetime, itertools import pandas as pd #suppress the chained assignment warning pd.options.mode.chained_assignment = None from mpl_toolkits.basemap import Basemap from obspy.taup import TauPyModel as TauP model = TauP(model="iasp91") from obspy.geodetics import locations2degrees as loc2d import Util as Ut import geopy.distance as pydist from obspy.core import read ############################# homedir = '' wb = 5 #which basin # are we working on for station list import maketemplates = 1 tlength = 7200 #nsamples on either side of detection time for template counter = datetime.date(int(yr), int(mo), int(dy)).timetuple().tm_yday edgebuffer = 00 duration = duration + edgebuffer #ndays= 2 #however many days you want to generate images for dayat = int(dy) #set parameter values; k = area threshold for detections: #thresholdv= 2.0 #deltaf = 250.0 nseconds = 7200 npts = int(deltaf * (nseconds + edgebuffer)) fftsize = 256 overlap = 4 hop = fftsize / overlap w = scipy.hanning(fftsize + 1)[:-1] #delta=250.0 if duration == 86400: im = 12 elif duration == 7200: im = 1 else: im = 1 #parse the datetime counter_3char = str(counter).zfill(3) datest = yr + str('-') + mo + str('-') + str(dayat) + str('T') + hr + str( ':') + mn + str('.') + sc tt = UTCDateTime(datest) ##################################################################### # Now start making the detections, in 2 hour data chunks, 1 day at a time print(os.getcwd()) for days in range(ndays): plt.close('all') print(str(tt)) sacyear = str(tt.date.year) sacmonth = str(tt.date.month) sacday = str(tt.date.day) if len(sacmonth) == 1: sacmonth = str(0) + sacmonth if len(sacday) == 1: sacday = str(0) + sacday sacname = str(sacyear) + str(sacmonth) + str(sacday) sacdir = datdir + sacyear + sacmonth + sacday + '/' + sacname + '*.sac' ############################# s = homedir + 'basin%s/' % wb + yr + str('_') + counter_3char if not os.path.exists(s): os.makedirs(s) sz = read(sacdir) sz.sort() sz.detrend() sz.trim(starttime=tt, endtime=tt + duration, pad=True, fill_value=000, nearest_sample=False) sz.filter('highpass', freq=1.0) alltimes = Ut.gettvals(sz[0], sz[1], sz[2]) ############################# ######################### #%% nptsf = edgebuffer * deltaf blockette = 0 d = { 'Contributor': 'NA', 'Latitude': 'NA', 'Longitude': 'NA', 'S1': 'NA', 'S1time': 'NA', 'Magnitude': -999.00, 'mag_error': -999.00, 'cent_er': -999.00, 'Confidence': 0, 'S2': 'NA', 'S3': 'NA', 'S4': 'NA', 'S5': 'NA', 'S2time': 'NA', 'S3time': 'NA', 'S4time': 'NA', 'S5time': 'NA', 'Type': 'Event' } index = [0] df1 = pd.DataFrame(data=d, index=index) stations, latitudes, longitudes, distances = [], [], [], [] snames, latitudes, longitudes = [], [], [] for i in range(len(sz)): snames.append(str(sz[i].stats.station)) latitudes.append(sz[i].stats.sac['stla']) longitudes.append(sz[i].stats.sac['stlo']) latmin = min(latitudes) lonmin = max(longitudes) newlat = np.empty([len(snames)]) newlon = np.empty([len(snames)]) stations = copy.copy(snames) for i in range(len(snames)): reindex = stations.index(snames[i]) newlat[i] = latitudes[reindex] newlon[i] = longitudes[reindex] distances.append( pydist.vincenty([newlat[i], newlon[i]], [latmin, lonmin]).meters) #####this is where maths happends and arrays are created for block in range(im): print(blockette, tt) ll, lo, stalist, vizray, dist = [], [], [], [], [] shorty = 0 for z in range(len(snames)): szdata = sz[z].data[blockette:blockette + npts] # if len(szdata)==npts: vizray.append([]) Bwhite = Ut.w_spec(szdata, deltaf, fftsize, freq1, freq2) vizray[shorty].append(np.sum(Bwhite[:, :], axis=0)) ll.append(newlat[z]) lo.append(newlon[z]) dist.append(distances[z]) stalist.append(snames[z]) shorty = shorty + 1 rays = np.vstack(np.array(vizray)) ix = np.where(np.isnan(rays)) rays[ix] = 0 rayz = np.copy(rays) latudes = copy.copy(ll) longitudes = copy.copy(lo) slist = copy.copy(stalist) #sort the array orders by distance from lomin,latmin for i in range(len(slist)): junk = np.where(np.array(dist) == max(dist)) rayz[i] = rays[junk[0][0]] ll[i] = latudes[junk[0][0]] lo[i] = longitudes[junk[0][0]] slist[i] = stalist[junk[0][0]] dist[junk[0][0]] = -9999999999 timevector = Ut.getfvals(tt, Bwhite, nseconds, edgebuffer) #clean up the array rayz = Ut.saturateArray(rayz, masktimes) ix = np.where(np.isnan(rayz)) rayz[ix] = 0 #determine which level to use as detections 4* MAD levels = [Ut.get_levels(rayz, madtimes)] #get the ANF catalog events and get closest station localE, globalE, closesti = Ut.getCatalogData(tt, nseconds, lo, ll) #closesti = np.flipud(closesti) #unstructured triangular mesh with stations as verticies, mask out the long edges triang = tri.Triangulation(lo, ll) mask, edgeL = Ut.long_edges(lo, ll, triang.triangles) triang.set_mask(mask) kval = Ut.get_k(lo, ll, triang.triangles, thresholdv) #%% #get contour areas by frame av,aa,xc,yc,centroids,ctimes,ctimesdate,junkx,junky=[],[],[],[],[],[],[],[],[] for each in range(len(rayz[0, :])): # refiner = tri.UniformTriRefiner(triang) # tri_refi, z_refi = refiner.refine_field(rayz[0:,each], subdiv=0) cs = plt.tricontour(triang, rayz[0:, each], mask=mask, levels=levels, colors='c', linewidths=[1.5]) contour = cs.collections[0].get_paths() for alls in range(len(contour)): vs = contour[alls].vertices a = Ut.PolygonArea(vs) aa.append(a) x = vs[:, 0] y = vs[:, 1] points = np.array([x, y]) points = points.transpose() sx = sy = sL = 0 for i in range( len(points)): # counts from 0 to len(points)-1 x0, y0 = points[ i - 1] # in Python points[-1] is last element of points x1, y1 = points[i] L = ((x1 - x0)**2 + (y1 - y0)**2)**0.5 sx += (x0 + x1) / 2 * L sy += (y0 + y1) / 2 * L sL += L xc.append(sx / sL) yc.append(sy / sL) if aa != []: idi = np.where(np.array(aa) > kval) filler = np.where(np.array(aa) <= kval) chained = itertools.chain.from_iterable(filler) chain = itertools.chain.from_iterable(idi) idi = list(chain) filler = list(chained) for alls in range(len(aa)): if aa[alls] > kval: centroids.append([xc[idi[0]], yc[idi[0]]]) ctimes.append(timevector[each]) ctimesdate.append(timevector[each]) av.append(aa[idi[0]]) else: centroids.append([0, 0]) ctimes.append(timevector[each]) ctimesdate.append(timevector[each]) av.append(0) aa, yc, xc = [], [], [] #%% Filter peaks in av above threshold by time and distance to remove redundant. idxx, idx, regionals, localev = [], [], [], [] coordinatesz = np.transpose(centroids) avz = av abovek = np.where(np.array(avz) > 0) idxx = abovek[0] iii = [] for i in range(len(abovek[0]) - 1): junk = ctimes[idxx[i + 1]] - ctimes[idxx[i]] junk1 = centroids[idxx[i]] junk2 = centroids[idxx[i + 1]] if junk.seconds < time_thres and pydist.vincenty( junk2, junk1).meters < distance_thres: iii.append(idxx[i + 1]) idxx = set(idxx) - set(iii) idxx = list(idxx) idxx.sort() idx = idxx ltxlocal, ltxlocalexist = [], [] ltxglobal = [] ltxglobalexist = [] doubles, localev = [], [] dit2 = [] #%% #if there are no picks but cataloged events exist, make null arrays if len(idx) == 0 and len(globalE) > 0: ltxglobalexist = np.ones(len(globalE)) if len(idx) == 0 and len(localE) > 0: ltxlocalexist = np.ones(len(localE)) #try to match detections with known catalog events based on time and location if len(idx) > 0: distarray = [] dmin = np.zeros([5]) dval = np.zeros([5]) closestl = np.empty([len(idx), 5]) dvals = np.empty([len(idx), 5]) closestl = closestl.astype(np.int64) for i in range(len(idx)): #find distance to the 5 nearest stations and save them for plotting templates for each in range(len(ll)): distarray.append( pydist.vincenty([ coordinatesz[1][idx[i]], coordinatesz[0][idx[i]] ], [ll[each], lo[each]]).meters) for all5 in range(5): dmin[all5] = np.argmin(distarray) dmin = dmin.astype(np.int64) dval[all5] = distarray[dmin[all5]] distarray[dmin[all5]] = 9e10 closestl[i][:] = dmin dvals[i][:] = dval dmin = np.zeros_like(dmin) distarray = [] #get timeseries for this pick stg = slist[closestl[i][0]] timeindex = bisect.bisect_left(alltimes, ctimes[idx[i]]) sss = sz.select(station=stg) av = sss[0].data[timeindex - tlength:timeindex + tlength] cf = recSTALTA(av, int(40), int(1200)) peaks = triggerOnset(cf, 3, .2) #get rid of peaks that are way off LTX times peaksi = [] for peak in peaks: peak = peak[0] junk = alltimes[timeindex] - alltimes[timeindex - tlength + peak] if abs(junk.seconds) > 45: peaksi.append(i) peaks = np.delete(peaks, peaksi, axis=0) #look for overlap with ANF global for j in range(len(globalE)): #get distance between stations and depth for theoretical ttime calc # the time buffers are somewhat arbitrary dep = globalE.depth[j] dit = loc2d(centroids[idx[i]][1], centroids[idx[i]][0], globalE.Lat[j], globalE.Lon[j]) arrivals = model.get_travel_times(dep, dit, phase_list=['P']) #if no calculated tt but sta/lta peak if len(arrivals) == 0 and len(peaks) != 0: junk = UTCDateTime( alltimes[timeindex - tlength + peaks[0][0]]) - UTCDateTime( globalE.DateString[j]) if junk > -40 and junk < 40: doubles.append(idx[i]) ltxglobal.append( UTCDateTime(alltimes[timeindex - tlength + peaks[0][0]])) ltxglobalexist.append(0) else: ltxglobalexist.append(1) #if no calculated tt and no sta/lta peak use ltx time elif len(arrivals) == 0 and len(peaks) == 0: junk = UTCDateTime( alltimes[timeindex]) - UTCDateTime( globalE.DateString[j]) if junk > -40 and junk < 40: doubles.append(idx[i]) ltxglobal.append( UTCDateTime(alltimes[timeindex])) ltxglobalexist.append(0) else: ltxglobalexist.append(1) #if there are calculated arrivals and sta/lta peak elif len(peaks) != 0: junk = UTCDateTime( alltimes[timeindex - tlength + peaks[0][0]] ) - (UTCDateTime(globalE.DateString[j]) + datetime.timedelta(seconds=arrivals[0].time)) if junk > -30 and junk < 30: doubles.append(idx[i]) ltxglobal.append( UTCDateTime(alltimes[timeindex - tlength + peaks[0][0]])) ltxglobalexist.append(0) else: ltxglobalexist.append(1) #if there are calculated arrivals and no sta/lta peaks else: junk = UTCDateTime(alltimes[timeindex]) - ( UTCDateTime(globalE.DateString[j]) + datetime.timedelta(seconds=arrivals[0].time)) if junk > -60 and junk < 60: doubles.append(idx[i]) ltxglobalexist.append(0) else: ltxglobalexist.append(1) #look for overlap with ANF local if len(localE) > 0 and len(peaks) != 0: for eachlocal in range(len(localE)): #junk= UTCDateTime(alltimes[timeindex-tlength+peaks[0][0]]) - UTCDateTime(localE.DateString[eachlocal]) #took this out because faulty picks disassociated too many events #calculate with LTX pick time instead dep = localE.depth[eachlocal] dit = pydist.vincenty( [centroids[idx[i]][1], centroids[idx[i]][0]], [localE.Lat[eachlocal], localE.Lon[eachlocal] ]).meters junk = UTCDateTime( alltimes[timeindex]) - UTCDateTime( localE.DateString[eachlocal]) if junk > -60 and junk < 60 and dit < 2.0 * edgeL: localev.append(idx[i]) ltxlocal.append( UTCDateTime(alltimes[timeindex - tlength + peaks[0][0]])) ltxlocalexist.append(0) else: ltxlocalexist.append(1) if len(localE) > 0 and len(peaks) == 0: for eachlocal in range(len(localE)): dep = localE.depth[eachlocal] dit = pydist.vincenty( [centroids[idx[i]][1], centroids[idx[i]][0]], [localE.Lat[eachlocal], localE.Lon[eachlocal] ]).meters junk = UTCDateTime( alltimes[timeindex]) - UTCDateTime( localE.DateString[eachlocal]) if junk > -60 and junk < 60 and dit < 2.0 * edgeL: localev.append(idx[i]) ltxlocal.append( UTCDateTime(alltimes[timeindex])) ltxlocalexist.append(0) else: ltxlocalexist.append(1) #if it goes with a local- don't let it go with a double too dupe = [] for dl in range(len(doubles)): if localev.count(doubles[dl]) > 0: dupe.append(doubles[dl]) for repeats in range(len(dupe)): doubles.remove(dupe[repeats]) # detections = [] detections = set(idx) #-set(doubles) detections = list(detections) #or if there are more locals LTX detections than ANF locals, fix it #by assuming double pick on closest pair pdist = [] if len(localev) > len(localE): for i in range(len(localev) - 1): pdist.append(localev[i + 1] - localev[i]) junk = np.where(pdist == min(pdist)) localev.pop(junk[0][0] + 1) #detections.remove(localev[junk[0][0]+1]) detections.sort() idx = detections dtype, cents = Ut.markType(detections, centroids, localev, localE, ctimes, doubles) #get the nearest station also for cataloged events closestd = np.zeros([len(doubles)]) distarray = np.zeros([len(ll)]) for event in range(len(doubles)): for each in range(len(ll)): distarray[each] = pydist.vincenty([ coordinatesz[1][doubles[event]], coordinatesz[0][doubles[event]] ], [ll[each], lo[each]]).meters finder = np.argmin(distarray) closestd[event] = finder distarray[finder] = 9e10 closestd = closestd.astype(np.int64) closestp = [] distarray = np.zeros([len(ll)]) for event in range(len(localev)): for each in range(len(ll)): distarray[each] = pydist.vincenty([ coordinatesz[1][localev[event]], coordinatesz[0][localev[event]] ], [ll[each], lo[each]]).meters finder = np.argmin(distarray) closestp.append(finder) distarray[finder] = 9e10 #%%#save templates from this round of picks to verify on closest station ss = str(tt) ss = ss[0:13] if 'detections' in locals(): index = range(len(detections)) else: index = [0] detections = [] df = pd.DataFrame(data=d, index=index) if maketemplates == 1 and len(detections) > 0: ptimes, confidence = [], [] magi = np.zeros_like(dvals) dum = 0 for fi in range(len(detections)): if localev.count(detections[fi]) == 0: df.Contributor[fi] = 'LTX' else: df.Contributor[fi] = 'ANF,LTX' allmags = [ localE.ms[dum], localE.mb[dum], localE.ml[dum] ] df.Magnitude[fi] = np.max(allmags) dum = dum + 1 #df.Latitude[fi] = coordinatesz[1][detections[fi]] #df.Longitude[fi]=coordinatesz[0][detections[fi]] df.Latitude[fi] = cents[fi][0] df.Longitude[fi] = cents[fi][1] df.Type[fi] = dtype[fi] plt.cla() ax = plt.gca() timeindex = bisect.bisect_left(alltimes, (ctimes[detections[fi]])) sss = np.zeros([5, tlength * 2]) for stas in range(5): stg = slist[closestl[fi][stas]] tr = sz.select(station=stg) if ctimes[detections[fi]] - datetime.timedelta( seconds=80) < tt.datetime: sss[stas][tlength:] = tr[0].data[ timeindex:timeindex + tlength] elif ctimes[detections[fi]] + datetime.timedelta( seconds=80) > tt.datetime + datetime.timedelta( seconds=nseconds + edgebuffer): sss[stas][0:tlength] = tr[0].data[ timeindex - tlength:timeindex] else: sss[stas][:] = tr[0].data[timeindex - tlength:timeindex + tlength] sss = np.nan_to_num(sss) stg = slist[closestl[0][0]] #plt.figure(fi) peak = None plt.suptitle('nearest station:' + stg + ' ' + str(ctimes[detections[fi]]) + 'TYPE = ' + dtype[fi]) for plots in range(5): plt.subplot(5, 1, plots + 1) cf = recSTALTA(sss[plots][:], int(80), int(500)) peaks = triggerOnset(cf, 3, .1) peaksi = [] dummy = 0 for pk in peaks: endi = pk[1] peak = pk[0] mcdur = alltimes[timeindex - tlength + endi] - alltimes[timeindex - tlength + peak] mdur = mcdur.total_seconds() if alltimes[timeindex] > alltimes[timeindex - tlength + peak]: junk = alltimes[timeindex] - alltimes[ timeindex - tlength + peak] else: junk = alltimes[timeindex - tlength + peak] - alltimes[timeindex] if (junk.seconds) > 40: peaksi.append(dummy) dummy = dummy + 1 peaks = np.delete(peaks, peaksi, axis=0) sss[plots] = np.nan_to_num(sss[plots]) #if the channel is blank underflow problems occur plotting station name sss = np.round(sss, decimals=10) plt.plot( Ut.templatetimes(alltimes[timeindex], tlength, deltaf), sss[plots][:], 'black') plt.axvline(x=alltimes[timeindex]) plt.text(alltimes[timeindex], 0, slist[closestl[fi][plots]], color='red', fontsize=20) plt.axis('tight') for arc in range(len(peaks)): plt.axvline(x=alltimes[timeindex - tlength - 10 + peaks[arc][0]], color='orange') plt.axvline(x=alltimes[timeindex - tlength - 10 + peaks[arc][1]], color='purple') if len(peaks) > 0: ptimes.append( UTCDateTime(alltimes[timeindex - tlength - 10 + peaks[0][0]])) confidence.append(len(peaks)) magi[fi][plots] = ( -2.25 + 2.32 * np.log10(mdur) + 0.0023 * dvals[fi][plots] / 1000) #magi[fi][plots]=(1.86*np.log10(mdur)-0.85) else: ptimes.append(UTCDateTime(alltimes[timeindex])) confidence.append(2) magi = np.round(magi, decimals=2) magii = pd.DataFrame(magi) magu = magii[magii != 0] if df.Contributor[fi] == 'ANF,LTX': df.mag_error[fi] = np.round(np.max(allmags) - np.mean(magu, axis=1)[fi], decimals=2) df.Magnitude[fi] = str( str(df.Magnitude[fi]) + ',' + str(np.round(np.mean(magu, axis=1)[fi], decimals=2))) df.cent_er[fi] = np.round(pydist.vincenty([ coordinatesz[1][detections[fi]], coordinatesz[0][detections[fi]] ], [cents[fi][0], cents[fi][1]]).meters / 1000.00, decimals=2) else: df.Magnitude[fi] = np.round(np.mean(magu, axis=1)[fi], decimals=2) #ptimes = np.reshape(ptimes,[len(ptimes)/5,5]) df.S1[fi] = slist[closestl[fi][0]] df.S1time[fi] = ptimes[0] df.S2[fi] = slist[closestl[fi][1]] df.S2time[fi] = (ptimes[1]) df.S3[fi] = slist[closestl[fi][2]] df.S3time[fi] = (ptimes[2]) df.S4[fi] = slist[closestl[fi][3]] df.S4time[fi] = (ptimes[3]) df.S5[fi] = slist[closestl[fi][4]] df.S5time[fi] = (ptimes[4]) #df.Confidence[fi]= confidence[0] ptimes = [] if dtype[fi] == 'earthquake': svname = homedir + str(s) + "/image" + ss[ 11:13] + "_pick_" + str(fi + 1) + ".png" plt.savefig(svname, format='png') plt.clf() #%% df1 = [df1, df] df1 = pd.concat(df1) ################################################ #%% fig = plt.figure() plt.cla() ax = plt.gca() #plot it all for i in range(len(detections)): if localev.count(detections[i]) == 1: color = 'c' elif doubles.count(detections[i]) == 1: color = 'blue' else: color = 'white' if dtype[i] == 'blast': facecolor = 'none' else: facecolor = color plt.scatter(mdates.date2num(ctimes[detections[i]]), closestl[i][0], s=200, color=color, facecolor=facecolor) # for i in range(len(globalE)): plt.scatter(mdates.date2num(UTCDateTime(globalE.time[i])), 1, s=100, color='b', alpha=.8) for i in range(len(localE)): plt.scatter(mdates.date2num(UTCDateTime(localE.time[i])), closesti[i], s=100, facecolor='c', edgecolor='grey') plt.imshow(np.flipud(rayz), extent=[ mdates.date2num(tt.datetime), mdates.date2num( (tt + nseconds + edgebuffer).datetime), 0, len(slist) ], aspect='auto', interpolation='nearest', cmap='bone', vmin=np.min(rayz) / 2, vmax=np.max(rayz) * 2) ax.set_adjustable('box-forced') ax.xaxis_date() plt.yticks(np.arange(len(ll))) ax.set_yticklabels(slist) tdate = yr + '-' + mo + '-' + str(dayat).zfill(2) plt.title(tdate) ax.grid(color='black') ss = str(tt) ss = ss[0:13] kurs = "%s/" % s + "%s.png" % ss svpath = homedir + kurs plt.savefig(svpath, format='png') plt.close() #%% blockette = blockette + (npts - nptsf) tt = tt + nseconds detections = [] localev = [] doubles = [] ############################# svpath = homedir + '%s' % s + "/picktable.html" df1.to_html(open(svpath, 'w'), index=False) svpath = homedir + '%s' % s + "/picktable.pkl" df1.to_pickle(svpath) dayat = dayat + 1 counter = counter + 1 counter_3char = str(counter).zfill(3) ############################# if __name__ == '__main__': detection_function()
def plotWaves(tr, mode, kmrad, area, chan, nert, aziplot, cft, slta, outdir, rot): tr = decimateStream(tr, 10) if slta != "None": tas = slta.split(' ') sta = eval(tas[0]) lta = eval(tas[1]) thrOn = eval(tas[2]) thrOff = eval(tas[3]) else: thrOn = 0 thrOff = 0 if len(tr) == 0: print "No traces to plot" sys.exit() # normalization to (kmrad[1]-kmrad[0])/len(tr) if (rot == "Y"): normlization = (kmrad[1] - kmrad[0]) / (float(len(tr)) / 2) * 6 else: normlization = (kmrad[1] - kmrad[0]) / (float(len(tr)) / 2) * 3 if mode == 2: for i in range(len(tr)): tr[i].data = (tr[i].data / max(abs(tr[i].data))) * normlization else: for i in range(len(tr)): tr[i].data = (tr[i].data / max(abs(tr[i].data))) #number of subplots nr_subpl = len(tr) #starting level for y_axe axe_y_lev = 0 xpoM1 = 0 xpoM2 = 0 xpoM3 = 0 # create empty list mykmList = [None] * len(tr) (Amin, Amax) = aziplot.split(' ') Amin = eval(Amin) Amax = eval(Amax) #loop over nr_subpl # define figures to save fig1 = plt.figure(1) if nert == "RT" or nert == "NE": fig2 = plt.figure(2) fig3 = plt.figure(3) for i in range(nr_subpl): # when --redo==Y: header valued of dist and az do not exist try: refaz = tr[i].stats['az'] except: refaz = 0 tr[i].stats['az'] = refaz # define controller for plotting azimuth. This allows to plot #Â for example 20-50 or 330-20 cases pltAziController = 0 if mode >= 1: if Amin <= Amax: if refaz >= Amin and refaz <= Amax: pltAziController = 1 else: if refaz <= Amin and refaz >= Amax: pltAziController = 0 else: pltAziController = 1 if pltAziController == 1: # y-axe # when --redo==Y: header valued of dist and az do not exist try: dist = tr[i].stats['dist'] except: dist = 10 tr[i].stats['dist'] = dist # x- axe tBegin = 0 tEnd = tr[i].stats.endtime.timestamp \ - tr[i].stats.starttime.timestamp t = np.arange(tBegin, tEnd, tr[i].stats.delta) nt = len(t) ntr = len(tr[i].data) if nt == ntr: pass elif nt < ntr: tr[i].data = tr[i].data[:nt] elif ntr < nt: t = t[:ntr] # Labels and info xPosText = 0 kPosText = t[len(t) - 1] + 0 distanceToPlot = "%8.2f" % (dist) nametoPlot = "%-9s" % (tr[i].stats['station']) li = list(tr[i].stats['channel']) if mode == 2: axe_y_lev = dist dista = int(tr[i].stats['dist']) azimu = int(tr[i].stats['az']) textdist = r"$\Phi$ = " + ` azimu ` + u"\u00b0" xlab = "Time [s]" ylab = "Distance [km]" else: textdist = "" xlab = "Time [s]" ylab = "Nr Traces" # try: if slta != "None": onOff = np.array(triggerOnset(cft[i].data, thrOn, thrOff)) # except IndexError: # pass df = tr[i].stats.sampling_rate if mode == 1: pik = 0.5 else: pik = 5.0 if li[2] == "Z" and li[0] == chan: if mode == 1: axe_y_lev = xpoM1 plt.figure(1) plt.plot(t, tr[i].data + axe_y_lev, color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'], fontsize=10, backgroundcolor='#99FFFF') #99FFFF plt.text(kPosText, axe_y_lev, textdist, fontsize=8, backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i = axe_y_lev - pik j = axe_y_lev + pik if slta != "None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM1 += 1 if nert == "RT": if li[2] == "T" and li[0] == chan: if mode == 1: axe_y_lev = xpoM2 plt.figure(2) plt.plot(t, tr[i].data + axe_y_lev, color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'], fontsize=10, backgroundcolor='#99FFFF') plt.text(kPosText, axe_y_lev, textdist, fontsize=8, backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i = axe_y_lev - pik j = axe_y_lev + pik if slta != "None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM2 += 1 elif li[2] == "R" and li[0] == chan: if mode == 1: axe_y_lev = xpoM3 plt.figure(3) plt.plot(t, tr[i].data + axe_y_lev, color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'], fontsize=10, backgroundcolor='#99FFFF') plt.text(kPosText, axe_y_lev, textdist, fontsize=8, backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i = axe_y_lev - pik j = axe_y_lev + pik if slta != "None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM3 += 1 else: pass elif nert == "NE": if li[2] == "N" and li[0] == chan: if mode == 1: axe_y_lev = xpoM2 plt.figure(2) plt.plot(t, tr[i].data + axe_y_lev, color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'], fontsize=8, backgroundcolor='#99FFFF') plt.text(kPosText, axe_y_lev, textdist, fontsize=8, backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i = axe_y_lev - pik j = axe_y_lev + pik if slta != "None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM2 += 1 elif li[2] == "E" and li[0] == chan: if mode == 1: axe_y_lev = xpoM3 plt.figure(3) plt.plot(t, tr[i].data + axe_y_lev, color='k') plt.text(xPosText, axe_y_lev, tr[i].stats['station'], fontsize=8, backgroundcolor='#99FFFF') plt.text(kPosText, axe_y_lev, textdist, fontsize=8, backgroundcolor='#F0FFFF') plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tr[i].stats['channel']) i = axe_y_lev - pik j = axe_y_lev + pik if slta != "None": try: plt.vlines(onOff[:, 0] / df, i, j, color='r', lw=2, label="Trigger On") except IndexError: pass xpoM3 += 1 else: pass fig1.savefig(outdir + os.sep + 'plotWavesZ.pdf') if nert == "NE": fig2.savefig(outdir + os.sep + 'plotWavesNS.pdf') fig3.savefig(outdir + os.sep + 'plotWavesEW.pdf') if nert == "RT": fig2.savefig(outdir + os.sep + 'plotWavesT.pdf') fig3.savefig(outdir + os.sep + 'plotWavesR.pdf') plt.show()
def trigger(st, rtable, opt): """ Run triggering algorithm on a stream of data. st: OBSPy stream of data rtable: Repeater table contains reference time of previous trigger in samples opt: Options object describing station/run parameters Returns triggered traces as OBSPy trace object updates ptime for next run """ # Filter the data for triggering st_f = st.copy() st_f = st_f.filter("bandpass", freqmin=opt.fmin, freqmax=opt.fmax, corners=2, zerophase=True) tr = st[0] tr_f = st_f[0] t = tr.stats.starttime cft = classicSTALTA(tr_f.data, opt.swin*opt.samprate, opt.lwin*opt.samprate) on_off = triggerOnset(cft, opt.trigon, opt.trigoff) if len(on_off) > 0: pick = on_off[:,0] ind = 0 # Slice out the raw data (not filtered except for highpass to reduce long period # drift) and save the maximum STA/LTA ratio value for # use in orphan expiration # Convert ptime from time of last trigger to samples before start time if rtable.attrs.ptime: ptime = (UTCDateTime(rtable.attrs.ptime) - t)*opt.samprate else: ptime = -opt.mintrig*opt.samprate for n in range(len(pick)): ttime = pick[n] if (ttime >= opt.atrig*opt.samprate) and (ttime >= ptime + opt.mintrig*opt.samprate) and (ttime < len(tr.data) - 2*opt.atrig*opt.samprate): ptime = ttime if ind is 0: # Slice and save as first trace trigs = st.slice(t - opt.ptrig + ttime/opt.samprate, t + opt.atrig + ttime/opt.samprate) trigs[ind].stats.maxratio = np.amax(cft[on_off[n,0]:(on_off[n,1]+1)]) ind = ind+1 else: # Slice and append to previous traces trigs = trigs.append(tr.slice( t - opt.ptrig + ttime/opt.samprate, t + opt.atrig + ttime/opt.samprate)) trigs[ind].stats.maxratio = np.amax(cft[on_off[n,0]:(on_off[n,1]+1)]) ind = ind+1 if ind is 0: rtable.attrs.ptime = (t + len(tr.data)/opt.samprate - opt.mintrig*opt.samprate).isoformat() return [] else: rtable.attrs.ptime = (t + ptime/opt.samprate).isoformat() return trigs else: rtable.attrs.ptime = (t + len(tr.data)/opt.samprate - opt.mintrig*opt.samprate).isoformat() return []
def stalta_pick(stream, stalen, ltalen, trig_on, trig_off, freqmin=False, freqmax=False, debug=0, show=False): r"""Simple sta-lta (short-term average/long-term average) picker, using \ obspy's stalta routine to generate the characteristic function. Currently very basic quick wrapper, there are many other (better) options \ in obspy, found \ (here)[http://docs.obspy.org/packages/autogen/obspy.signal.trigger.html]. :type stream: obspy.Stream :param stream: The stream to pick on, can be any number of channels. :type stalen: float :param stalen: Length of the short-term average window in seconds. :type ltalen: float :param ltalen: Length of the long-term average window in seconds. :type trig_on: float :param trig_on: sta/lta ratio to trigger a detection/pick :type trig_off: float :param trig_off: sta/lta ratio to turn the trigger off - no further picks\ will be made between exceeding trig_on until trig_off is reached. :type freqmin: float :param freqmin: Low-cut frequency in Hz for bandpass filter :type freqmax: float :param freqmax: High-cut frequency in Hz for bandpass filter :type debug: int :param debug: Debug output level from 0-5. :type show: bool :param show: Show picks on waveform. :returns: list of pick class. """ from obspy.signal.trigger import classicSTALTA, triggerOnset, plotTrigger from sfile_util import PICK import EQcorrscan_plotting as plotting picks = [] for tr in stream: # We are going to assume, for now, that if the pick is made on the # horizontal channel then it is an S, otherwise we will assume it is # a P-phase: obviously a bad assumption... if tr.stats.channel[-1] == 'Z': phase = 'P' else: phase = 'S' if freqmin and freqmax: tr.detrend('simple') tr.filter('bandpass', freqmin=freqmin, freqmax=freqmax, corners=3, zerophase=True) df = tr.stats.sampling_rate cft = classicSTALTA(tr.data, int(stalen * df), int(ltalen * df)) if debug > 3: plotTrigger(tr, cft, trig_on, trig_off) triggers = triggerOnset(cft, trig_on, trig_off) for trigger in triggers: on = tr.stats.starttime + (trigger[0] / df) # off = tr.stats.starttime + (trigger[1] / df) pick = PICK(station=tr.stats.station, channel=tr.stats.channel, time=on, phase=phase) if debug > 2: print('Pick made:') print(pick) picks.append(pick) # QC picks del pick pick_stations = list(set([pick.station for pick in picks])) for pick_station in pick_stations: station_picks = [ pick for pick in picks if pick.station == pick_station ] # If P-pick is after S-picks, remove it. p_time = [pick.time for pick in station_picks if pick.phase == 'P'] s_time = [pick.time for pick in station_picks if pick.phase == 'S'] if p_time > s_time: p_pick = [pick for pick in station_picks if pick.phase == 'P'] for pick in p_pick: print('P pick after S pick, removing P pick') picks.remove(pick) if show: plotting.pretty_template_plot(stream, picks=picks, title='Autopicks', size=(8, 9)) return picks
def refTrigger(self, RefWaveform): Config = self.Config cfg = ConfigObj(dict=Config) name = ('%s.%s.%s.%s') % ( RefWaveform[0].stats.network, RefWaveform[0].stats.station, RefWaveform[0].stats.location, RefWaveform[0].stats.channel) i = self.searchMeta(name, self.StationMeta) de = loc2degrees(self.Origin, i) ptime = 0 Phase = cake.PhaseDef('P') model = cake.load_model() if cfg.colesseo_input() == True: arrivals = model.arrivals([de, de], phases=Phase, zstart=self.Origin.depth, zstop=0.) else: arrivals = model.arrivals([de, de], phases=Phase, zstart=self.Origin.depth * km, zstop=0.) try: ptime = arrivals[0].t except: arrivals = model.arrivals([de, de], phases=Phase, zstart=o_depth * km - 0.1) ptime = arrivals[0].t phasename = ('%sphase') % (os.path.basename(self.AF)) if ptime == 0: print '\033[31mAvailable phases for reference station %s in range %f deegree\033[0m' % ( i, de) print '\033[31m' + '|'.join( [str(item['phase_name']) for item in tt]) + '\033[0m' print '\033[31myou tried phase %s\033[0m' % ( self.Config[phasename]) raise Exception("\033[31mILLEGAL: phase definition\033[0m") tw = self.calculateTimeWindows(ptime) if cfg.pyrocko_download() == True: stP = self.readWaveformsPicker_pyrocko(i, tw, self.Origin, ptime) elif cfg.colesseo_input() == True: stP = self.readWaveformsPicker_colos(i, tw, self.Origin, ptime) else: stP = self.readWaveformsPicker(i, tw, self.Origin, ptime) refuntouchname = os.path.basename(self.AF) + '-refstation-raw.mseed' stP.write(os.path.join(self.EventPath, refuntouchname), format='MSEED', byteorder='>') stP.filter("bandpass", freqmin=float(self.Config['refstationfreqmin']), freqmax=float(self.Config['refstationfreqmax'])) stP.trim(tw['xcorrstart'], tw['xcorrend']) trP = stP[0] trP.stats.starttime = UTCDateTime(3600) refname = os.path.basename(self.AF) + '-refstation-filtered.mseed' trP.write(os.path.join(self.EventPath, refname), format='MSEED', byteorder='>') sta = float(self.Config['refsta']) lta = float(self.Config['reflta']) cft = recSTALTA(trP.data, int(sta * trP.stats.sampling_rate), int(lta * trP.stats.sampling_rate)) t = triggerOnset(cft, lta, sta) try: onset = t[0][0] / trP.stats.sampling_rate print 'ONSET ', onset except: onset = self.mintforerun trigger = trP.stats.starttime + onset print 'TRIGGER ', trigger print 'THEORETICAL: ', UTCDateTime(3600) + self.mintforerun tdiff = (trP.stats.starttime + onset) - (UTCDateTime(3600) + self.mintforerun) print 'TDIFF: ', tdiff refp = UTCDateTime(self.Origin.time) + ptime reftriggeronset = refp + onset - self.mintforerun if int(self.Config['autoxcorrcorrectur']) == 1: try: refmarkername = os.path.join(self.EventPath, ('%s-marker') % (os.path.basename(self.AF))) fobjrefmarkername = open(refmarkername, 'w') fobjrefmarkername.write( '# Snuffler Markers File Version 0.2\n') fobjrefmarkername.write(( 'phase: %s 0 %s None None None XWStart None False\n' ) % (tw['xcorrstart'].strftime('%Y-%m-%d %H:%M:%S.%f'), name)) fobjrefmarkername.write(( 'phase: %s 0 %s None None None XWEnd None False\n' ) % (tw['xcorrend'].strftime('%Y-%m-%d %H:%M:%S.%f'), name)) fobjrefmarkername.write(( 'phase: %s 1 %s None None None TheoP None False\n' ) % (refp.strftime('%Y-%m-%d %H:%M:%S.%f'), name)) fobjrefmarkername.write(( 'phase: %s 3 %s None None None XTrig None False' ) % (reftriggeronset.strftime('%Y-%m-%d %H:%M:%S.%f'), name)) fobjrefmarkername.close() cmd = 'snuffler %s --markers=%s&' % (os.path.join( self.EventPath, refuntouchname), refmarkername) os.system(cmd) thrOn = float(self.Config['reflta']) # 4 thrOff = float(self.Config['refsta']) # 0.7 plotTrigger(trP, cft, thrOn, thrOff) selection = float( raw_input('Enter self picked phase in seconds: ')) tdiff = selection - self.mintforerun refname = os.path.basename(self.AF) + '-shift.mseed' trP.stats.starttime = trP.stats.starttime - selection trP.write(os.path.join(self.EventPath, refname), format='MSEED') except: selection = 0. refname = os.path.basename(self.AF) + '-shift.mseed' trP.stats.starttime = trP.stats.starttime - selection - self.mintforerun trP.write(os.path.join(self.EventPath, refname), format='MSEED') ''' tdiff = 0 trigger = trP.stats.starttime ''' To = Trigger(name, trigger, os.path.basename(self.AF), tdiff) return tdiff, To
def picker(st): """docstring for picker""" s_picks=[np.nan]*2 df = st[0].stats.sampling_rate npts = st[0].stats.npts for i,cmp in enumerate(['L','Q','T']): tmp=st.select(component=cmp) trace=tmp[0] # calculate cft of zDetect for 20 sample window cft=zDetect(trace,20) #mincft=min(cft) maxcft=max(cft) #meancft=mean(cft) #print mincft,maxcft,(maxcft+mincft)/2,meancft if cmp=='L': # P-trace: care less about this one, go ahead and pick picks=triggerOnset(cft,0,0) # plotTrigger(trace, cft, 0, 0) p_pick=np.nan for pick,end in picks: if npts-pick<100: break else: stcut = st.copy() # cut trace from pick to 100 samples past pick startcut=stcut[0].stats.starttime+dt.timedelta(seconds= pick/df) endcut=startcut + dt.timedelta(seconds=100/df) stcut = stcut.slice(startcut,endcut) stcut.sort() azi,inc,lin,plan=flinn(stcut) #print "inc, lin =", inc, lin if inc<40 and lin>0.6: # good enough for a p-pick p_pick=pick break else: # S-traces: only pick if the signal is relatively large s_picks[i-1]=np.nan if maxcft>6: picks=triggerOnset(cft,4,1) for pick,end in picks: if npts-pick<100: break else: stcut =st.copy() # cut trace from pick to 100 samples past pick startcut=stcut[0].stats.starttime+dt.timedelta(seconds= pick/df) endcut=startcut + dt.timedelta(seconds=100/df) stcut = stcut.slice(startcut,endcut) stcut.sort() azi,inc,lin,plan=flinn(stcut) if inc>50 and lin>0.75: # good enough for an s-pick s_picks[i-1]=pick break s_pick=np.nanmin(s_picks) return (p_pick-50)/df,[(i-50)/df for i in s_picks]
# Detrend and merge, fill gaps with zeros, bandpass st = st.detrend() st = st.merge(method=1, fill_value=0) st = st.filter('bandpass', freqmin=1.0, freqmax=10.0, corners=2, zerophase=True) # print("Close the window to continue...") # Helicorder plot # st.plot(type='dayplot') # STA/LTA ttrigger print('Triggering') tr = st[0] cft = classicSTALTA(tr.data, 80, 700) # 0.8 s short, 7 s long # Grab triggers [on off], in samples on_off = triggerOnset(cft, 3, 2) # Go through the trigger list, don't allow triggers within 10 seconds of each other # Slice out the traces, save them to an array we can manipulate later # Find first trigger that's after the start of the day # Last trigger has to be before end of day # Note: not sure if this is the best way to grab the data to manipulate it later... trigtime = 0 print('Cutting out triggers to save: time consuming!!') for n in range(0,len(on_off)): if on_off[n,0] > trigtime + 1000: if trigtime is 0: trigtime = on_off[n,0] trigs = st.slice(t - 15 + 0.01*trigtime, t + 5.47 + 0.01*trigtime)
file_list = glob.glob(os.path.join(os.getcwd(), "*.sac")) N = len(file_list) misses = 0 for k in range(0,N): trace = read(file_list[k]) tr = trace[0] df = tr.stats.sampling_rate try: cft = classicSTALTA(tr.data, int(stla * df), int(ltla * df)) #cft = recSTALTA(tr.data, int(stla * df), int(ltla * df)) except: print "Error from file ", file_list[k] misses = misses + 1 continue on_of = triggerOnset(cft, on_tres, off_tres ) if len(on_of) > 0: #plotTrigger(tr, cft, on_tres, off_tress) try: t5 = tr.times()[on_of[0][0]] + tr.stats.sac.b except: print "Error from file ", file_list[k] misses = misses + 1 continue tr.stats.sac.t5 = t5 tr.write(file_list[k], format='SAC') else: misses = misses + 1 print "Unable to pick p arrival.", file_list[k] print "Files analyzed ", k print "Unable to detect ", misses
def refTrigger(self, RefWaveform, phase, cfg_yaml): Config = self.Config cfg = ConfigObj(dict=Config) name = ('%s.%s.%s.%s') % (RefWaveform[0].stats.network, RefWaveform[0].stats.station, RefWaveform[0].stats.location, RefWaveform[0].stats.channel) i = self.searchMeta(name, self.StationMeta) de = loc2degrees(self.Origin, i) ptime = 0 Phase = cake.PhaseDef(phase) model = cake.load_model() if cfg_yaml.config_data.colesseo_input is True: arrivals = model.arrivals([de, de], phases=Phase, zstart=self.Origin.depth, zstop=0.) else: arrivals = model.arrivals([de, de], phases=Phase, zstart=self.Origin.depth*km, zstop=0.) try: ptime = arrivals[0].t except Exception: arrivals = model.arrivals([de, de], phases=Phase, zstart=self.Origin.depth*km-0.1) ptime = arrivals[0].t if ptime == 0: raise Exception("\033[31mILLEGAL: phase definition\033[0m") tw = self.calculateTimeWindows(ptime) if cfg_yaml.config_data.pyrocko_download is True: stP = self.readWaveformsPicker_pyrocko(i, tw, self.Origin, ptime, cfg_yaml) elif cfg_yaml.config_data.colesseo_input is True: stP = self.readWaveformsPicker_colos(i, tw, self.Origin, ptime, cfg_yaml) else: stP = self.readWaveformsPicker(i, tw, self.Origin, ptime, cfg_yaml) refuntouchname = os.path.basename(self.AF)+'-refstation-raw.mseed' stP.write(os.path.join(self.EventPath, refuntouchname), format='MSEED', byteorder='>') stP.filter("bandpass", freqmin=float(cfg_yaml.config_xcorr.refstationfreqmin), freqmax=float(cfg_yaml.config_xcorr.refstationfreqmax)) stP.trim(tw['xcorrstart'], tw['xcorrend']) trP = stP[0] trP.stats.starttime = UTCDateTime(3600) refname = os.path.basename(self.AF)+'-refstation-filtered.mseed' trP.write(os.path.join(self.EventPath, refname), format='MSEED', byteorder='>') sta = float(cfg_yaml.config_xcorr.refsta) lta = float(cfg_yaml.config_xcorr.reflta) cft = recSTALTA(trP.data, int(sta * trP.stats.sampling_rate), int(lta * trP.stats.sampling_rate)) t = triggerOnset(cft, lta, sta) try: onset = t[0][0] / trP.stats.sampling_rate except Exception: onset = self.mintforerun trigger = trP.stats.starttime+onset tdiff = (trP.stats.starttime + onset)-(UTCDateTime(3600) + self.mintforerun) refp = UTCDateTime(self.Origin.time)+ptime reftriggeronset = refp+onset-self.mintforerun if cfg_yaml.config_xcorr.autoxcorrcorrectur is True: refmarkername = os.path.join(self.EventPath, ('%s-marker') % (os.path.basename( self.AF))) fobjrefmarkername = open(refmarkername, 'w') fobjrefmarkername.write('# Snuffler Markers File Version\ 0.2\n') fobjrefmarkername.write(('phase: %s 0 %s None None None XWStart None False\n') % (tw['xcorrstart'].strftime('%Y-%m-%d %H:%M:%S.%f'), name)) fobjrefmarkername.write(('phase: %s 0 %s None None None XWEnd None False\n') % (tw['xcorrend'].strftime('%Y-%m-%d %H:%M:%S.%f'), name)) fobjrefmarkername.write(('phase: %s 1 %s None None None TheoP None False\n') % (refp.strftime('%Y-%m-%d %H:%M:%S.%f'), name)) fobjrefmarkername.write(('phase: %s 3 %s None None None XTrig None False') % (reftriggeronset.strftime('%Y-%m-%d %H:%M:%S.%f'), name)) fobjrefmarkername.close() cmd = 'snuffler %s --markers=%s&' % (os.path.join( self.EventPath, refuntouchname), refmarkername) os.system(cmd) thrOn = float(self.Config['reflta']) thrOff = float(self.Config['refsta']) plotTrigger(trP, cft, thrOn, thrOff) selection = float(input('Enter self picked phase in seconds: ')) tdiff = selection-self.mintforerun refname = os.path.basename(self.AF)+'-shift.mseed' trP.stats.starttime = trP.stats.starttime - selection trP.write(os.path.join(self.EventPath, refname), format='MSEED') ''' tdiff = 0 trigger = trP.stats.starttime ''' To = Trigger(name, trigger, os.path.basename(self.AF), tdiff) return tdiff, To
file_list = glob.glob(os.path.join(os.getcwd(), "*.sac")) N = len(file_list) misses = 0 for k in range(0, N): trace = read(file_list[k]) tr = trace[0] df = tr.stats.sampling_rate try: cft = classicSTALTA(tr.data, int(stla * df), int(ltla * df)) #cft = recSTALTA(tr.data, int(stla * df), int(ltla * df)) except: print "Error from file ", file_list[k] misses = misses + 1 continue on_of = triggerOnset(cft, on_tres, off_tres) if len(on_of) > 0: #plotTrigger(tr, cft, on_tres, off_tress) try: t5 = tr.times()[on_of[0][0]] + tr.stats.sac.b except: print "Error from file ", file_list[k] misses = misses + 1 continue tr.stats.sac.t5 = t5 tr.write(file_list[k], format='SAC') else: misses = misses + 1 print "Unable to pick p arrival.", file_list[k] print "Files analyzed ", k print "Unable to detect ", misses