def _cal_event_snr(tr, signal=[-10, 10], noise=[-100, -50], waterlevel=1.0e-8): """ Calculation of SNR for event data. :param tr: :param signal: :param noise: :param waterlevel: :return: """ tr_sig = tr.copy() tr_noi = tr.copy() t1 = tr.stats.onset + signal[0] t2 = tr.stats.onset + signal[1] if t1 < tr.stats.starttime or t2 > tr.stats.endtime: logging.warning("t1 < tr.stats.starttime") return 0 tr_sig.trim(starttime=t1, endtime=t2) t1 = tr.stats.onset + noise[0] t2 = tr.stats.onset + noise[1] if t1 < tr.stats.starttime or t2 > tr.stats.endtime: logging.warning("t1 < tr.stats.starttime") return 0 tr_noi.trim(starttime=t1, endtime=t2) sig = envelope(tr_sig.data) noi = envelope(tr_noi.data) snr = np.max(sig) / max(np.max(noi), waterlevel) return snr
def test_trace(self): t = np.arange(0, 0.5, self.dt) impuls = np.zeros(len(t)) impuls[0.08 / self.dt] = 1 impuls[0.12 / self.dt] = -1 impuls[0.235 / self.dt] = 1 impuls[0.265 / self.dt] = -1 impuls[0.39 / self.dt] = 1 impuls[0.41 / self.dt] = -1 trace = np.convolve(impuls, self.ricker, mode='same') import matplotlib.pyplot as plt fig = plt.figure() fig.set_facecolor('white') ax1 = fig.add_subplot(211) ax1.plot(t, impuls, 'k') ax2 = fig.add_subplot(212) ax2.plot(trace, 'k') from obspy.signal import filter env = filter.envelope(trace) ifreq = instant_freq(trace, self.dt, np.fft.fft(trace), 0, len(trace) - 1, plot=False) ibw = instant_bw(trace, env, self.dt, np.fft.fft(trace), ponset=0, tend=len(trace), plot=False)
def Collect_All_Envelopes(): min_freq = 12 max_freq = 22 all_trainings =LoadPickle('all_trainings') i = 1 all_envelopes ={name : [] for name in all_trainings.keys()} for name, trainings in all_trainings.items(): print(name) print(i) i = i+1 #Session, signalIdx, block for session in range(0, trainings.shape[0]): for block in range(0,trainings.shape[2]): single_block = trainings[session,:,block][~np.isnan(trainings[session,:,block])] #check if there isnt to many nans if(np.count_nonzero(~np.isnan(single_block)) > 1000): #Filter for bands filt = FilterData(single_block, min_freq, max_freq) #Get envelope envelope = filters.envelope(filt) all_envelopes[name].append(envelope) SavePickle(all_envelopes, 'all_envelopes') return all_envelopes
def calculations(traces1, traces1_norm, traces2, traces2_norm, time_events): global corr_deconv_array, corr_deconv_array_env, half_x_axis, env_max, env_max_sec corr_deconv_array = np.empty([len(traces1_norm), 2 * len(traces1_norm[0])]) # Init empty numpy array # for calculating deconvolution print(corr_deconv_array.shape) a = noise_cross_deconv(traces1_norm[0], traces2_norm[0], fs=500) print(a.shape) for i in range(len(traces1_norm)): corr_deconv_array[i,:] = noise_cross_deconv(traces1_norm[i], traces2_norm[i], fs=500) # Calculating # deconvolution corr_deconv_array_env = np.empty_like(corr_deconv_array) # Init empty array with the same shape as another array for i in range(len(corr_deconv_array)): corr_deconv_array_env[i, :] = envelope(corr_deconv_array[i, :]) half_x_axis = int(np.ceil(len(corr_deconv_array_env[0])/2)) env_max = np.argmax(corr_deconv_array_env[:,half_x_axis:half_x_axis+2000], axis=1) # Index of maximum value # of envelope env_max_sec = env_max / 1000 env_max_deconv_data = np.array([time_events, env_max_sec]) env_max_deconv_data = env_max_deconv_data.T output_filename = 'env_max_deconv_out.dat' np.savetxt(output_filename, env_max_deconv_data, delimiter='\t', header='Day\tTime_when_envelope_has_maximum_value') print(output_filename, ' was saved') data2 = (corr_deconv_array, corr_deconv_array_env, half_x_axis, env_max, env_max_sec) return data2
def ram_norm(tr,winlen,prefilt=None): trace_orig = tr.copy() hlen = int(winlen*tr.stats.sampling_rate/2.) if 2*hlen >= tr.stats.npts: tr.data = np.zeros(tr.stats.npts) return() weighttrace = np.zeros(tr.stats.npts) if prefilt is not None: tr.filter('bandpass',freqmin=prefilt[0],freqmax=prefilt[1],\ corners=prefilt[2],zerophase=True) envlp = envelope(tr.data) for n in xrange(hlen,tr.stats.npts-hlen): weighttrace[n] = np.sum(envlp[n-hlen:n+hlen+1]/(2.*hlen+1)) weighttrace[0:hlen] = weighttrace[hlen] weighttrace[-hlen:] = weighttrace[-hlen-1] tr.data = trace_orig.data / weighttrace
def calculate_preliminiaries(self): """ Calculates the envelope, STA/LTA and the finds the local extrema. """ logger.info("Calculating envelope of synthetics.") self.synthetic_envelope = envelope(self.synthetic.data) logger.info("Calculating STA/LTA.") self.stalta = sta_lta(self.synthetic_envelope, self.observed.stats.delta, self.config.min_period) self.peaks, self.troughs = utils.find_local_extrema(self.stalta) print(self.peaks, self.troughs) #pa if not len(self.peaks) and len(self.troughs): return if self.ttimes: offset = self.event.origin_time - self.observed.stats.starttime min_time = self.ttimes[0]["time"] - \ self.config.max_time_before_first_arrival + offset min_idx = int(min_time / self.observed.stats.delta) dist_in_km = obspy.geodetics.calc_vincenty_inverse( self.station.latitude, self.station.longitude, self.event.latitude, self.event.longitude)[0] / 1000.0 max_time = dist_in_km / self.config.min_surface_wave_velocity + \ offset + self.config.max_period max_idx = int(max_time / self.observed.stats.delta) # Reject all peaks and troughs before the minimal allowed start # time and after the maximum allowed end time. first_trough, last_trough = self.troughs[0], self.troughs[-1] self.troughs = self.troughs[(self.troughs >= min_idx) & (self.troughs <= max_idx)] print(self.troughs) #pa # If troughs have been removed, readd them add the boundaries. if len(self.troughs): if first_trough != self.troughs[0]: self.troughs = np.concatenate([ np.array([min_idx], dtype=self.troughs.dtype), self.troughs ]) if last_trough != self.troughs[-1]: self.troughs = np.concatenate([ self.troughs, np.array([max_idx], dtype=self.troughs.dtype) ]) #pa else: self.troughs = np.concatenate([ np.array([min_idx], dtype=self.troughs.dtype), np.array([max_idx], dtype=self.troughs.dtype) ]) ## # Make sure peaks are inside the troughs! print(self.troughs) #pa min_trough, max_trough = self.troughs[0], self.troughs[-1] self.peaks = self.peaks[(self.peaks > min_trough) & (self.peaks < max_trough)]
def envsac(tr, low, high, delta, debug=False): """ Function to generate an envelope from given seismic data - requires obspy :type tr: obspy.Trace :type low: float :param low: Lowcut in Hz :type high: float :param high: Highcut in Hz :type delta: float :param delta: Sampling interval desired :return env: Envelope as an obspy.Trace object """ from obspy.signal.filter import bandpass, envelope if debug: print 'Detrend' env=tr.detrend('simple') # Demean the data del tr if debug: print 'Resample' env.resample(40) # Downsample to 40Hz if debug: print 'Bandpass' env.data=bandpass(env.data, low, high, env.stats.sampling_rate,\ 3, True) # Filter if debug: print 'Envelope' env.data=envelope(env.data) # Generate envelope if debug: print 'Resample' env.resample(1) # Deimate to 1 Hz return env
def proc_syn_data(): X_orig, y, names = read_syncat() nev = len(y) names = ['Kurtosis', 'MaxMean', 'DomT', 'Dur'] X = np.empty((nev, len(names)), dtype=float) # for each event for i in xrange(nev): otime = X_orig[i] fname = "%s_*MSEED" % (otime) st = read(join(syn_dir, fname)) tr = st[0] starttime = tr.stats.starttime dt = tr.stats.delta # get start and end of signal i_start, i_end = start_end(tr) # trim data tr.trim(starttime=starttime + i_start * dt, endtime=starttime + i_end * dt) # now calculate the attributes kurt = kurtosis(tr.data) env = envelope(tr.data) max_mean = np.max(env) / np.mean(env) dur = (i_end - i_start) * dt X[i, 0] = kurt X[i, 1] = max_mean X[i, 2] = dominant_period(st) X[i, 3] = dur return X, y, names
def test_trace(self): t = np.arange(0,0.5,self.dt) impuls = np.zeros(len(t)) impuls[0.08/self.dt] = 1 impuls[0.12/self.dt] = -1 impuls[0.235/self.dt] = 1 impuls[0.265/self.dt] = -1 impuls[0.39/self.dt] = 1 impuls[0.41/self.dt] = -1 trace = np.convolve(impuls,self.ricker,mode='same') import matplotlib.pyplot as plt fig = plt.figure() fig.set_facecolor('white') ax1 = fig.add_subplot(211) ax1.plot(t,impuls,'k') ax2 = fig.add_subplot(212) ax2.plot(trace,'k') from obspy.signal import filter env = filter.envelope(trace) ifreq = instant_freq(trace, self.dt, np.fft.fft(trace), 0, len(trace)-1, plot=True) ibw = instant_bw(trace, env, self.dt, np.fft.fft(trace), ponset = 0, tend=len(trace), plot=True)
def get_freq_band_stuff(tr, FFI=[0.1, 1, 3, 10, 20], FFE=None, corners=2): # FFI gives the left (low-frequency) side of the butterworth filter to use # FFE gives the right (high-frequency) side of the butterworth filter to use sps = tr.stats.sampling_rate dt = tr.stats.delta NyF = sps / 2. nf = len(FFI) if FFE is None: FFE = np.empty(nf, dtype=float) FFE[0:-1] = FFI[1:nf] FFE[-1] = 0.99 * NyF ES = np.empty(nf, dtype=float) KurtoF = np.empty(nf, dtype=float) for j in xrange(nf): tr_filt = tr.copy() tr_filt.filter('bandpass', freqmin=FFI[j], freqmax=FFE[j], corners=corners) ES[j] = 2 * np.log10(np.trapz(envelope(tr_filt.data), dx=dt)) KurtoF[j] = kurtosis(tr_filt.data, fisher=False) return ES, KurtoF
def test_gaussian_kurtosis(self): data = np.array([gauss(5,1) for i in range(100000)]) from obspy.signal import filter env = filter.envelope(data) KurtosisEnvelope = kurtosis_envelope(env) KurtosisEnvelopeTest = 3 self.assertAlmostEquals(KurtosisEnvelope, KurtosisEnvelopeTest, places = 1)
def Envelope(tr,plot): """Envelope gives the enveloppe of a signal (trace) and return the sum of this enveloppe * input : - tr : type trace; trace -plot type bool; if True waves and envelope are plotted *output : - Envelope : envelope of the signal - t: type list; time where data are computed - SumEnvelope : type float; Sum of the data values of the enveloppe - MaxEnv ; type float; maximum of the envelope *exemple : Envelope, t, SumEnvelope = Envelope(tr) """ Envelope = envelope(tr.data) npts = tr.stats.npts fs = tr.stats.sampling_rate t = np.arange(0,npts/fs,1/fs) #integration of the envelope SumEnvelope = sum(Envelope) #max~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EnvMax = max(Envelope) indexmax= np.argwhere (Envelope==EnvMax) if plot==True: plt.figure() plt.plot(t,tr.data ) plt.plot(t, Envelope, '.g') print EnvMax,indexmax return Envelope, t, SumEnvelope, EnvMax
def _xlim_from_envelope(self, data, dt): """ Get rough bounds for the xlimits by looking at waveform envelopes :return: """ env = envelope(data) idx = np.where(env >= env.std())[0] * dt return [np.floor(idx[0]) - 20, np.ceil(idx[-1]) + 20]
def test_ricker(self): from obspy.signal import filter env = filter.envelope(self.ricker) tf = np.fft.fft(self.ricker) ifreq = instant_freq(self.ricker, self.dt, tf, 50, 150, plot=True) ibw = instant_bw(self.ricker, env, self.dt, tf, plot=True)
def test_ricker(self): from obspy.signal import filter env = filter.envelope(self.ricker) tf = np.fft.fft(self.ricker) ifreq = instant_freq(self.ricker, self.dt, tf, 50, 150, plot=False) ibw = instant_bw(self.ricker, env, self.dt, tf, plot=False)
def process_envelope(self): """ Runs envelope processing on a waveform. Replaces self.trace and sets self.proc to "Envelope'. """ xs = filter.envelope(self.values) self.trace.data = xs self.proc = "Envelope"
def get_var_data(self, P_start_time, full_obs_stream): max_amp = 0 noise_est = full_obs_stream.copy() for trace in noise_est: env = envelope(trace.data) trace.data = env trace.trim(starttime=trace.meta.starttime, endtime=P_start_time) max_amp += max(trace.data) return max_amp / (len(noise_est) * 2)
def test_gaussian_kurtosis(self): data = np.array([gauss(5, 1) for i in range(100000)]) from obspy.signal import filter env = filter.envelope(data) KurtosisEnvelope = kurtosis_envelope(env) KurtosisEnvelopeTest = 3 self.assertAlmostEquals(KurtosisEnvelope, KurtosisEnvelopeTest, places=1)
def envelope(n, e, z, fcorner=None, Ncomponents=3): ''' Build the envelope of a 3- or 2-component accelerogram using the Hilbert transform as implemented in obspy.signal.filter ''' from obspy.signal.filter import envelope from mudpy.forward import lowpass #remove pre-event baseline n[0].data -= n[0].data[0] e[0].data -= e[0].data[0] z[0].data -= z[0].data[0] #Initalize per-component envelopes nenv = n.copy() eenv = e.copy() zenv = z.copy() #make envelopes nenv[0].data = envelope(n[0].data) eenv[0].data = envelope(e[0].data) zenv[0].data = envelope(z[0].data) #combine envelopes into one aenv = n.copy() aenvf = n.copy() #How many components if Ncomponents == 3: aenv[0].data = (nenv[0].data**2 + eenv[0].data**2 + zenv[0].data**2)**0.5 else: aenv[0].data = (nenv[0].data**2 + eenv[0].data**2)**0.5 #Low pass filter envelope if fcorner == None: aenvf = aenv.copy() else: aenvf[0].data = lowpass(aenv[0].data, fcorner, 1. / aenv[0].stats.delta, 2) return aenvf
def process_envelope(tr,w=51): """ Runs envelope processing on a waveform. w is the length of the sliding window """ from obspy.signal import filter env = filter.envelope(tr) s = np.r_[env[w-1:0:-1],env,env[-1:-w:-1]] window = np.ones(w,'d') return np.convolve(window/window.sum(),s,mode='valid')[w/2:-w/2]
def process_envelope(tr, w=51): """ Runs envelope processing on a waveform. w is the length of the sliding window """ from obspy.signal import filter env = filter.envelope(tr) s = np.r_[env[w - 1:0:-1], env, env[-1:-w:-1]] window = np.ones(w, 'd') return np.convolve(window / window.sum(), s, mode='valid')[w / 2:-w / 2]
def transfer_data_into_envelope(data): t1 = time.time() data_env = np.zeros(data.shape) for idx1 in range(data.shape[0]): for idx2 in range(data.shape[1]): data_env[idx1, idx2, :] = envelope(data[idx1, idx2, :]) t2 = time.time() print("Time used to convert envelope: %.2f sec" % (t2 - t1)) return data_env
def envelope(n,e,z,fcorner=None,Ncomponents=3): ''' Build the envelope of a 3- or 2-component accelerogram using the Hilbert transform as implemented in obspy.signal.filter ''' from obspy.signal.filter import envelope from mudpy.forward import lowpass #remove pre-event baseline n[0].data-=n[0].data[0] e[0].data-=e[0].data[0] z[0].data-=z[0].data[0] #Initalize per-component envelopes nenv=n.copy() eenv=e.copy() zenv=z.copy() #make envelopes nenv[0].data=envelope(n[0].data) eenv[0].data=envelope(e[0].data) zenv[0].data=envelope(z[0].data) #combine envelopes into one aenv=n.copy() aenvf=n.copy() #How many components if Ncomponents==3: aenv[0].data=(nenv[0].data**2+eenv[0].data**2+zenv[0].data**2)**0.5 else: aenv[0].data=(nenv[0].data**2+eenv[0].data**2)**0.5 #Low pass filter envelope if fcorner==None: aenvf=aenv.copy() else: aenvf[0].data=lowpass(aenv[0].data,fcorner,1./aenv[0].stats.delta,2) return aenvf
def max_over_mean(trace): """ Returns the maximum of the envelope of a trace over its mean. from Hibert 2012 """ e = filter.envelope(trace) emax = np.max(e) emean = np.mean(e) return emax / emean
def calculate_preliminiaries(self): """ Calculates the envelope, STA/LTA and the finds the local extrema. """ logger.info("Calculating envelope of synthetics.") self.synthetic_envelope = envelope(self.synthetic.data) logger.info("Calculating STA/LTA.") self.stalta = sta_lta(self.synthetic_envelope, self.observed.stats.delta, self.config.min_period) self.peaks, self.troughs = utils.find_local_extrema(self.stalta)
def process_envelope(self): """ Runs envelope processing on a waveform. """ from obspy.signal import filter env = filter.envelope(self.tr) # Smooth the envelope w = 51 # length of the sliding window s = np.r_[env[w-1:0:-1],env,env[-1:-w:-1]] window = np.ones(w,'d') self.tr_env = np.convolve(window/window.sum(),s,mode='valid')[w/2:-w/2]
def max_over_mean(trace): """ Returns the maximum of the envelope of a trace over its mean. from Hibert 2012 """ e = filter.envelope(trace) emax = np.max(e) emean = np.mean(e) return emax/emean
def process_envelope(self): """ Runs envelope processing on a waveform. """ from obspy.signal import filter env = filter.envelope(self.tr) # Smooth the envelope w = 51 # length of the sliding window s = np.r_[env[w - 1:0:-1], env, env[-1:-w:-1]] window = np.ones(w, 'd') self.tr_env = np.convolve(window / window.sum(), s, mode='valid')[w / 2:-w / 2]
def _get_cut_times(config, tr): """Get trace cut times between P arrival and end of envelope coda.""" tr_env = tr.copy() # remove the mean... tr_env.detrend(type='constant') # ...and the linear trend... tr_env.detrend(type='linear') # ...filter freqmin = 1. freqmax = 20. nyquist = 1./(2. * tr.stats.delta) if freqmax >= nyquist: freqmax = nyquist * 0.999 msg = '%s: maximum frequency for bandpass filtering ' % tr.id msg += 'in local magnitude computation is larger than or equal ' msg += 'to Nyquist. Setting it to %s Hz' % freqmax logger.warning(msg) cosine_taper(tr_env.data, width=config.taper_halfwidth) tr_env.filter(type='bandpass', freqmin=freqmin, freqmax=freqmax) tr_env.data = envelope(tr_env.data) tr_env.data = smooth(tr_env.data, 100) # Skip traces which do not have arrivals try: p_arrival_time = tr.stats.arrivals['P'][1] except Exception: logger.warning('%s: Trace has no P arrival: skipping trace' % tr.id) raise RuntimeError t1 = p_arrival_time - config.win_length t2 = p_arrival_time + config.win_length tr_noise = tr_env.copy() tr_signal = tr_env.copy() tr_noise.trim(starttime=t1, endtime=p_arrival_time, pad=True, fill_value=0) tr_signal.trim(starttime=p_arrival_time, endtime=t2, pad=True, fill_value=0) ampmin = tr_noise.data.mean() ampmax = tr_signal.data.mean() if ampmax <= ampmin: logger.warning( '%s: Trace has too high noise before P arrival: ' 'skipping trace' % tr.id) raise RuntimeError trigger = trigger_onset(tr_env.data, ampmax, ampmin, max_len=9e99, max_len_delete=False)[0] t0 = p_arrival_time t1 = t0 + trigger[-1] * tr.stats.delta if t1 > tr.stats.endtime: t1 = tr.stats.endtime return t0, t1
def HVscheme2(st, f0, bazi, astime, aetime, disdeg, eve): st2 = finalfilter(st, f0, bazi, astime, aetime, True) corrs = [] win = int(round(1. / f0, 0)) for window in st2.slide(window_length=win, step=int(round(win / 16., 0))): HilbertV = np.imag(hilbert(window.select(component="Z")[0].data)) lag, corr = xcorr(HilbertV, window.select(component="R")[0].data, 5, full_xcorr=False) #corr = pearsonr(HilbertV, window.select(component="R")[0].data) corrs.append(corr) corr = corrs HilbertV = np.imag(hilbert(st2.select(component="Z")[0].data)) oldx = np.asarray(range( len(corr))) / (float(len(corr)) / float(len(HilbertV))) corr = np.interp(range(len(HilbertV)), oldx, corr) env = envelope(st2.select(component="R")[0].data) * envelope(HilbertV) HV = envelope(st2.select(component="R")[0].data) / envelope(HilbertV) env *= 1. / np.max(np.abs(env)) #corr *= env t = np.asarray(range(len(HilbertV))) lim = t[(corr >= .90)] if len(lim) == 0: return 0., 0., 0. HV2 = HV[(corr >= .90)] lim = lim[(HV2 <= np.mean(HV2) + 3. * np.std(HV2)) & (HV2 >= np.mean(HV2) - 3. * np.std(HV2))] HV2 = HV2[(HV2 <= np.mean(HV2) + 3. * np.std(HV2)) & (HV2 >= np.mean(HV2) - 3. * np.std(HV2))] mHV = np.mean(HV2) stdHV = np.std(HV2) return mHV, stdHV, corr
def get_all_single_station_attributes(st): NaN_value = -12345.0 min_length = 11 # set attribute names att_names = att_names_single_station_1D if st is None or len(st) == 0: # return names of attributes and NaN values att = np.ones((1, len(att_names)), dtype=float) * np.nan return att, att_names if st[0].stats.npts < min_length: # return names of attributes and NaN values att = np.ones((1, len(att_names)), dtype=float) * np.nan return att, att_names # create the amplitude trace and its envelope if len(st) == 3: att_names.extend(list(['rectilinP', 'azimuthP', 'dipP', 'Plani'])) amp_data = np.sqrt(st[0].data * st[0].data + st[1].data * st[1].data + st[2].data * st[2].data) amp_trace = st.select(component="Z")[0].copy() amp_trace.data = amp_data else: try: amp_trace = st.select(component="Z")[0] except IndexError: att = np.ones((1, len(att_names)), dtype=float) * np.nan return att, att_names env = envelope(amp_trace.data) if len(st) == 3: att_names.extend(list(['rectilinP', 'azimuthP', 'dipP', 'Plani'])) att = np.empty((1, len(att_names)), dtype=float) att[0, 0:1] = get_AsDec(amp_trace, env) att[0, 1:2] = get_Duration(amp_trace) att[0, 2:5] = get_RappStuff(amp_trace, env) att[0, 5:9] = get_KurtoSkew(amp_trace, env) att[0, 9:11] = get_CorrStuff(amp_trace) ES, KurtoF = get_freq_band_stuff(amp_trace) att[0, 11:16] = ES[:] att[0, 16:21] = KurtoF[:] att[0, 21:38] = get_full_spectrum_stuff(amp_trace) att[0, 38:40] = get_AmpStuff(amp_trace) if len(st) == 3: att[0, 40:44] = get_polarization_stuff(st, env) return att, att_names
def filter(self, stream, time_at_rec, la_s, lo_s, depth, Rayleigh=True): env_stream = Stream() dist, az, baz = gps2dist_azimuth(lat1=la_s, lon1=lo_s, lat2=self.prior['la_r'], lon2=self.prior['lo_r'], a=self.prior['radius'], f=0) if Rayleigh == True: phases = self.get_R_phases(time_at_rec) else: phases = self.get_L_phases(time_at_rec) for i, v in enumerate(stream.traces): npts = len(v.data) trace = stream.traces[i].copy() trace.detrend(type="demean") trace.interpolate( sampling_rate=10. / phases[i]['dt'] ) # No method specified, so : 'weighted_average_slopes' is used trace.filter('highpass', freq=phases[i]['fmin'], zerophase=True) trace.filter('lowpass', freq=phases[i]['fmax'], zerophase=True) trace.detrend() trace.detrend(type="demean") env = envelope(trace.data) zero_trace = Trace(np.zeros(npts), header={ "starttime": phases[i]['starttime'](dist, depth), 'delta': trace.meta.delta, "station": trace.meta.station, "network": trace.meta.network, "location": trace.meta.location, "channel": trace.meta.channel, "instaseis": trace.meta.instaseis }) env_trace = Trace(env, header={ "starttime": phases[i]['starttime'](dist, depth), 'delta': trace.meta.delta, "station": trace.meta.station, "network": trace.meta.network, "location": trace.meta.location, "channel": trace.meta.channel, "instaseis": trace.meta.instaseis }) env_stream.append(env_trace) return env_stream
def test_network_response_plot(self): detections = [(self.st[0].stats.starttime + 10).datetime, ] false_detections = [(self.st[0].stats.starttime + 20).datetime, ] _envelope = self.st.copy() for tr in _envelope: tr.data = filter.envelope(tr.data) envelope = Stream(_envelope[0]) for tr in envelope[1:]: envelope[0].data += tr.data envelope.detrend() fig = NR_plot(stream=self.st, NR_stream=envelope, detections=detections, false_detections=false_detections, show=False, return_figure=True) return fig
def SpecWhiten(trace): if specWhiten_method == 0: return trace else: dataFFT = np.fft.fft(trace.data) if specWhiten_method == 1: envelope = filter.envelope(np.abs(dataFFT)) dataFFT = dataFFT / envelope else: dataFFT = dataFFT / np.abs(dataFFT) trace.data = np.real(np.fft.ifft(dataFFT)) return trace
def stream_envelope(st): """ Calculate the envelopes of all traces in a stream. It works on a copy of the stream. :type st: ::class:`~obspy.core.stream.Stream` :param st: Stream fo be used for calculating the envelopes. :rtype sst: :class:`~obspy.core.stream.Stream` :return: **sst**: envelopes of stream """ for tr in st: tr.data = envelope(tr.data) return st
def get_RappStuff(tr, env=None): # get max over mean / median / std if env is None: env = envelope(tr.data) max_env = max(env) smooth_norm_env = sp.smooth(env / max_env) RappMaxMean = 1. / np.mean(smooth_norm_env) RappMaxMedian = 1. / np.median(smooth_norm_env) RappMaxStd = 1. / np.std(smooth_norm_env) return RappMaxMean, RappMaxMedian, RappMaxStd
def get_AsDec(tr, env=None): # smooth data using a filter of the same length as the sampling rate # to give 1-second smoothing window if env is None: env = envelope(tr.data) smooth_env = sp.smooth(env) imax = np.argmax(smooth_env) AsDec = (imax + 1) / float(len(tr.data) + 1 - (imax + 1)) # note : the +1s are to avoid zeros or division by zero return AsDec
def calculate_preliminiaries(self): """ Calculates the envelope, STA/LTA and the finds the local extrema. """ logger.info("Calculating envelope of synthetics.") self.synthetic_envelope = envelope(self.synthetic.data) logger.info("Calculating STA/LTA.") self.stalta = sta_lta(self.synthetic_envelope, self.observed.stats.delta, self.config.min_period) self.peaks, self.troughs = utils.find_local_extrema(self.stalta) if not len(self.peaks) and len(self.troughs): return if self.ttimes: offset = self.event.origin_time - self.observed.stats.starttime min_time = self.ttimes[0]["time"] - \ self.config.max_time_before_first_arrival + offset min_idx = int(min_time / self.observed.stats.delta) dist_in_km = geodetics.calcVincentyInverse( self.station.latitude, self.station.longitude, self.event.latitude, self.event.longitude)[0] / 1000.0 max_time = dist_in_km / self.config.min_surface_wave_velocity + \ offset + self.config.max_period max_idx = int(max_time / self.observed.stats.delta) # Reject all peaks and troughs before the minimal allowed start # time and after the maximum allowed end time. first_trough, last_trough = self.troughs[0], self.troughs[-1] self.troughs = self.troughs[(self.troughs >= min_idx) & (self.troughs <= max_idx)] # If troughs have been removed, readd them add the boundaries. if len(self.troughs): if first_trough != self.troughs[0]: self.troughs = np.concatenate([ np.array([min_idx], dtype=self.troughs.dtype), self.troughs]) if last_trough != self.troughs[-1]: self.troughs = np.concatenate([ self.troughs, np.array([max_idx], dtype=self.troughs.dtype)]) # Make sure peaks are inside the troughs! min_trough, max_trough = self.troughs[0], self.troughs[-1] self.peaks = self.peaks[(self.peaks > min_trough) & (self.peaks < max_trough)]
def make_env(st, lowpass=0.2): from obspy.signal.filter import envelope for tr in st: tr.data = envelope(tr.data) st.filter('lowpass', freq=lowpass) sr = st[0].stats.sampling_rate if sr == 25: st.decimate(5) elif sr == 20: st.decimate(2) st.decimate(2) return st
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 envelope(self, traces=None): """ Take the envelope of the data. :param traces: List of ``SEGYTrace`` objects with data to operate on. Default is to operate on all traces. Computes the envelope of the given function. The envelope is determined by adding the squared amplitudes of the function and it's Hilbert-Transform and then taking the square-root. (See [Kanasewich1981]_) The envelope at the start/end should not be taken too seriously. """ if not traces: traces = self.traces for tr in traces: tr.data = filter.envelope(tr.data)
def getAmplitudeEnvelopeFeaturesReal(traceName = '/home/anton/WI_Models/AllTraces/M0055_station_0003_location_Class036_channel_Z.mseed', st=1.2,fn=2.2,fmin=1,fmax=10,starttime=None,endtime=None ): import obspy import numpy as np from obspy.signal.filter import envelope from scipy.integrate import simps from scipy.stats import kurtosis trace = obspy.read(traceName) if trace[0].stats.starttime.year < starttime.year: return None trace.taper(type= "hann",max_percentage=0.2) trace.filter(type='bandpass',freqmin=fmin,freqmax=fmax) trace.trim(starttime = starttime,endtime = endtime) trace.normalize() trace.taper(type= "cosine",max_percentage=0.05) trace.plot(type='relative') #data_envelopeM = obspy.signal.filter.envelope(trace.data) TraceCopy = trace[0].copy() envTrace = trace[0].copy() envTrace.data = envelope(TraceCopy.data) # Feature 0 : peakedness KurtosisEnvelopeDiff =kurtosis(np.diff(envTrace.data)) # Feature 1 StdEnvelope = envTrace.data.std() # Feature 2 MeanEnvelope = envTrace.data.mean() envTrace.trim(starttime = trace[0].stats.starttime + st,endtime = trace[0].stats.starttime + fn) TraceCopy.trim(starttime = trace[0].stats.starttime + st,endtime = trace[0].stats.starttime + fn) #Integrate the envelope in the region: # Feature 3 EnvelopeIntegral = simps(y = envTrace.data,x = envTrace.times()) / (envTrace.stats.endtime - envTrace.stats.starttime) EnergyInTheSubTrace = simps(y = TraceCopy.data**2,x = TraceCopy.times()) EnergyWholeTrace = simps(y = trace[0].data**2,x = trace[0].times()) #Feature 4 EnergyRatio = EnergyInTheSubTrace/EnergyWholeTrace #Feature 5 zc= np.sign( np.diff(envTrace.data) ) zc[zc==0] = -1 # replace zeros with -1 zcFeature = np.where(np.diff(zc))[0].shape[0] return KurtosisEnvelopeDiff,StdEnvelope,MeanEnvelope,EnvelopeIntegral,EnergyRatio,zcFeature
def get_KurtoSkew(tr, env=None): if env is None: env = envelope(tr.data) max_env = max(env) smooth_norm_env = sp.smooth(env / max_env) max_sig = max(tr.data) norm_sig = tr.data / max_sig KurtoEnv = kurtosis(smooth_norm_env, fisher=False) KurtoSig = kurtosis(norm_sig, fisher=False) SkewnessEnv = skew(smooth_norm_env) SkewnessSig = skew(norm_sig) return KurtoEnv, KurtoSig, SkewnessEnv, SkewnessSig
def test_envelopeVsPitsa(self): """ Test Envelope filter against PITSA. The rms is not so good, but the fit is still good in most parts. """ # load test file filename = os.path.join(self.path, 'rjob_20051006.gz') with gzip.open(filename) as f: data = np.loadtxt(f) # filter trace datcorr = envelope(data) # load pitsa file filename = os.path.join(self.path, 'rjob_20051006_envelope.gz') with gzip.open(filename) as f: data_pitsa = np.loadtxt(f) # calculate normalized rms rms = np.sqrt(np.sum((datcorr - data_pitsa) ** 2) / np.sum(data_pitsa ** 2)) self.assertEqual(rms < 1.0e-02, True)
def slope_distribution(fkdata, prange, pdelta, peakpick=None, delta_threshold=0, smoothing=False, interactive=False): """ Generates a distribution of slopes in a range given in prange. Needs fkdata as input. k on the y-axis fkdata[0] f on the x-axis fkdata[1] :param fkdata: array-like dataset transformed to f-k domain. :param prange: range of slopes, with minimum and maximum value Slopes are defined as nondimensional, by the formula m = 1/2 * (ymax - ymin)/(xmax - xmin), respectively p = 1/2 * (kmax - kmin)/(fmax - fmin). The factor 1/2 is due too the periodicity in the f-k domain. :type prange: array-like, tuple or list :param pdelta: stepsize of slope-interval :type pdelta: int :param peakpick: method to pick the peaks of distribution possible is: mod - minimum mean of distribution (default) mop - minimum mean of peaks float - minimum float value None - pick all peaks :type peakpick: int or float :param delta_threshold: Value to lower manually :type delta_threshold: int :param smoothing: Parameter to smooth distribution :type smoothing: float :param interactive: If True, picking by hand is enabled. :type interactive: boolean returns: :param MD: Magnitude distribution of the slopes p :type MD: 1D array, numpy.ndarray :param prange: Range of slopes :type prange: 1D array, numpy.ndarray :param peaks: position ( peaks[0] ) and value ( peaks[1] ) of the peaks. :type peaks: numpy.ndarray """ M = fkdata.copy() Mt = M.conj().transpose() fk_shift = np.zeros(M.shape).astype('complex') pnorm = 1/2. * ( float(M.shape[0])/float(M.shape[1]) ) pmin = prange[0] pmax = prange[1] N = abs(pmax - pmin) / pdelta + 1 MD = np.zeros(N) srange = np.linspace(pmin,pmax,N) rend = float( len(srange) ) for i, delta in enumerate(srange): p = delta*pnorm for j, trace in enumerate(Mt): shift = int(math.floor(p*j)) fk_shift[:,j] = np.roll(trace, shift) MD[i] = sum(abs(fk_shift[0,:])) / len(fk_shift[0,:]) prcnt = 100*(i+1) / rend print("%i %% done" % prcnt, end="\r") sys.stdout.flush() if interactive: peaks = pick_data(srange, MD, 'Slope in fk-domain', 'Magnitude of slope', 'Magnitude-Distribution') for j,pairs in enumerate(peaks): if len(pairs) > 1: maxm = 0 for i, item in enumerate(pairs): if item[1] > maxm: maxm = item[1] idx = i peaks[j] = [(pairs[idx][0], maxm)] peaks = np.array(peaks).reshape(len(peaks), 2).transpose() else: if smoothing: blen = int(abs(pmin-pmax))*smoothing if blen < 1 : blen=1 MDconv = sp.signal.convolve(MD, sp.signal.boxcar(blen),mode=1) else: MDconv=MD peaks_first = find_peaks(MDconv, srange, peakpick='All', mindist=0.3) peaks_first[1] = peaks_first[1]/peaks_first.max()*MD.max() # Calculate envelope of the picked peaks, and pick the # peaks of the envelope. peak_env = obsfilter.envelope( peaks_first[1] ) peaks_tmp = find_peaks( peaks_first[1], peaks_first[0], peak_env.mean() + delta_threshold) if peaks_tmp[0].size > 4: peaks = find_peaks( peaks_tmp[1], peaks_tmp[0], 0.5 + delta_threshold) else: peaks = peaks_tmp return MD, srange, peaks
def cross_net(stream, env=False, debug=0, master=False): """ Generate picks using a simple envelope cross-correlation. Picks are made for each channel based on optimal moveout \ defined by maximum cross-correlation with master trace. Master trace \ will be the first trace in the stream. :type stream: :class: obspy.Stream :param stream: Stream to pick :type env: bool :param env: To compute cross-correlations on the envelope or not. :type debug: int :param debug: Debug level from 0-5 :type master: obspy.Trace :param master: Trace to use as master, if False, will use the first trace \ in stream. :returns: obspy.core.event.Event .. rubric:: Example >>> from obspy import read >>> from eqcorrscan.utils.picker import cross_net >>> st = read() >>> event = cross_net(st, env=True) >>> event.creation_info.author 'EQcorrscan' """ from obspy.signal.cross_correlation import xcorr from obspy.signal.filter import envelope from obspy import UTCDateTime from obspy.core.event import Event, Pick, WaveformStreamID from obspy.core.event import CreationInfo, Comment, Origin import matplotlib.pyplot as plt import numpy as np event = Event() event.origins.append(Origin()) event.creation_info = CreationInfo(author='EQcorrscan', creation_time=UTCDateTime()) event.comments.append(Comment(text='cross_net')) samp_rate = stream[0].stats.sampling_rate if not env: if debug > 2: print('Using the raw data') st = stream.copy() st.resample(samp_rate) else: st = stream.copy() if debug > 2: print('Computing envelope') for tr in st: tr.resample(samp_rate) tr.data = envelope(tr.data) if debug > 2: st.plot(equal_scale=False, size=(800, 600)) if not master: master = st[0] else: master = master master.data = np.nan_to_num(master.data) for i, tr in enumerate(st): tr.data = np.nan_to_num(tr.data) if debug > 2: msg = ' '.join(['Comparing', tr.stats.station, tr.stats.channel, 'with the master']) print(msg) shift_len = int(0.3 * len(tr)) if debug > 2: print('Shift length is set to ' + str(shift_len) + ' samples') if debug > 3: index, cc, cc_vec = xcorr(master, tr, shift_len, full_xcorr=True) cc_vec = np.nan_to_num(cc_vec) if debug > 4: print(cc_vec) fig = plt.figure() ax1 = fig.add_subplot(211) x = np.linspace(0, len(master) / samp_rate, len(master)) ax1.plot(x, master.data / float(master.data.max()), 'k', label='Master') ax1.plot(x + (index / samp_rate), tr.data / float(tr.data.max()), 'r', label='Slave shifted') ax1.legend(loc="lower right", prop={'size': "small"}) ax1.set_xlabel("time [s]") ax1.set_ylabel("norm. amplitude") ax2 = fig.add_subplot(212) print(len(cc_vec)) x = np.linspace(0, len(cc_vec) / samp_rate, len(cc_vec)) ax2.plot(x, cc_vec, label='xcorr') # ax2.set_ylim(-1, 1) # ax2.set_xlim(0, len(master)) plt.show() index, cc = xcorr(master, tr, shift_len) wav_id = WaveformStreamID(station_code=tr.stats.station, channel_code=tr.stats.channel, network_code=tr.stats.network) event.picks.append(Pick(time=tr.stats.starttime + (index / tr.stats.sampling_rate), waveform_id=wav_id, phase_hint='S', onset='emergent')) if debug > 2: print(event.picks[i]) event.origins[0].time = min([pick.time for pick in event.picks]) - 1 event.origins[0].latitude = float('nan') event.origins[0].longitude = float('nan') # Set arbitrary origin time del st return event
def cross_net(stream, env=False, debug=0, master=False): r"""Function to generate picks for each channel based on optimal moveout \ defined by maximum cross-correaltion with master trace. Master trace \ will be the first trace in the stream. :type stream: :class: obspy.Stream :param stream: Stream to pick :type envelope: bool :param envelope: To compute cross-correlations on the envelope or not. :type debug: int :param debug: Debug level from 0-5 :type master: obspy.Trace :param master: Trace to use as master, if False, will use the first trace \ in stream. :returns: list of pick class """ from obspy.signal.cross_correlation import xcorr from obspy.signal.filter import envelope from eqcorrscan.utils.Sfile_util import PICK import matplotlib.pyplot as plt import numpy as np picks = [] samp_rate = stream[0].stats.sampling_rate if not env: if debug > 2: print('Using the raw data') st = stream.copy() st.resample(samp_rate) else: st = stream.copy() if debug > 2: print('Computing envelope') for tr in st: tr.resample(samp_rate) tr.data = envelope(tr.data) if debug > 2: st.plot(equal_scale=False, size=(800, 600)) if not master: master = st[0] else: master = master master.data = np.nan_to_num(master.data) for tr in st: tr.data = np.nan_to_num(tr.data) if debug > 2: msg = ' '.join(['Comparing', tr.stats.station, tr.stats.channel, 'with the master']) print(msg) shift_len = int(0.3 * len(tr)) if debug > 2: print('Shift length is set to ' + str(shift_len) + ' samples') if debug > 3: index, cc, cc_vec = xcorr(master, tr, shift_len, full_xcorr=True) cc_vec = np.nan_to_num(cc_vec) if debug > 4: print(cc_vec) fig = plt.figure() ax1 = fig.add_subplot(211) x = np.linspace(0, len(master) / samp_rate, len(master)) ax1.plot(x, master.data / float(master.data.max()), 'k', label='Master') ax1.plot(x + (index / samp_rate), tr.data / float(tr.data.max()), 'r', label='Slave shifted') ax1.legend(loc="lower right", prop={'size': "small"}) ax1.set_xlabel("time [s]") ax1.set_ylabel("norm. amplitude") ax2 = fig.add_subplot(212) print(len(cc_vec)) x = np.linspace(0, len(cc_vec) / samp_rate, len(cc_vec)) ax2.plot(x, cc_vec, label='xcorr') # ax2.set_ylim(-1, 1) # ax2.set_xlim(0, len(master)) plt.show() index, cc = xcorr(master, tr, shift_len) pick = PICK(station=tr.stats.station, channel=tr.stats.channel, impulsivity='E', phase='S', weight='1', time=tr.stats.starttime + (index / tr.stats.sampling_rate)) if debug > 2: print(pick) picks.append(pick) del st return picks
from obspy.core import read from obspy.signal.filter import envelope import matplotlib.pyplot as plt import numpy as np st = read('http://examples.obspy.org/COP.BHZ.DK.2009.050') tr = st[0] tr.trim(starttime=tr.stats.starttime, endtime=tr.stats.starttime+60*4) tr.filter('lowpass', freq=.2) env = envelope(tr.data) t = np.linspace(0, 1, len(env)) fig = plt.figure() ax = fig.gca() ax.plot(t, tr.data, alpha=.6, color='k', lw=.75) ax.set_title('') ax.plot(t, env, linestyle='-', color='k', label='Envelope') #ax.legend(loc=1) ax.set_xticklabels('') ax.set_yticklabels('') ax.set_xlabel('Zeit') ax.set_ylabel('Amplitude') fig.set_size_inches(10, 3) fig.savefig('../envelope.png', dpi=150)
print(dt) df = 1.0 / dt t1 = 60 * dt print(dt) print(len(data[1].data)) data.plot() # trN=data[1].copy() trNfil = data.copy() # trNfil.filter('highpass',freq=0.5,corners=2,zerophase=True) trNfil.filter("bandpass", freqmin=1, freqmax=20, corners=2, zerophase=True) trNfil.taper(type="cosine", max_percentage=0.05) cft = classicSTALTA(trNfil[2].data, int(4 / dt), int(30 / dt)) envel = envelope(trNfil[2].data) plt.plot(trNfil[2].data) plt.plot(envel, c="r") plt.xlim(7500, 8000) plt.show # In[48]: tmp = trNfil[0].copy() tmp.spectrogram(log=True) # In[4]:
def process_envelope(self): """ Runs envelope processing on a waveform. """ from obspy.signal import filter self.tr_env = filter.envelope(self.tr)