def make_trigger(origin_folder, filename, dest_folder, trig_on, trig_of, trigger_type, nsta, nlta): stream = obspy.read(os.path.join(origin_folder, filename)) freqmin = bandpass[1] freqmax = bandpass[0] print freqmin, freqmax filtered = stream.filter("bandpass", freqmin=bandpass[1], freqmax=bandpass[0]) fm = float(filtered[0].stats.sampling_rate) to_process = filtered.copy() merged = to_process.merge(method=0) if np.isnan(merged).any(): to_process = filtered.copy() data = merge_numpy(to_process) print type(data) print type(nsta) print type(nlta) cft = recursive_sta_lta(data, int(float(nsta) * fm), np.int(float(nlta) * fm)) on_of = trigger_onset(cft, trig_on, trig_off) else: # we can process the whole day. data = merged[0] cft = recursive_sta_lta(data, int(nsta * fm), int(nlta * fm)) on_of = trigger_onset(cft, trig_on, trig_off) # we can process the whole day. cft = recursive_sta_lta(data, int(nsta * fm), int(nlta * fm)) on_of = trigger_onset(cft, trig_on, trig_of) save_stalta(dest_folder, filename, data, cft, on_of, trig_on, trig_of, fm)
def predict(dtfl, ev_list, dataOperator): for c, evi in enumerate(ev_list): try: if c % 1000 == 0: print(c) dataset = dtfl.get('data/'+str(evi)) data = np.array(dataset) pre_E = trigger_onset(recursive_sta_lta( data[:, 0], config['sta_window'], config['lta_window']), config['on_trigger'], config['off_trigger']) pre_N = trigger_onset(recursive_sta_lta( data[:, 1], config['sta_window'], config['lta_window']), config['on_trigger'], config['off_trigger']) # pre_Z = trigger_onset(recursive_sta_lta( # data[:, 2], config['sta_window'], config['lta_window']), config['on_trigger'], config['off_trigger']) N_end_time, E_end_time = 6000, 6000 if len(pre_E) == 0 and len(pre_N) == 0: dataOperator.data_writer(dataset.attrs['trace_name'], dataset.attrs['p_arrival_sample'], dataset.attrs['s_arrival_sample'], dataset.attrs['coda_end_sample'], -1, -1, -1, dataset.attrs['trace_category'], "noise") continue if dataset.attrs['trace_category'] == 'noise': dataOperator.data_writer(dataset.attrs['trace_name'], dataset.attrs['p_arrival_sample'], dataset.attrs['s_arrival_sample'], dataset.attrs['coda_end_sample'], -1, -1, -1, dataset.attrs['trace_category'], "earthquake_local") continue if len(pre_E): E_end_time = pre_E[-1][1] if len(pre_N): N_end_time = pre_N[-1][1] end_time = (E_end_time + N_end_time) / 2 p_pick, s_pick = ar_pick(data[:, 0], data[:, 1], data[:, 2], 100, 1.0, 20.0, 1.0, 0.1, 4.0, 1.0, 2, 8, 0.1, 0.2) p_pick, s_pick = p_pick*100, s_pick*100 # y_true = [float(dataset.attrs['p_arrival_sample']), # float(dataset.attrs['s_arrival_sample']), float(dataset.attrs['coda_end_sample'][0][0])] # y_pred = [p_pick, s_pick, end_time] # p_true = np.zeros(shape=(6000,)) # p_true[p_pick-20:p_pick+21] = 1 # a = np.array(y_true) # b = np.array(y_pred) # print(a * b) # break dataOperator.data_writer(dataset.attrs['trace_name'], dataset.attrs['p_arrival_sample'], dataset.attrs['s_arrival_sample'], dataset.attrs['coda_end_sample'], int(p_pick), int(s_pick), int(end_time), dataset.attrs['trace_category'], "earthquake_local") except: continue return
def get_triggers_stalta(st): len_sta, len_lta, trig_on, trig_off, freqmin, freqmax = load_stalta_parameters( ) stations_list = [] triggers_list = [] if len(st) > 0: for tr in st: try: tr.detrend('demean') tr.detrend('linear') tr.taper(max_percentage=0.015, type='hann') tr.filter("bandpass", freqmin=freqmin, freqmax=freqmax, corners=2) cft_rec = recursive_sta_lta( tr.data, int(len_sta * tr.stats.sampling_rate), int(len_lta * tr.stats.sampling_rate)) on_off = trigger_onset(cft_rec, trig_on, trig_off) triggers = [] for trig in on_off: on = tr.times("utcdatetime")[trig[0]] off = tr.times("utcdatetime")[trig[1]] triggers.append([on, off]) stations_list.append(tr.stats.station) triggers_list.append(triggers) except: continue return stations_list, triggers_list
def _init_first_arrivals(self): def find_fa(file, channel): for fa in self.genie.current_inversion_cfg.first_arrivals: if fa.file == file and fa.channel == channel: return fa return None new_first_arrivals = [] for meas in self._measurements: if meas.data is not None: for i, trace in enumerate(meas.data["data"]): cft = recursive_sta_lta(trace.data, 40, 60) t = np.argmax(cft) / trace.stats.sampling_rate fa = find_fa(meas.file, i) if fa is not None: fa.time_auto = t new_first_arrivals.append(fa) else: new_first_arrivals.append( FirstArrival(file=meas.file, channel=i, time_auto=t)) self.genie.current_inversion_cfg.first_arrivals = new_first_arrivals
def predictinput(sacfile, algo): #print(input_path) bhnfile = read("/home/shilpa/Desktop/earthquakeproject/files/" + sacfile) bhn_tr = bhnfile[0] df = bhn_tr.stats.sampling_rate bhn_trigger = recursive_sta_lta(bhn_tr.data, int(5 * df), int(10 * df)) bhnonoff = trigger_onset(bhn_trigger, 1.2, 0.5) p_pick, s_pick = ar_pick(bhnfile[0].data, bhnfile[0].data, bhnfile[0].data, df, 1.0, 20.0, 1.0, 0.1, 4.0, 1.0, 2, 8, 0.1, 0.2) data = [] temp = [] temp.append(200) temp.append(p_pick) temp.append(s_pick) temp.append(int(bhnonoff[0][1]) - int(bhnonoff[0][0])) data.append(temp) print(data) if algo == "decisiontree": prediction = d_model.predict(data) elif algo == "randomforest": prediction = r_model.predict(data) elif algo == "svm": prediction = r_model.predict(data) result = " " if (prediction[0] == 1): result = "an Earthquake" else: result = "No Earthquake" return result
def extract_filter_params(trace): samp_rate = trace.stats.sampling_rate trigs = [] p_arrivals = model.get_travel_times_geo(trace.stats.event_depth, trace.stats.event_latitude, trace.stats.event_longitude, trace.stats.station_latitude, trace.stats.station_longitude, phase_list=[ 'P', ]) mean_parrival = np.mean([parr.time for parr in p_arrivals]) for band in [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (1.5, 2.5), (2.5, 3.5), (3.5, 4.5), (4.5, 5.5), (5.5, 6.5), (6.5, 7.5), (7.5, 8.5), (8.5, 9.5)]: tr_copy = trace.copy() clean_trace(tr_copy, tr_copy.stats.starttime, tr_copy.stats.endtime, freqmin=band[0], freqmax=band[1]) cft = recursive_sta_lta(tr_copy.data, int(5 * samp_rate), int(20 * samp_rate)) upper, lower = find_best_bounds(cft, samp_rate) trigs.extend([ (onset, tr_copy.stats.channel, upper - lower, band, upper) for onset in trigger_onset(cft, upper, lower, max_len=(60 * tr_copy.stats.sampling_rate), max_len_delete=True) ]) trigs = [ trig for trig in trigs if abs(trace.stats.event_time + mean_parrival - trace.stats.starttime - (trig[0][0] / samp_rate)) < pphase_search_margin ] if len(trigs) > 0: mintrigdiff = abs(trace.stats.event_time + mean_parrival - trace.stats.starttime - trigs[0][0][0]) besttrig = trigs[0][0][0] best_trig_margin = trigs[0][2] best_band = trigs[0][3] best_upper = trigs[0][4] for trig in trigs: if abs(trace.stats.event_time + mean_parrival - trace.stats.starttime - trig[0][0]) <= mintrigdiff and \ trig[2] >= best_trig_margin and trig[4] >= best_upper: mintrigdiff = abs(trace.stats.event_time + mean_parrival - trace.stats.starttime - trig[0][0]) besttrig = trig[0][0] best_trig_margin = trig[2] best_band = trig[3] best_upper = trig[4] return (best_band, best_trig_margin, best_upper) else: print('Something went wrong ... ') return None, None, None
def picker(data, rate, nsta=10, nlta=100, uncer=0.5): stalta = recursive_sta_lta(data, nsta, nlta) n_max = np.argmax(stalta) quality = stalta[n_max] n_onset = int(uncer * rate) n_diff_max = np.argmax(np.diff(stalta[n_max - n_onset:n_max + n_onset])) n_pick = n_max - n_onset + n_diff_max arr = n_pick / rate return arr, quality
def _filter(self): ''' Filters the stream associated with this class. ''' if self.filt: if self.filt in 'bandpass': self.stalta = recursive_sta_lta( self.stream[0].copy().filter(type=self.filt, freqmin=self.freqmin, freqmax=self.freqmax), int(self.sta * self.sps), int(self.lta * self.sps)) else: self.stalta = recursive_sta_lta( self.stream[0].copy().filter(type=self.filt, freq=self.freq), int(self.sta * self.sps), int(self.lta * self.sps)) else: self.stalta = recursive_sta_lta(self.stream[0], int(self.sta * self.sps), int(self.lta * self.sps))
def _channel_loop(tr, parameters, max_trigger_length=60, despike=False): """ Internal loop for parellel processing. :type tr: obspy.core.trace :param tr: Trace to look for triggers in. :type parameters: list :param parameters: List of TriggerParameter class for trace. :type max_trigger_length: float :type despike: bool :return: trigger :rtype: list """ for par in parameters: if par['station'] == tr.stats.station and \ par['channel'] == tr.stats.channel: parameter = par break else: Logger.warning('No parameters set for station ' + str(tr.stats.station)) return [] triggers = [] Logger.debug(tr) tr.detrend('simple') if despike: median_filter(tr) if parameter['lowcut'] and parameter['highcut']: tr.filter('bandpass', freqmin=parameter['lowcut'], freqmax=parameter['highcut']) elif parameter['lowcut']: tr.filter('highpass', freq=parameter['lowcut']) elif parameter['highcut']: tr.filter('lowpass', freq=parameter['highcut']) # find triggers for each channel using recursive_sta_lta df = tr.stats.sampling_rate cft = recursive_sta_lta(tr.data, int(parameter['sta_len'] * df), int(parameter['lta_len'] * df)) if max_trigger_length: trig_args = {'max_len_delete': True} trig_args['max_len'] = int(max_trigger_length * df + 0.5) tmp_trigs = trigger_onset(cft, float(parameter['thr_on']), float(parameter['thr_off']), **trig_args) for on, off in tmp_trigs: cft_peak = tr.data[on:off].max() cft_std = tr.data[on:off].std() on = tr.stats.starttime + \ float(on) / tr.stats.sampling_rate off = tr.stats.starttime + \ float(off) / tr.stats.sampling_rate triggers.append( (on.timestamp, off.timestamp, tr.id, cft_peak, cft_std)) return triggers
def compute_sta_lta(data, fm, trigger_type, nlta=10.0, nsta=5.0, trig_on=1.2, trig_off=0.5): """ Function that handles the building of STA/LTA event picking: classic, recursive and delayed. It follows Obspy implementation of these algorithms and can be interfaced with the main GUI to plot the results, or with the CLI to other analysis routines. A detailed comparison of STA/LTA techniques algorithms are included in: Withers, M., Aster, R., Young, C., Beiriger, J., Harris, M., Moore, S., and Trujillo, J. (1998), A comparison of select trigger algorithms for automated global seismic phase and event detection, Bulletin of the Seismological Society of America, 88 (1), 95-106. http://www.bssaonline.org/content/88/1/95.abstract Args: data : Numpy Array The seismic data we want to apply our STA/LTA routine fm : float The sampling frequency of the main trace trigger_type : str A string identifiying which trigger type we want (Recursive, Delayed, Classic) nlta : float Length of the Long Time Average Window (LTA) nsta : float Length of the Short Time Average Window (STA) trig_on : float Value of the CF to consider as an activation trigger trig_off : float Value of the CF to consider as a de-activation trigger Returns: cft: Numpy Array The characteristic function result of the on_of: Tuple A data tuple containing the on/ofs times of the even picking """ if np.isnan(data).any(): data = merge_numpy(data) try: if trigger_type == "Recursive": cft = recursive_sta_lta(data, int(nsta * fm), int(nlta * fm)) elif trigger_type == "Delayed": cft = delayed_sta_lta(data, int(nsta * fm), int(nlta * fm)) else: cft = classic_sta_lta(data, int(nsta * fm), int(nlta * fm)) on_of = trigger_onset(cft, trig_on, trig_off) return cft, on_of except ArithmeticError: print "Problem whilst computing the trigger"
def test_rec_sta_lta_c(self): """ Test case for ctypes version of recursive_sta_lta """ nsta, nlta = 5, 10 c1 = recursive_sta_lta(self.data, nsta, nlta) self.assertAlmostEqual(c1[99], 0.80810165) self.assertAlmostEqual(c1[100], 0.75939449) self.assertAlmostEqual(c1[101], 0.91763978) self.assertAlmostEqual(c1[102], 0.97465004)
def getTrigger(sac, short=2, long=30): df = sac.stats.sampling_rate # get cft cft = recursive_sta_lta(sac.data, int(short * df), int(long * df)) # set threshold threshold = np.mean(cft) + (np.max(cft) - np.mean(cft)) / 4 # get on on_of = trigger_onset(cft, threshold, threshold) if len(on_of) != 0: return on_of[:, 0] else: return np.array([])
def getTrigger(sac, short=2, long=30): df = sac.stats.sampling_rate # get cft cft = recursive_sta_lta(sac.data, int(short * df), int(long * df)) # set threshold threshold = np.mean(cft) + (np.max(cft) - np.mean(cft))/4 # get on on_of = trigger_onset(cft, threshold*1.1, threshold*0.9) if len(on_of) != 0: return on_of[:, 0] else: return np.array([])
def _doubleChecking(station_list, detections, preprocessed_dir, moving_window, thr_on=3.7, thr_of=0.5): 'this function perform traditional detection (STA/LTA) and picker (AIC) to double check for events on the remaining stations when an event has been detected on more than two stations' for stt in station_list: sttt = stt.split('_')[0] # print(sttt) if sttt not in detections['station'].to_list(): new_picks = {} if platform.system() == 'Windows': file_name = preprocessed_dir+"\\"+sttt+".hdf5" file_csv = preprocessed_dir+"\\"+sttt+".csv" else: file_name = preprocessed_dir+"/"+sttt+".hdf5" file_csv = preprocessed_dir+"/"+sttt+".csv" df = pd.read_csv(file_csv) df['start_time'] = pd.to_datetime(df['start_time']) mask = (df['start_time'] > detections.iloc[0]['event_start_time']-timedelta(seconds = moving_window)) & (df['start_time'] < detections.iloc[0]['event_start_time']+timedelta(seconds = moving_window)) df = df.loc[mask] dtfl = h5py.File(file_name, 'r') dataset = dtfl.get('data/'+df['trace_name'].to_list()[0]) data = np.array(dataset) cft = recursive_sta_lta(data[:,2], int(2.5 * 100), int(10. * 100)) on_of = trigger_onset(cft, thr_on, thr_of) if len(on_of) >= 1: p_pick, s_pick = ar_pick(data[:,2], data[:,1], data[:,0], 100, 1.0, 20.0, 1.0, 0.1, 4.0, 1.0, 2, 8, 0.1, 0.2) if (on_of[0][1]+100)/100 > p_pick > (on_of[0][0]-100)/100: # print('got one') new_picks['traceID'] = df['trace_name'].to_list()[0] new_picks['network'] = dataset.attrs["network_code"] new_picks['station'] = sttt new_picks['instrument_type'] = df['trace_name'].to_list()[0].split('_')[2] new_picks['stlat'] = round(dataset.attrs["receiver_latitude"], 4) new_picks['stlon'] = round(dataset.attrs["receiver_longitude"], 4) new_picks['stelv'] = round(dataset.attrs["receiver_elevation_m"], 2) new_picks['event_start_time'] = datetime.strptime(str(UTCDateTime(dataset.attrs['trace_start_time'].replace(' ', 'T')+'Z')+(on_of[0][0]/100)).replace('T', ' ').replace('Z', ''), '%Y-%m-%d %H:%M:%S.%f') new_picks['event_end_time'] = datetime.strptime(str(UTCDateTime(dataset.attrs['trace_start_time'].replace(' ', 'T')+'Z')+(on_of[0][1]/100)).replace('T', ' ').replace('Z', ''), '%Y-%m-%d %H:%M:%S.%f') new_picks['detection_prob'] = 0.3 new_picks['detection_unc'] = 0.6 new_picks['p_arrival_time'] = datetime.strptime(str(UTCDateTime(dataset.attrs['trace_start_time'].replace(' ', 'T')+'Z')+p_pick).replace('T', ' ').replace('Z', ''), '%Y-%m-%d %H:%M:%S.%f') new_picks['p_prob'] = 0.3 new_picks['p_unc'] = 0.6 new_picks['p_snr'] = None new_picks['s_arrival_time'] = None new_picks['s_prob'] = 0.0 new_picks['s_unc'] = None new_picks['s_snr'] = None new_picks['amp'] = None detections = detections.append(new_picks , ignore_index=True) return detections
def semblancestalta(sembmaxvaluevector, sembmaxlatvector, sembmaxlonvector): data = np.array(sembmaxvaluevector, dtype=np.float64) tr = Trace(data, header=None) sta = 0.5 lta = 4 cft = recursive_sta_lta(tr, int(sta * tr.stats.sampling_rate), int(lta * tr.stats.sampling_rate)) thrOn = 0.5 thrOff = 1.5 plotTrigger(tr, cft, thrOn, thrOff)
def phase_trigger(self, time_before, time_after, stl=5, ltl=10): t1, t2 = self._get_time(time_before, time_after) self.st_pick = self.st.copy().trim(t1, t2) if len(self.st_pick) == 0: return if self.phase[-1] == 'P': tr = self.st_pick.select(channel='*Z')[0] else: tr = self.st_pick.select(channel='*T')[0] df = tr.stats.sampling_rate cft = recursive_sta_lta(tr.data, int(stl * df), int(ltl * df)) n_trigger = np.argmax(np.diff(cft)[int(ltl * df):]) + int(ltl * df) self.t_trigger = t1 + n_trigger / df self.trigger_shift = n_trigger / df - time_before
def standard_trigger_finder(trace, channel_name): global std_on global std_off t = trace.copy() max_triggers = 30 max_trigger_length = 20000 ctf_start = 300 # avoids triggering on initial spike if "PDB" in channel_name: #trace.filter('highpass', freq=1500) sta = 20 lta = 60 ctf = recursive_sta_lta(t.data, sta, lta) ctf = ctf[ctf_start:] std_on = ctf[find_index_of_best_val(ctf, max_triggers)] * 0.98 std_off = std_on * 0.8 trigger_indices = trigger_onset(ctf, std_on, std_off, max_trigger_length) if "OT" in channel_name: #t.filter('bandpass', freqmin=1000, freqmax=15000) sta = 10 lta = 50 ctf = recursive_sta_lta(t.data, sta, lta) ctf = ctf[ctf_start:] #std_on = ctf[find_index_of_max_val(ctf, max_triggers)] * 0.94 std_on = ctf[find_index_of_best_val(ctf, max_triggers)] * 0.92 if (std_on < 1): std_on += (1 - std_on) * 1.1 #print("std_on: " + str(std_on)) std_off = 1 #std_on * 0.92 trigger_indices = trigger_onset(ctf, std_on, std_off, max_trigger_length) return trigger_indices, ctf
def test_trigger_onset_issue_2891(self): """ Regression test for issue 2891 This used to raise an error if a trigger was activated near the end of the trace, and all sample values after that trigger on threshold are above the designated off threshold. So basically this can only happen if the on threshold is below the off threshold, which is kind of unusual, but we fixed it nevertheless, since people can run into this playing around with different threshold settings """ tr = read(os.path.join(self.path, 'BW.UH1._.EHZ.D.2010.147.a.slist.gz'))[0] cft = recursive_sta_lta(tr.data, 5, 30) trigger_onset(cft, 2.5, 3.2)
def update_cft(prev_val, selected=None): print(ticker_alg.value) if ticker_alg.value == 'Classic STA/LTA': from obspy.signal.trigger import classic_sta_lta, trigger_onset on = trigger_slider.value[1]; off=trigger_slider.value[0] cft = classic_sta_lta(st[0].data, int(stalta_slider.value[0] * st[0].stats.sampling_rate), int(stalta_slider.value[1] * st[0].stats.sampling_rate)) on_off = np.array(trigger_onset(cft, on, off)) source_stalta.data = dict(times=st[0].times(), cft=cft) source_triggers.data = dict(ontimes=st[0].times()[on_off[:,0]], y=np.zeros(on_off[:,0].shape)) #source_triggers.data = dict(offtimes=st[0].times()[on_off[:,1]], y=np.zeros(on_off[:,1].shape)) sta_on.location = on sta_off.location = off elif ticker_alg.value == 'Recursive STA/LTA': from obspy.signal.trigger import recursive_sta_lta, trigger_onset on = trigger_slider.value[1]; off=trigger_slider.value[0] cft = recursive_sta_lta(st[0].data, int(stalta_slider.value[0] * st[0].stats.sampling_rate), int(stalta_slider.value[1] * st[0].stats.sampling_rate)) on_off = np.array(trigger_onset(cft, on, off)) source_stalta.data = dict(times=st[0].times(), cft=cft) source_triggers.data = dict(ontimes=st[0].times()[on_off[:,0]], y=np.zeros(on_off[:,0].shape)) #source_triggers.data = dict(offtimes=st[0].times()[on_off[:,1]], y=np.zeros(on_off[:,1].shape)) sta_on.location = on sta_off.location = off elif ticker_alg.value == 'Carl-Sta-Trig [Not Yet Implemented]': from obspy.signal.trigger import carl_sta_trig, trigger_onset on = 3000; off=-500 cft = carl_sta_trig(st[0].data, int(5 * st[0].stats.sampling_rate), int(10 * st[0].stats.sampling_rate), 0.8, 0.8) on_off = np.array(trigger_onset(cft, on, off)) source_stalta.data = dict(times=st[0].times(), cft=cft) source_triggers.data = dict(ontimes=st[0].times()[on_off[:,0]], y=np.zeros(on_off[:,0].shape)) sta_on.location = on sta_off.location = off else: print(ticker_alg.value + ' is not yet implemented.') ticker_alg.value = prev_val
def pick_arrival(trace, nsta_seconds, nlta_seconds, df, origin_time, pick_threshold, plot_flag=False): """ P wave arrival is picked using a recursive sta/lta algorithm. Parameters ---------- trace: obspy trace Seimic data. nsta_seconds, nlta_seconds, pick_threshold: float parameters for sta/lta df: int, float Data sampling rate origin_time: obspy UTCDateTime Earthquake occurrence time . Returns ------- P_pick: array-like Picked arrivals in samples. Reference: Withers, M., Aster, R., Young, C., Beiriger, J., Harris, M., Moore, S., and Trujillo, J. (1998), A comparison of select trigger algorithms for automated global seismic phase and event detection, Bulletin of the Seismological Society of America, 88 (1), 95-106. """ cft = recursive_sta_lta(trace, int(nsta_seconds * df), int(nlta_seconds * df)) arrivals = trigger_onset(cft, pick_threshold, 0.5) if plot_flag: plot_trigger(trace, cft, pick_threshold, 0.5, show=True) P_pick = check_arrival_time(arrivals, trace.stats.starttime, origin_time, df) return P_pick
def getTrigger(sac, short=2, long=25): # 1.75 1.25 4.wan perfect df = sac.stats.sampling_rate # print 'sampling_rate = ' # print df # get cft cft = recursive_sta_lta(sac.data, int(short * df), int(long * df)) # set threshold threshold = np.mean(cft) + (np.max(cft) - np.mean(cft)) / 4 if np.isnan(threshold) == 1: print 'thre = nan' threshold = 3.2 # get on # gk change # on_of = trigger_onset(cft, threshold, threshold) on_of = trigger_onset(cft, threshold * 1.38, threshold * 0.92) if len(on_of) != 0: return on_of[:, 0] else: return np.array([])
def network_detection(st, cft_return=True): # TODO: Dynamic threshold method of Akram 2013 fs = st[0].stats.sampling_rate sta_len_sec = 2.5 * DOM_PERIOD # 2-3 times dominant period lta_len_sec = 7.5 * sta_len_sec # 5-10 times STA nsta = int(sta_len_sec * fs) nlta = int(lta_len_sec * fs) on_thresh = 3.0 # 3.5 off_thresh = 0.5 numsta = len(list(set([tr.stats.station for tr in st]))) min_chans = numsta * 2 # Minimum number of channels to log network detection cft_stream = Stream() if cft_return: for i, tr in enumerate(st.traces): cft = recursive_sta_lta(tr.data, nsta=nsta, nlta=nlta) # cft = eps_smooth(cft, w=int(EPS_WINLEN * Fs)) cft_stream += Trace(data=cft, header=tr.stats) detection_list = coincidence_trigger(None, on_thresh, off_thresh, cft_stream, thr_coincidence_sum=min_chans, max_trigger_length=2.0, delete_long_trigger=True, details=True) else: detection_list = coincidence_trigger('recstalta', on_thresh, off_thresh, st, sta=sta_len_sec, lta=lta_len_sec, thr_coincidence_sum=min_chans, max_trigger_length=2.0, delete_long_trigger=True, details=True) # Dictionary keys: # time, stations, trace_ids, coincidence_sum, cft_peaks, cft_stds, duration, cft_wmean, cft_std_wmean return detection_list, cft_stream
def pick_arrival(trace, nsta_seconds, nlta_seconds, df, origin_time, pick_threshold, plot_flag=False): """ P wave arrival is picked using a recursive sta/lta algorithm. """ cft = recursive_sta_lta(trace, int(nsta_seconds * df), int(nlta_seconds * df)) arrivals = trigger_onset(cft, pick_threshold, 0.5) if plot_flag: plot_trigger(trace, cft, pick_threshold, 0.5, show=True) P_pick = check_arrival_time(arrivals, trace.stats.starttime, origin_time, df) return P_pick
def pick(self, path_to_file=None, from_file=False, method='sta_lta', trigger_on=2.0, sta=1.0, lta=5.0): ''' Pick onsets ''' from obspy.signal.trigger import recursive_sta_lta from numpy import zeros, where, nan, genfromtxt, array if from_file == False: self.picks = zeros(len(self.filtered_stations)) for k in range(len(self.filtered_stations)): df = self.waveforms_up[k].stats.sampling_rate cft = recursive_sta_lta(self.waveforms_up[k], int(sta * df), int(lta * df)) i = where(cft > trigger_on)[0] if len(i) > 0: self.picks[k] = self.waveforms_up[k].times()[i[0]] else: i = where(cft > trigger_on / 2.)[0] self.picks[k] = self.waveforms_up[k].times()[i[0]] else: picks = genfromtxt(path_to_file + self.ID + '.pick', usecols=1, dtype='S') for k in range(len(picks)): if picks[k] == 'nan': picks[k] = float(nan) else: picks[k] = float(picks[k]) picks = array(picks).astype('float') self.picks = array(picks)
def LTASTAtr(tr,thres1, thres2,STA, LTA,plotSTA): """ return the cut on and off of the LTA/STA list [[cuton, cutoff], [cuton, cutoff]] * input : - tr : type : trace , stream to filnd STA, LTA - thres1 : type; float : cut on limit of STA/LTA values : after tjis value the cut on is defined - thres2 : type, float : cut off limit of STA/LTA values : after this value the cut off is defined - STA : type int : size of the LTA windows in second : STA = the trace average on this time windows - LTA : type int : size of the LTA windows in second : LTA = the trace average on this time windows - plotSTA: type, bool; it true, the trace and it's characteristic function are plotted RQ: AFTER TESTING IT'S SEEEMS GOOD TO HAVE A RATIO WSTA/WLTA > 1/4 AND A CUT OFF HIGHER THAN CUT ON * outputs - L_onoff: type np, array : 2D array of cut on and cut_off time in number of sample ie time* df where df is the sampling rate [[cuton,cutoff], [cuton1, cutoff1]] exemple: st = Read_event('15','206','15','1', '1', True) stcorrec = Stream_Correction(st, '1', False) stfiltered= Stream_PBfilter(stcorrec,0.5, 20,False) LTASTA(stfiltered,2, 2.5,300,1400,True) """ #0. sampling rate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ df = tr.stats.sampling_rate #1. characteristic function of the trace following classical LTA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #cft = classicSTALTA(tr.data, int(STA * df), int(LTA* df)) #2. characteristic function of the trace following recursive LTA cft2 =recursive_sta_lta(tr.data, int(STA * df), int(LTA* df)) #3. list of [cuton, cutoff] time in number of samples~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #max_len = maximum lenght of the triggered event in sample, #max_len_delete = Do not write events longer than max_len into report file. L_onoff = trigger_onset(cft2, thres1, thres2, max_len=9e+99, max_len_delete=False) #4. plot~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if plotSTA==True : ##plotTrigger(tr[0], cft, thres1,thres2) plotTrigger(tr[0], cft2, thres1,thres2) plt.title('recursive') return np.array(L_onoff)
def STA_LTA(self, dataset, batch_size=100, short_window=30, long_window=200): """ STA/LTA method :param dataset: Dataset name. :param batch_size: Model directory name. """ dataset_path, eval_path = self.get_eval_dir(dataset) dataset = seisnn.io.read_dataset(dataset) data_len = self.get_dataset_length(self.database) progbar = tf.keras.utils.Progbar(data_len) n = 0 for val in dataset.prefetch(100).batch(batch_size): progbar.add(batch_size) title = f"eval_{n:0>5}" trace_len = val['trace'].shape[2] batch_len = val['trace'].shape[0] predict = np.zeros((batch_len, 1, 3008, 3)) for i in range(batch_len): z_trace = val['trace'].numpy()[i, :, :, 0].reshape(trace_len) cft = recursive_sta_lta(z_trace, short_window, long_window) predict[i, :, :, 0] = cft val['predict'] = predict val['id'] = tf.convert_to_tensor(title.encode('utf-8'), dtype=tf.string)[tf.newaxis] example = next(seisnn.example_proto.batch_iterator(val)) instance = Instance(example) instance.to_tfrecord(os.path.join(eval_path, title + '.tfrecord')) n += 1
0].stats.starttime + 21 * 60 * 60 + 10 * 60 #+18*60*60 +20*60 #time window start end = start + 70 * 60 #end=sample[0].stats.endtime trs = trace.slice( starttime=start, endtime=end ) #cut out sample waveform with same window length as chosen event #trs_e = obspy.signal.filter.envelope(trs.data) #print('reference waveform') trs.plot(type='relative', color='b') #, starttime=start , endtime=end) sr = trace.stats.sampling_rate nsta = int(2 * sr) #2 nlta = int(10 * sr) #20 stream = trs.data cft = recursive_sta_lta(stream, nsta, nlta) trig_on = 6 #8 trig_off = 0.2 #0.2 plot_trigger(trs, cft, trig_on, trig_off) on_off = trigger_onset(cft, trig_on, trig_off) for x in range(0, len(on_off)): tr = trace.slice(starttime=start + (on_off[x, 0] / sr) - 10, endtime=start + (on_off[x, 1] / sr) + 10) tr_e = obspy.signal.filter.envelope(tr.data) #%% frequency info tr_data = tr.data m = np.mean(tr_data) tr_data = tr_data - m
import matplotlib.pyplot as plt from obspy import read from obspy.signal.trigger import recursive_sta_lta, trigger_onset from seisnn.io import get_dir_list predict_pkl_dir = "/mnt/tf_data/pkl/2017_02" predict_pkl_list = get_dir_list(predict_pkl_dir) for i, pkl in enumerate(predict_pkl_list): trace = read(pkl).traces[0] df = trace.stats.sampling_rate cft = recursive_sta_lta(trace.data, int(0.5 * df), int(1. * df)) on_of = trigger_onset(cft, 1, 0.5) # Plotting the results ax = plt.subplot(211) plt.plot(trace.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()
import obspy from obspy.signal.trigger import plot_trigger, recursive_sta_lta trace = obspy.read("https://examples.obspy.org/ev0_6.a01.gse2")[0] df = trace.stats.sampling_rate cft = recursive_sta_lta(trace.data, int(5 * df), int(10 * df)) plot_trigger(trace, cft, 1.2, 0.5)
import obspy from obspy.clients.arclink import Client from obspy.signal.trigger import recursive_sta_lta, trigger_onset # Retrieve waveforms via ArcLink client = Client(host="erde.geophysik.uni-muenchen.de", port=18001, user="******") t = obspy.UTCDateTime("2009-08-24 00:19:45") st = client.get_waveforms('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 = recursive_sta_lta(tr.data, int(2.5 * df), int(10. * df)) on_of = trigger_onset(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 main(): outputdir = './output/' data = load_data() X_train = data['X_train'] y_train = data["y_train"] X_test = data['X_test'] y_test = data["y_test"] ridge = load_json(outputdir + 'ridge.json') ada_rf_exp = load_json(outputdir + 'ada_rf_exp.json') #rf = load_json(outputdir + 'rf.json') # Baseline model (linear fit for log10(Z.disp.max_amp)) z = np.polyfit(X_train['Z.disp.max_amp'].values, y_train.values, 1) y_pred_base = X_test['Z.disp.max_amp'].values * z[0] + z[1] ##################################################### #Figure 1: #Empirical measurements used in literature ##################################################### label_font = 20 tick_font = 20 alpha = 0.5 plt.figure(1, figsize=(24, 5)) fig = plt.subplot(131) plt.plot(y_train, X_train['Z.disp.max_amp'], '.', alpha=alpha) plt.plot(y_test, X_test['Z.disp.max_amp'], 'r.', alpha=alpha) plt.plot(np.arange(2.5, 7.5, 1), (np.arange(2.5, 7.5, 1) - z[1]) / z[0], 'k--', linewidth=2) plt.xlabel('Magnitude', fontsize=label_font) plt.ylabel(r'$log_{10}(P_d * r^2)$', fontsize=label_font) fig.tick_params(labelsize=tick_font) fig.legend(['Train', 'Test', 'Linear fit (train)'], loc='lower right', fontsize=15) fig = plt.subplot(132) plt.plot(y_train, X_train['Z.tau_c'], '.', alpha=alpha) plt.plot(y_test, X_test['Z.tau_c'], 'r.', alpha=alpha) plt.xlabel('Magnitude', fontsize=label_font) plt.ylabel(r'$log_{10}(\tau_c)$', fontsize=label_font) fig.tick_params(labelsize=tick_font) fig = plt.subplot(133) plt.plot(y_train, X_train['Z.tau_p_max'], '.', alpha=alpha) plt.plot(y_test, X_test['Z.tau_p_max'], 'r.', alpha=alpha) plt.xlabel('Magnitude', fontsize=label_font) plt.ylabel(r'$log_{10}(\tau_p^{max})$', fontsize=label_font) #plt.ylabel(r'$log_{10}(mean frequency)$', fontsize = label_font) fig.tick_params(labelsize=tick_font) plt.savefig(outputdir + 'empirical_measurements.png', format='png') ##################################################### #Figure 2: #Feature coefficients/importance ##################################################### plt.figure(2, figsize=(12, 8)) ax = plt.subplot(141) plot_feature_importance(ridge['coef'], ridge['features'], ax, top_feature=30) plt.xlabel('Coefficient', fontsize=15) plt.title('Ridge', fontsize=15) #plt.tick_params(labelsize = tick_font) ax = plt.subplot(143) plot_feature_importance(ada_rf_exp['coef'], ada_rf_exp['features'], ax, top_feature=30) plt.xlabel('Feature importance', fontsize=15) plt.title('Adaboosted Random Forest', fontsize=15) #plt.tick_params(labelsize = tick_font) plt.savefig(outputdir + 'Feature_importance.png', format='png') ##################################################### #Figure 3: #True magnitude vs. prediction ##################################################### label_font = 25 tick_font = 20 alpha = 0.5 plt.figure(3, figsize=(27, 15)) fig = plt.subplot(2, 3, 1) plot_true_vs_prediction(y_test, y_pred_base, symbol='r.') plt.text(2.2, 6.0, 'Test set', fontsize=label_font + 10) fig.tick_params(labelsize=tick_font + 5) plt.ylabel('Predicted magnitude', fontsize=label_font + 10) plt.title('Baseline', fontsize=label_font + 10) fig = plt.subplot(2, 3, 2) plot_true_vs_prediction(y_test, ridge['y_test_pred'], symbol='r.') fig.tick_params(labelsize=tick_font + 5) plt.title('Ridge', fontsize=label_font + 10) fig = plt.subplot(2, 3, 3) plot_true_vs_prediction(y_test, ada_rf_exp['y_test_pred'], symbol='r.') fig.tick_params(labelsize=tick_font + 5) plt.title('Adaboosted Random Forest', fontsize=label_font + 10) ##################################################### fig = plt.subplot(2, 3, 4) error_base = error_large_eq(y_test.values, y_pred_base) plot_true_vs_error(y_test.values, y_pred_base, error_base) plt.xlabel('True Magnitude', fontsize=label_font + 10) plt.ylabel('Test error', fontsize=label_font + 10) fig.tick_params(labelsize=tick_font + 5) fig = plt.subplot(2, 3, 5) error_ridge = error_large_eq(y_test.values, ridge['y_test_pred']) plot_true_vs_error(y_test.values, ridge['y_test_pred'], error_ridge) plt.xlabel('True Magnitude', fontsize=label_font + 10) fig.tick_params(labelsize=tick_font + 5) fig = plt.subplot(2, 3, 6) error_ada_rf = error_large_eq(y_test.values, ada_rf_exp['y_test_pred']) plot_true_vs_error(y_test.values, ada_rf_exp['y_test_pred'], error_ada_rf) plt.xlabel('True Magnitude', fontsize=label_font + 10) fig.tick_params(labelsize=tick_font + 5) plt.savefig(outputdir + 'prediction.png', format='png') ##################################################### #Figure 4: #Error distribution (> M4.5) ##################################################### plt.figure(4, figsize=(8, 5.5)) bins = np.arange(-1.4, 0.8, 0.1) plt.hist(error_base['error_large'], bins=bins, alpha=0.7, label="Baseline") plt.hist(error_ridge['error_large'], bins=bins, alpha=0.7, label="Ridge") plt.hist(error_ada_rf['error_large'], bins=bins, alpha=0.7, label="Adaboosted RF") plt.legend(loc='upper left', fontsize=15) plt.plot([0, 0], [0, 50], 'k--') plt.ylim([0, 50]) plt.xlabel('Error (> M4.5)', fontsize=label_font) plt.tick_params(labelsize=tick_font) plt.quiver(-0.05, 42, -1, 0) plt.quiver(0.05, 42, 1, 0) plt.text(-0.6, 45, 'Underestimate', fontsize=15) plt.text(0.12, 45, 'Overestimate', fontsize=15) plt.savefig(outputdir + 'error.png', format='png') ##################################################### #Figure 5: #Map view ##################################################### station_loc = pd.read_csv('../data/station.csv') catalog = pd.read_csv('../data/source.csv') plot_stations_and_events(station_loc, catalog, map_flag=True) plt.savefig(outputdir + 'mapview.png', format='png') plot_map_us() plt.savefig(outputdir + 'mapview_us.png', format='png') ##################################################### #Figure 6: #Time series data visualization ##################################################### st = read('../data/proc/2016-06-10T08:04:38.700000Z/CI.mseed') trace = st.select(channel='BHE', station='BAR') df = trace[0].stats.sampling_rate cft = recursive_sta_lta(trace[0], int(0.05 * df), int(20 * df)) arrivals = trigger_onset(cft, 100, 0.5) start = arrivals[0][0] / df - 60 plt.figure(5, figsize=(12, 6)) #plt.subplot(2,1,1) plt.fill_between([start, start + 4], -0.0075, 0.009, facecolor=[0.7, 0.7, 0.7]) plt.plot(np.arange(0, 180, 1. / df) - 60, trace[0]) plt.xlim([60 - 60, 130 - 60]) plt.ylim([-0.0075, 0.009]) plt.text(start + 0.25, -0.006, '4 s', fontsize=25) plt.tick_params(labelsize=tick_font) plt.title('M5.19, 2016-06-10, 08:04:38.70', fontsize=label_font) plt.xlabel('Time (s)', fontsize=label_font) plt.ylabel('Amplitude (m/s)', fontsize=label_font) plt.savefig(outputdir + 'time_series.png', format='png')
import matplotlib.pyplot as plt from obspy import read from obspy.signal.trigger import recursive_sta_lta, trigger_onset from seisnn.io import get_dir_list predict_pkl_dir = "/mnt/tf_data/dataset/2017_02" predict_pkl_list = get_dir_list(predict_pkl_dir) on = 3.5 off = 0.5 for i, pkl in enumerate(predict_pkl_list): trace = read(pkl).traces[0] start_time = trace.stats.starttime df = trace.stats.sampling_rate cft = recursive_sta_lta(trace.data, int(0.2 * df), int(2. * df)) on_of = trigger_onset(cft, on, off) # Plotting the results ax = plt.subplot(211) plt.plot(trace.data, 'k') ymin, ymax = ax.get_ylim() try: plt.vlines(on_of[:, 0], ymin, ymax, color='r', linewidth=2) plt.vlines(on_of[:, 1], ymin, ymax, color='b', linewidth=2) except TypeError: pass plt.subplot(212, sharex=ax) plt.plot(cft, 'k') plt.hlines([on, off], 0, len(cft), color=['r', 'b'], linestyle='--') plt.xticks(range(0, 3001, 500), range(0, 31, 5))
#print(len(data_stream)) sr = 100 nsta = int(1 * sr) nlta = int(10 * sr) trig_on = 2.5 trig_off = 0.05 #for x in range(0,len(data_stream)): for x in range(0, 10): data_s = event_stream[x].data max_a = data_s.max() min_a = data_s.min() p2p = max_a - min_a cft = recursive_sta_lta(data_s, nsta, nlta) # plot_trigger(sq_stream[x], cft, trig_on, trig_off) on_off = trigger_onset(cft, trig_on, trig_off) start = event_stream[x].stats.starttime tr = event_stream[x].slice(starttime=start + (on_off[0, 0] / sr), endtime=start + (on_off[0, 1] / sr)) print('event:', event_stream[x].stats.starttime, 'from station: ', stre[x].stats.station, ', has energy: ', sum(np.square(tr.data)), ' and peak to peak:', p2p) plt.figure(x) plt.plot(tr) plt.figure(x + 20) plt.plot(np.square(tr.data)) #%% energy information
def _channel_loop(tr, parameters, max_trigger_length=60, despike=False, debug=0): """ Internal loop for parellel processing. :type tr: obspy.core.trace :param tr: Trace to look for triggers in. :type parameters: list :param parameters: List of TriggerParameter class for trace. :type max_trigger_length: float :type despike: bool :type debug: int :return: trigger :rtype: list """ from eqcorrscan.utils.despike import median_filter from obspy.signal.trigger import trigger_onset, plot_trigger from obspy.signal.trigger import recursive_sta_lta import warnings for par in parameters: if par['station'] == tr.stats.station and \ par['channel'] == tr.stats.channel: parameter = par break else: msg = 'No parameters set for station ' + str(tr.stats.station) warnings.warn(msg) return [] triggers = [] if debug > 0: print(tr) tr.detrend('simple') if despike: median_filter(tr) if parameter['lowcut'] and parameter['highcut']: tr.filter('bandpass', freqmin=parameter['lowcut'], freqmax=parameter['highcut']) elif parameter['lowcut']: tr.filter('highpass', freq=parameter['lowcut']) elif parameter['highcut']: tr.filter('lowpass', freq=parameter['highcut']) # find triggers for each channel using recursive_sta_lta df = tr.stats.sampling_rate cft = recursive_sta_lta(tr.data, int(parameter['sta_len'] * df), int(parameter['lta_len'] * df)) if max_trigger_length: trig_args = {'max_len_delete': True} trig_args['max_len'] = int(max_trigger_length * df + 0.5) if debug > 3: plot_trigger(tr, cft, parameter['thr_on'], parameter['thr_off']) tmp_trigs = trigger_onset(cft, float(parameter['thr_on']), float(parameter['thr_off']), **trig_args) for on, off in tmp_trigs: cft_peak = tr.data[on:off].max() cft_std = tr.data[on:off].std() on = tr.stats.starttime + \ float(on) / tr.stats.sampling_rate off = tr.stats.starttime + \ float(off) / tr.stats.sampling_rate triggers.append((on.timestamp, off.timestamp, tr.id, cft_peak, cft_std)) return triggers