def build_tt_tables(minlat=None, maxlat=None, minlon=None, maxlon=None, channel_codes=['EH', 'BH', 'HH'], db=None, maxdist=500., source_depth=5.): """ channel_codes select channels that start with those codes maximum distance is in km source depth is generally set to the average earthquake depth for the region you are working for more granularity use the 3D associator """ # Create a connection to an sqlalchemy database tt_engine = create_engine(db, echo=False) tt_stations_1D.BaseTT1D.metadata.create_all(tt_engine) TTSession = sessionmaker(bind=tt_engine) tt_session = TTSession() # Create a cliet to IRIS FDSN fdsnclient = fdsn.Client("IRIS") # Create an obspy inventory of stations #http://docs.obspy.org/packages/autogen/obspy.clients.fdsn.client.Client.get_stations.html#obspy.clients.fdsn.client.Client.get_stations inv = fdsnclient.get_stations(minlatitude=minlat, maxlatitude=maxlat, minlongitude=minlon, maxlongitude=maxlon, level='channel') # Plot our results just for fun inv.plot(projection='ortho', color_per_network='True') # Now save these station into the 1D travel-time table database # The associator could be modified to interact with Obspy Inventory objects for net in inv: network = net.code for sta in net: loccodes = [] for ch in sta: # print(ch) # print(dir(ch)) for cc in channel_codes: if re.match(cc, ch.code): if not ch.location_code in loccodes: loccodes.append(ch.location_code) for loc in loccodes: station = tt_stations_1D.Station1D(sta.code, network, loc, sta.latitude, sta.longitude, sta.elevation) # Save the station locations in the database tt_session.add(station) tt_session.commit() # Now we have to build our traveltime lookup tables # We will use IASP91 here but obspy.taup does let you build your own model velmod = taup.TauPyModel(model='iasp91') # Define our distances we want to use in our lookup table delta_distance = 1. # km for spacing tt calculations # Probably better to use a progressive type scheme instead of linear, but this is an example distance_km = np.arange(0, maxdist + delta_distance, delta_distance) for d_km in distance_km: d_deg = geodetics.kilometer2degrees(d_km) ptimes = [] stimes = [] p_arrivals = velmod.get_travel_times(source_depth_in_km=source_depth, distance_in_degree=d_deg, phase_list=['P', 'p']) for p in p_arrivals: ptimes.append(p.time) s_arrivals = velmod.get_travel_times(source_depth_in_km=source_depth, distance_in_degree=d_deg, phase_list=['S', 's']) for s in s_arrivals: stimes.append(s.time) tt_entry = tt_stations_1D.TTtable1D(d_km, d_deg, np.min(ptimes), np.min(stimes), np.min(stimes) - np.min(ptimes)) tt_session.add(tt_entry) tt_session.commit( ) # Probably faster to do the commit outside of loop but oh well tt_session.close() return inv
datetimefile = value iscustom = 1 elif op == "-B": timerange = value elif op == "-C": chan = value elif op == "-L": loca = value elif op == "-F": fformat = value elif op == "-P": stla = float(value.split('/')[0]) stlo = float(value.split('/')[1]) phase = value.split('/')[2] isph = 1 mod = taup.TauPyModel(model='iasp91') elif op == "-M": magmin = float(value.split('/')[0]) magmax = float(value.split('/')[1]) elif op == "-h": Usage() sys.exit(1) else: Usage() sys.exit(1) if head == '': print("Head file are not exist!") Usage() sys.exit(1)
from obspy.clients.neic.client import Client from obspy.io.xseed import Parser #from obspy.core.util import gps2DistAzimuth from obspy.geodetics import gps2dist_azimuth as gps2DistAzimuth #from obspy.taup import TauPyModel from obspy.signal import invsim as inv from obspy.io.xseed.utils import SEEDParserException # plot all traces into one pdf file from matplotlib.backends.backend_pdf import PdfPages from matplotlib import pyplot from matplotlib.dates import date2num # we will use dataless seed from IRIS to get station information parser = Parser("../../data/AU.dataless") # travel-time model will be iasp91 but could be any from obspy import taup vel_model = taup.TauPyModel(model="iasp91") #from obspy.taup.TauPyModel import get_travel_times # local modules from magnitude.ml import local_magnitude r_earth = 6371 def sind(x): return np.sin(x / 180. * np.pi) def cosd(x): return np.cos(x / 180. * np.pi) def tand(x):
def measure_sks_skks(file, outputdir, windows): """ Function to measure SWS using the eigenvalue, transverse minimisation and cross correlation methods This is done using the devel release of splitwave py (Needs to run from the splitwavepy environment) """ filestem = file[55:] try: st = obspy.read('{}??_BH[N,E].sac'.format(file)) except Exception: print(Exception) st = obspy.read('{}_??????_BH[N,E].sac'.format(file[:-5])) f_check_SKS = '/Users/ja17375/Shear_Wave_Splitting/Sheba/Runs/Jacks_Split/{}/SKS/{}SKS_sheba.final_result'.format( st[0].stats.station, filestem) f_check_SKKS = '/Users/ja17375/Shear_Wave_Splitting/Sheba/Runs/Jacks_Split/{}/SKKS/{}SKKS_sheba.final_result'.format( st[0].stats.station, filestem) # apply a bandpass filter st.filter("bandpass", freqmin=0.01, freqmax=0.5) # estimate SKS and SKKS arrival times info = st[0].stats.sac evlat, evlon = info['evla'], info['evlo'] stlat, stlon = info['stla'], info['stlo'] evdepth = info['evdp'] model = taup.TauPyModel('iasp91') arrivals = model.get_travel_times_geo(evdepth, evlat, evlon, stlat, stlon, phase_list=['SKS', 'SKKS']) evtime = UTCDateTime(year=info['nzyear'], julday=info['nzjday'], hour=info['nzhour'], minute=info['nzmin'], second=info['nzsec'], microsecond=1000 * info['nzmsec']) skstime = evtime + arrivals[0].time skkstime = evtime + arrivals[1].time delta_t = skkstime - skstime # find back azimuth baz = info['baz'] # trim around SKS and SKKS wbeg_sks = evtime + windows[0] wend_sks = evtime + windows[1] wbeg_skks = evtime + windows[2] wend_skks = evtime + windows[3] st.trim(wbeg_sks - 30, wend_skks + 30) # put data into splitwavepy object data = splitwavepy.Data(st.select(channel='BHN')[0].data, st.select(channel='BHE')[0].data, delta=st.select(channel='BHN')[0].stats.delta) # add the SAC header info data.sacinfo = st[0].stats.sac # # # measure sks splitting # data.set_window(30, 30+(wend_sks-wbeg_sks)) # data.EigenM(lags=(4,)).save(outputdir + filestem + '.sks.eigm') # data.TransM(lags=(4,), pol=baz).save(outputdir + filestem + '.sks.trnm') # data.XcorrM(lags=(4,)).save(outputdir + filestem + '.sks.xcrm') # # # measure skks splitting # data.set_window(30+(wbeg_skks-wbeg_sks), 30+(wend_skks-wbeg_sks)) # data.EigenM(lags=(4,)).save(outputdir + filestem + '.skks.eigm') # data.TransM(lags=(4,), pol=baz).save(outputdir + filestem + '.skks.trnm') # data.XcorrM(lags=(4,)).save(outputdir + filestem + '.skks.xcrm') # measure sks splitting data.set_window(30, 30 + (wend_sks - wbeg_sks)) data.SC(lags=(4, ), bootstrap=True).save('{}/{}_sks.eigm'.format(outputdir, filestem)) data.SC(lags=(4, ), pol=baz, bootstrap=True).save('{}/{}_sks.trnm'.format(outputdir, filestem)) data.XC(lags=(4, ), bootstrap=True).save('{}/{}_sks.xcrm'.format(outputdir, filestem)) # measure skks splitting data.set_window(30 + (wbeg_skks - wbeg_sks), 30 + (wend_skks - wbeg_sks)) data.SC(lags=(4, ), bootstrap=True).save('{}/{}_skks.eigm'.format(outputdir, filestem)) data.SC(lags=(4, ), pol=baz, bootstrap=True).save('{}/{}_skks.trnm'.format(outputdir, filestem)) data.XC(lags=(4, ), bootstrap=True).save('{}/{}_skks.xcrm'.format(outputdir, filestem))
rsample = 10 endtime = 25.0 tpratio = 0.05 winlen = 15 envolope = 0 mindist = 30 maxdist = 90 mu = 2.0 eqdir = 'data_demo/' eqs = open(''.join([eqdir, 'event_list_pickle']), 'rb') eqs = pickle.load(eqs) evid = [] model = taup.TauPyModel(model='ak135') for ii in eqs: evid.append(ii['event_id']) npoints = int(endtime * rsample + 1) evelist = glob.glob(eqdir + '/*a') nevent = len(evelist) for ievent in range(0, nevent): datasave_sub = defaultdict(list) start = time.time() ievent1 = ievent evname1 = evelist[ievent1].split('/')[-1] evidx1 = evid.index(evname1) evlat1 = eqs[evidx1]['latitude'] evlon1 = eqs[evidx1]['longitude']
def rfOnQuake(quake,waveform,staInfos,mod='fft',r=1.73,\ isPlot=False,indexL=np.arange(-10,15*50),staRF=[],\ staNum=None,model=None,f=[1/20,2],isFFTShift=False,\ outDir='rfFig/',isPrint=True): count = 0 if model == None: taupM = taupM0 else: taupM = taup.TauPyModel(model=model) for record in quake: delta = waveform['deltaL'][0, count] fl = f[0] fh = f[1] if delta == 0: print('bad waveform') count += 1 continue wn0 = fl / (0.5 / delta) wn1 = fh / (0.5 / delta) b, a = signal.butter(2, [wn0, wn1], 'bandpass') staIndex = record.getStaIndex() staInfo = staInfos[staIndex] if True: dis=DistAz(quake.loc[0],quake.loc[1],staInfo['la'],\ staInfo['lo']) BAZ = dis.getBaz() / 180 * np.pi - staInfo['az'] / 180 * np.pi Dis = dis.getDelta() ray=taupM.get_travel_times(max(min(1,quake.loc[2]+staInfo['dep']/1000),100),\ Dis,phase_list=('p','P'))[0] inj = ray.incident_angle / 180 * np.pi AI = calAI(inj, r=r) * 0 index0 = np.where(waveform['indexL'][0][:] == 0)[0][0] w = waveform['pWaveform'][count, indexL + index0, :] w[:, 2] = -w[:, 2] pre=waveform['pWaveform'][count,\ max(0,indexL[0]+index0-1000):indexL[0]+index0-2,:] for comp in range(3): w[:, comp] = signal.filtfilt(b, a, w[:, comp]) pre[:, comp] = signal.filtfilt(b, a, pre[:, comp]) wMax = np.abs(w).max() preMax = np.abs(pre).max() if wMax.max() <= preMax.max() * 3 or wMax.max() == 0: print('bad waveform') count += 1 continue AI0, BAZ0 = calConvPhiTheta(w) print("%.2f %.2f" % (AI * rad2deg, BAZ * rad2deg)) rf,rms=receiverFunc(w,BAZ,\ AI*0,mod=mod,isPlot=isPlot,delta=delta,isFFTShift=isFFTShift) print(rms) if rf.any() == None or rf.any() == np.nan: return None if len(staRF) != 0 and rms < 0.15: staRF[staIndex, :] += rf staNum[staIndex] += 1 theta = -BAZ phi = AI if isPlot and mod != 'iterconv': plt.subplot(4, 1, 4) plt.plot((indexL - float(indexL[0])) * float(waveform['deltaL'][0, count]), rf) plt.show() count += 1 if isPrint and isPlot: staDir = outDir + '/' + str(staIndex) + '/' if not os.path.exists(outDir): os.mkdir(outDir) if not os.path.exists(staDir): os.mkdir(staDir) filename = staDir + os.path.basename( quake.filename)[:-4] + str(staIndex) + '.png' #plt.title plt.suptitle(('%.2f' % rms) + ' ' + str(quake.loc[0]) + ' ' + str(quake.loc[1]) + ' ' + ('%.2f' % (BAZ / np.pi * 180)) + ' ' + ('%.2f' % (BAZ0 / np.pi * 180))) plt.savefig(filename) plt.close() elif isPlot: plt.show()
theta = atan(e / n) + np.pi return phi, theta def calConvPhiTheta(w, isAbsJust=True): m = calConvM(w) b, v = np.linalg.eig(m / m.sum()) maxIndex = b.argmax() vMax = v[:, maxIndex] if isAbsJust: vMax = vMax / np.sign(vMax[-1]) return calPhiTheta(vMax) model0 = 'iasp91' taupM0 = taup.TauPyModel(model=model0) def rfOnQuake(quake,waveform,staInfos,mod='fft',r=1.73,\ isPlot=False,indexL=np.arange(-10,15*50),staRF=[],\ staNum=None,model=None,f=[1/20,2],isFFTShift=False,\ outDir='rfFig/',isPrint=True): count = 0 if model == None: taupM = taupM0 else: taupM = taup.TauPyModel(model=model) for record in quake: delta = waveform['deltaL'][0, count] fl = f[0] fh = f[1] if delta == 0: