def semblance(st, s, baz, winlen): ''' Returns the semblance for a seismic array, for a beam of given slowness and backazimuth. Parameters ---------- st : ObsPy Stream object Stream of SAC format seismograms for the seismic array, length K = no. of stations in array s : float Magnitude of slowness vector, in s / km baz : float Backazimuth of slowness vector, (i.e. angle from North back to epicentre of event) winlen : int Length of Hann window over which to calculate the semblance. Returns ------- semblance : NumPy array The semblance at the given slowness and backazimuth, as a time series. ''' # Check that each channel has the same number of samples, otherwise we can't construct the beam properly assert len(set([ len(tr) for tr in st ])) == 1, "Traces in stream have different lengths, cannot stack." nsta = len(st) stack = linear_stack(st, s, baz) # Taper the linear stack stack_trace = Trace(stack) stack_trace.taper(type='cosine', max_percentage=0.05) stack = stack_trace.data shifts = get_shifts(st, s, baz) # Smooth data with sliding Hann window (i.e. convolution of signal and window function) window = np.hanning(winlen) shifted_st = st.copy() for i, tr in enumerate(shifted_st): tr.data = np.roll(tr.data, shifts[i]) # Shift data in each trace by its offset tr.taper(type='cosine', max_percentage=0.05) # Taper it # Calculate the power in the beam beampower = np.convolve(stack**2, window, mode='same') # Calculate the summed power of each trace tracepower = np.convolve(np.sum([tr.data**2 for tr in shifted_st], axis=0), window, mode='same') # Calculate semblance semblance = nsta * beampower / tracepower return semblance
def test_taper(self): """ Test taper method of trace """ data = np.ones(10) tr = Trace(data=data) tr.taper() for i in range(len(data)): self.assertLessEqual(tr.data[i], 1.) self.assertGreaterEqual(tr.data[i], 0.)
def test_taper(self): """ Test taper method of trace """ data = np.ones(10) tr = Trace(data=data) tr.taper() for i in range(len(data)): self.assertTrue(tr.data[i] <= 1.) self.assertTrue(tr.data[i] >= 0.)
def test_taper(self): """ Test taper method of trace """ data = np.ones(10) tr = Trace(data=data) tr.taper() for i in range(len(data)): self.assertTrue(tr.data[i] <= 1.) self.assertTrue(tr.data[i] >= 0.)
def semblance(st, s, baz, winlen): """ Returns the semblance for a seismic array, for a beam of given slowness and backazimuth. Parameters ---------- st : ObsPy Stream object Stream of SAC format seismograms for the seismic array, length K = no. of stations in array s : float Magnitude of slowness vector, in s / km baz : float Backazimuth of slowness vector, (i.e. angle from North back to epicentre of event) winlen : int Length of Hann window over which to calculate the semblance. Returns ------- semblance : NumPy array The semblance at the given slowness and backazimuth, as a time series. """ # Check that each channel has the same number of samples, otherwise we can't construct the beam properly assert len(set([len(tr) for tr in st])) == 1, "Traces in stream have different lengths, cannot stack." nsta = len(st) stack = linear_stack(st, s, baz) # Taper the linear stack stack_trace = Trace(stack) stack_trace.taper(type="cosine", max_percentage=0.05) stack = stack_trace.data shifts = get_shifts(st, s, baz) # Smooth data with sliding Hann window (i.e. convolution of signal and window function) window = np.hanning(winlen) shifted_st = st.copy() for i, tr in enumerate(shifted_st): tr.data = np.roll(tr.data, shifts[i]) # Shift data in each trace by its offset tr.taper(type="cosine", max_percentage=0.05) # Taper it # Calculate the power in the beam beampower = np.convolve(stack ** 2, window, mode="same") # Calculate the summed power of each trace tracepower = np.convolve(np.sum([tr.data ** 2 for tr in shifted_st], axis=0), window, mode="same") # Calculate semblance semblance = nsta * beampower / tracepower return semblance
def st(data, minfreq=0, maxfreq=None, samprate=None, freqsamprate=1, remove_edge=False, analytic_signal=False, factor=1): if data.shape[0] <= 1 or len(data.shape) > 1: raise TypeError('input data invalid ,please check!') if not maxfreq and not samprate: #regard signal as 1 second length maxfreq = len(data) // 2 samprate = len(data) if maxfreq and not samprate: samprate = len(data) if not maxfreq and samprate: maxfreq = samprate // 2 orig = copy.copy(data) st_res = np.zeros((int((maxfreq - minfreq) / freqsamprate) + 1, len(data)), dtype='c8') if remove_edge: print( 'remove_edge selected; Remove trend with polynomial fit and taper!' ) try: from obspy.core import Trace except ModuleNotFoundError: print('Obspy not found ,please install Obspy!') sys.exit() tmp = Trace(data=orig) tmp.detrend('polynomial', order=2) tmp.taper(0.04) orig = tmp.data if analytic_signal: print('analytic_signal selected; Calculating analytic signal!') orig = signal.hilbert(orig) vec = np.hstack((np.fft.fft(orig), np.fft.fft(orig))) if minfreq == 0: st_res[0] = np.mean(orig) * np.ones(len(data)) else: st_res[0] = np.fft.ifft(vec[minfreq:minfreq + len(data)] * g_window(len(data), minfreq, factor)) for i in range(freqsamprate, (maxfreq - minfreq) + 1, freqsamprate): st_res[int(i / freqsamprate)] = np.fft.ifft( vec[minfreq + i:minfreq + i + len(data)] * g_window(len(data), minfreq + i, factor)) return st_res
def create_kiknet_acc(recid, path_kiknet_folder, fminNS2, fmaxNS2, fminEW2, fmaxEW2): """ KiK-net acc are stored within Database_small.hdf5 file """ # Import libraries import numpy as np from obspy.core import Trace, UTCDateTime import re from obspy.signal import filter # desc1 = "" # desc2 = "" time1 = [] time2 = [] inp_acc1 = [] inp_acc2 = [] npts1 = [] npts2 = [] for i in range(1, 3): if i == 1: comp = 'EW2' fmin = fminEW2 fmax = fmaxEW2 elif i == 2: comp = 'NS2' fmin = fminNS2 fmax = fmaxNS2 file_acc = path_kiknet_folder + '/' + str(recid) + '/' + str( recid) + '.' + comp hdrnames = [ 'Origin Time', 'Lat.', 'Long.', 'Depth. (km)', 'Mag.', 'Station Code', 'Station Lat.', 'Station Long.', 'Station Height(m)', 'Record Time', 'Sampling Freq(Hz)', 'Duration Time(s)', 'Dir.', 'Scale Factor', 'Max. Acc. (gal)', 'Last Correction', 'Memo.' ] acc_data = [] time = [] with open(file_acc, 'r') as f: content = f.readlines() counter = 0 for line in content: if counter < 17: if not line.startswith(hdrnames[counter]): sys.exit("Expected line to start with %s but got %s " % (hdrnames[counter], line)) else: flds = line.split() if (counter == 0): origin_time = flds[2] + ' ' + flds[3] origin_time = UTCDateTime.strptime(origin_time, '%Y/%m/%d %H:%M:%S') # All times are in Japanese standard time which is 9 hours ahead of UTC origin_time -= 9 * 3600. elif (counter == 1): lat = float(flds[1]) elif (counter == 2): lon = float(flds[1]) elif (counter == 3): dp = float(flds[2]) elif (counter == 4): mag = float(flds[1]) elif (counter == 5): stnm = flds[2] elif (counter == 6): stla = float(flds[2]) elif (counter == 7): stlo = float(flds[2]) elif (counter == 8): stel = float(flds[2]) elif (counter == 9): record_time = flds[2] + ' ' + flds[3] # A 15 s delay is added to the record time by the # the K-NET and KiK-Net data logger record_time = UTCDateTime.strptime(record_time, '%Y/%m/%d %H:%M:%S') - 15.0 # All times are in Japanese standard time which is 9 hours ahead of UTC record_time -= 9 * 3600. elif (counter == 10): freqstr = flds[2] m = re.search('[0-9]*', freqstr) freq = int(m.group()) elif (counter == 11): duration = float(flds[2]) elif (counter == 12): channel = flds[1].replace('-', '') kiknetcomps = { '1': 'NS1', '2': 'EW1', '3': 'UD1', '4': 'NS2', '5': 'EW2', '6': 'UD2' } if channel.strip() in kiknetcomps.keys( ): # kiknet directions are 1-6 channel = kiknetcomps[channel.strip()] elif (counter == 13): eqn = flds[2] num, denom = eqn.split('/') num = float(re.search('[0-9]*', num).group()) denom = float(denom) # convert the calibration from gal to m/s^2 calib = 0.01 * num / denom elif (counter == 14): accmax = float(flds[3]) elif (counter == 15): last_correction = flds[2] + ' ' + flds[3] last_correction = UTCDateTime.strptime(last_correction, '%Y/%m/%d %H:%M:%S') # All times are in Japanese standard time which is 9 hours ahead of UTC last_correction -= 9 * 3600. elif counter > 16: data = str(line).split() for value in data: a = float(value) acc_data.append(a) counter = counter + 1 data = np.array(acc_data) tr = Trace(data) tr.detrend("linear") tr.taper(max_percentage=0.05, type='cosine', side='both') filter_order = 4 pad = np.zeros(int(round(1.5 * filter_order / fmin * freq))) tr.data = np.concatenate([pad, tr.data, pad]) fN = freq / 2 if fmax < fN: tr.data = filter.bandpass(tr.data, freqmin=fmin, freqmax=fmax, df=freq, corners=4, zerophase=True) else: tr.data = filter.highpass(tr.data, freq=fmin, df=freq, corners=4, zerophase=True) tr.data = tr.data[len(pad):len(tr.data) - len(pad)] tr.data = tr.data * calib / 9.81 #in g npts = len(tr.data) time = [] for j in range(0, npts): t = j * 1 / freq time.append(t) time = np.asarray(time) if i == 1: inp_acc1 = tr.data npts1 = npts time1 = time if i == 2: inp_acc2 = tr.data npts2 = npts time2 = time return time1, time2, inp_acc1, inp_acc2, npts1, npts2
i_max = np.argmax(abs(filt_stf)) ind = nstep - 1 while (filt_stf[ind] < tol): ind -= 1 delay = ind - i_max print 'Delay used : ' + str(delay) # 2 : Apply delay and bandpass source time function delayed_stf = np.zeros(nstep + delay) delayed_stf[-nstep:] = np.array(stf) resu = bandpass(delayed_stf, freqmin, freqmax, df, zerophase=True) t = Trace() t.data = resu t.taper(0.005, type='hann') resu = t.data if resamp == 1: resu = resample(resu[:nstep], int(1.5 * nstep_resamp))[:nstep_resamp] plt.figure(1) plt.plot(resu) #plt.figure(1) #plt.plot(result) plt.plot(delayed_stf) plt.show() stf = open("my_filtered_stf.txt", "w") for i in range(0, nstep_resamp): #nstep + delay): stf.write("%d " % i)