def test_source_depth_error_handling(all_remote_dbs): """ Test the seismogram extraction from local and remote databases. """ db = all_remote_dbs # Skip forward databases. if "100s_db_fwd" in db._client.filepath: return # Mock responses to get the tornado testing to work. _add_callback(db._client) # 900 km is deeper than any test database. src = instaseis.Source( latitude=4.0, longitude=3.0, depth_in_m=900000, m_rr=4.71e17, m_tt=3.81e17, m_pp=-4.74e17, m_rt=3.99e17, m_rp=-8.05e17, m_tp=-1.23e17, ) rec = instaseis.Receiver(latitude=10.0, longitude=20.0, depth_in_m=0) with pytest.raises(ValueError) as err: db.get_seismograms(source=src, receiver=rec) assert err.value.args[0] == ( "Source too deep. Source would be located at a radius of 5471000.0 " "meters. The database supports source radii from 6000000.0 to " "6371000.0 meters.") # Too shallow. src = instaseis.Source( latitude=4.0, longitude=3.0, depth_in_m=-10000, m_rr=4.71e17, m_tt=3.81e17, m_pp=-4.74e17, m_rt=3.99e17, m_rp=-8.05e17, m_tp=-1.23e17, ) rec = instaseis.Receiver(latitude=10.0, longitude=20.0, depth_in_m=0) with pytest.raises(ValueError) as err: db.get_seismograms(source=src, receiver=rec) assert err.value.args[0] == ( "Source is too shallow. Source would be located at a radius of " "6381000.0 meters. The database supports source radii from " "6000000.0 to 6371000.0 meters.")
def _calc(self): db = instaseis.open_db(self.db_name) nazi = 8 dt = min([self.dt, db.info.dt]) lats = np.linspace(start=-90., stop=90., num=self.ndist) lons = np.linspace(start=-180, stop=180., num=nazi, endpoint=False) src = instaseis.Source(latitude=90.0, longitude=0.0, depth_in_m=self.depth_in_m, m_rr=-1.670000e+28 / 1e7, m_tt=3.820000e+27 / 1e7, m_pp=1.280000e+28 / 1e7, m_rt=-7.840000e+27 / 1e7, m_rp=-3.570000e+28 / 1e7, m_tp=1.550000e+27 / 1e7) npts = _get_npts(db, dt) stack_R = np.zeros(shape=(self.ndist, nazi, npts)) stack_T = np.zeros(shape=(self.ndist, nazi, npts)) stack_Z = np.zeros(shape=(self.ndist, nazi, npts)) for ilat in tqdm(range(0, int(self.ndist))): lat = lats[ilat] for ilon in range(0, nazi): lon = lons[ilon] rec = instaseis.Receiver(latitude=lat, longitude=lon, network="AB", station="%d" % lon) st = db.get_seismograms(src, rec, components='RTZ', kind='velocity', dt=dt, remove_source_shift=True) stack_R[ilat, ilon, :] = st.select(channel='*R')[0].data stack_T[ilat, ilon, :] = st.select(channel='*T')[0].data stack_Z[ilat, ilon, :] = st.select(channel='*Z')[0].data return stack_R, stack_T, stack_Z, st[0].stats, db.info
def select_and_add(st, db_HF, db_LF, M, dist): winlen_hours = 4 tstart_total = float(st[0].stats.starttime) + 3600 tend_total = float(st[0].stats.endtime) - 3600 * (winlen_hours + 1) tstart_win = tstart_total + (tend_total - tstart_total) * np.random.rand(1) tend_win = tstart_win + 3600 * winlen_hours t0 = tstart_win + 600 + (tend_win - 4200 - tstart_win) * np.random.rand(1) st_LF = st.slice(starttime=utct(tstart_win - 1800), endtime=utct(tend_win + 1800)) st_HF = st.slice(starttime=utct(tstart_win - 1800), endtime=utct(tend_win + 1800)) st_HF.filter('highpass', freq=0.9) st_LF.filter('bandpass', freqmin=1./60, freqmax=1.2) st_LF.trim(starttime=utct(tstart_win), endtime=utct(tend_win)) st_HF.trim(starttime=utct(tstart_win), endtime=utct(tend_win)) src = instaseis.Source(latitude=90.0-dist, longitude=0.0, depth_in_m=1e3 + np.random.rand(1) * 2.9e4, m_rr=instaseis.source.magnitude2moment(M)[0] * np.sqrt(2.), origin_time=utct(t0) ) rec = instaseis.Receiver(latitude=90.0, longitude=0.0, network='XB', station='ELYSE', location='58') for db, flims in zip([db_HF, db_LF], [(1./10, 4.), (1./100., 1./10.)]): st_inst = db.get_seismograms(source=src, receiver=rec, kind='velocity', components='Z', dt=0.1) st_inst.trim(endtime=st_HF[0].stats.endtime-2) st_inst[0].stats.channel = 'BZC' #st_inst.filter('lowpass', freq=fmin) st_inst.filter('highpass', freq=flims[0]) st_inst.filter('lowpass', freq=flims[1]) i0 = int((st_inst[0].stats.starttime - st_LF[0].stats.starttime) * 10) for s in (st_LF, st_HF): s[0].data[i0:i0+len(st_inst[0].data)] += st_inst[0].data return st_LF, st_HF, t0
def create_insta_from_invcat(network, event, database): """ This function creates synthetic data using the given network and event information, with the database of instaseis :param network: Desired Network, for which the data is generated :type network: obspy.core.inventory.Network :param event: Event, for wich the data is generated. The event must have stored the moment tensor (e.g. given by glogalcmt.org) :type event: obspy.core.event.Event :param database: Link to the database, e.g. the path on your harddrive :type database: str """ db = instaseis.open_db(database) tofe = event.origins[0].time lat = event.origins[0].latitude lon = event.origins[0].longitude depth = event.origins[0].depth source = instaseis.Source(latitude=lat, longitude=lon, depth_in_m=depth, m_rr=event.MomentTensor.m_rr, m_tt=event.MomentTensor.m_tt, m_pp=event.MomentTensor.m_pp, m_rt=event.MomentTensor.m_rt, m_rp=event.MomentTensor.m_rp, m_tp=event.MomentTensor.m_tp, origin_time=tofe) stream = Stream() tmp = [] for station in network: rec = instaseis.Receiver(latitude=str(station.latitude), longitude=str(station.longitude), network=str(network.code), station=str(station.code)) tmp.append(db.get_seismograms(source=source, receiver=rec)) for x in tmp: stream += x return stream
def mt_source(self): m_rr = float(self.ui.m_rr.value()) m_tt = float(self.ui.m_tt.value()) m_pp = float(self.ui.m_pp.value()) m_rt = float(self.ui.m_rt.value()) m_rp = float(self.ui.m_rp.value()) m_tp = float(self.ui.m_tp.value()) source = instaseis.Source(latitude=self.ui.evla.value(), longitude=self.ui.evlo.value(), depth_in_m=self.ui.evdp.value(), m_rr=m_rr, m_tt=m_tt, m_pp=m_pp, m_rt=m_rt, m_rp=m_rp, m_tp=m_tp) return source
def compare_dbs(seed, databases): if seed: random.seed(seed) reference = instaseis.open_db(databases[0]) others = [instaseis.open_db(_i) for _i in databases[1:]] max_depth = reference.info.max_radius - reference.info.min_radius while True: receiver = instaseis.Receiver( latitude=random.random() * 180.0 - 90.0, longitude=random.random() * 360.0 - 180.0, network="AB", station="CED", ) source = instaseis.Source( latitude=random.random() * 180.0 - 90.0, longitude=random.random() * 360.0 - 180.0, depth_in_m=random.random() * max_depth, m_rr=4.710000e24 / 1e7, m_tt=3.810000e22 / 1e7, m_pp=-4.740000e24 / 1e7, m_rt=3.990000e23 / 1e7, m_rp=-8.050000e23 / 1e7, m_tp=-1.230000e24 / 1e7, origin_time=obspy.UTCDateTime(2011, 1, 2, 3, 4, 5), ) print("======") ref = reference.get_seismograms(source=source, receiver=receiver, components="ZNERT") oth = [ _i.get_seismograms(source=source, receiver=receiver, components="ZNERT") for _i in others ] for _i, _j in zip(oth, others): print(_j.info.directory, ":", ref == _i) assert ref == _i, str(source) + "\n" + str(receiver)
def on_open_instaseis_button_released(self): cwd = os.getcwd() self.folder = str( QtGui.QFileDialog.getExistingDirectory( self, "choose instaseis database folder", cwd)) if not self.folder: return self.instaseis_db = instaseis.open_db(self.folder) self.source = instaseis.Source(latitude=self.ui.evla.value(), longitude=self.ui.evlo.value(), depth_in_m=self.ui.evdp.value() * 1000., m_rr=self.ui.m_rr.value(), m_tt=self.ui.m_tt.value(), m_pp=self.ui.m_pp.value(), m_rt=self.ui.m_rt.value(), m_rp=self.ui.m_rp.value(), m_tp=self.ui.m_pp.value()) self.receiver = instaseis.Receiver(latitude=self.ui.stla.value(), longitude=self.ui.stlo.value()) self.stream = self.instaseis_db.get_seismograms( source=self.source, receiver=self.receiver, components=str(self.ui.component.currentText()), kind=str(self.ui.motion_type.currentText()), remove_source_shift=True) self.stream[0].stats.sac = {} self.stream[0].stats.sac['o'] = 0.0 self.stream[0].stats.sac['gcarc'] = geodetics.locations2degrees( float(self.ui.evla.value()), float(self.ui.evlo.value()), float(self.ui.stla.value()), float(self.ui.stlo.value())) self.stream_copy = self.stream.copy() time = self.get_time_axis self.ui.window_start.setMaximum(time[-1]) self.ui.window_end.setMaximum(time[-1]) self.ui.window_start.setValue(time[0]) self.ui.window_end.setValue(time[-1]) self.instaseis = True self.plot_map() self.update()
def _get_npts(db, dt): src = instaseis.Source(latitude=90.0, longitude=0.0, depth_in_m=0.0, m_rr=-1.670000e+28 / 1e7, m_tt=3.820000e+27 / 1e7, m_pp=1.280000e+28 / 1e7, m_rt=-7.840000e+27 / 1e7, m_rp=-3.570000e+28 / 1e7, m_tp=1.550000e+27 / 1e7) rec = instaseis.Receiver(latitude=10, longitude=10) st = db.get_seismograms(src, rec, components='RTZ', kind='displacement', dt=dt, remove_source_shift=True) return st[0].stats.npts
def get_source(self, la_s, lo_s, depth, strike=None, dip=None, rake=None, m_tp=None, m_rp=None, m_rt=None, m_pp=None, m_tt=None, m_rr=None, time=None, M0=None, sdr=False): if sdr == True: source = instaseis.Source.from_strike_dip_rake(latitude=la_s, longitude=lo_s, depth_in_m=depth, strike=strike, dip=dip, rake=rake, M0=M0, origin_time=time, dt=2.0) return source else: source = instaseis.Source(latitude=la_s, longitude=lo_s, depth_in_m=depth, m_tp=m_tp, m_rp=m_rp, m_rt=m_rt, m_pp=m_pp, m_tt=m_tt, m_rr=m_rr, origin_time=time) return source
def get_smgr(db, origin, rec, depth_in_m, channel, dt, m_tt=0.0, m_pp=0.0, m_rr=0.0, m_tp=0.0, m_rt=0.0, m_rp=0.0): src_lat = origin.latitude src_lon = origin.longitude time = origin.time src = instaseis.Source(latitude=src_lat, longitude=src_lon, depth_in_m=depth_in_m, origin_time=time, m_tt=m_tt, m_pp=m_pp, m_rr=m_rr, m_tp=m_tp, m_rt=m_rt, m_rp=m_rp) src.set_sliprate_dirac(dt, nsamp=100) tr = db.get_seismograms(src, rec, dt=dt, components='Z', remove_source_shift=False, reconvolve_stf=True)[0] tr.stats['channel'] = channel return tr
def addSynthetics(name, clean): print(instaseis.__path__) # Input directory with PICKLE data as argument dir = 'Data/' + name + '/' # Load database with Greens functions db = instaseis.open_db("/raid2/sc845/Instaseis/DB/10s_PREM_ANI_FORCES/") # Directory needs to contain a CMT source text file with open(dir + 'cmtsource.txt', 'r') as inf: srcdict = eval(inf.read()) # Unpack dictionary latitude = srcdict['latitude'] longitude = srcdict['longitude'] depth_in_m = srcdict['depth'] * 1.e3 m_rr = srcdict['Mrr'] / 1E7 m_tt = srcdict['Mtt'] / 1E7 m_pp = srcdict['Mpp'] / 1E7 m_rt = srcdict['Mrt'] / 1E7 m_rp = srcdict['Mrp'] / 1E7 m_tp = srcdict['Mtp'] / 1E7 origin_time = obspy.UTCDateTime(srcdict['year'], srcdict['month'], srcdict['day'], srcdict['hour'], srcdict['min'], srcdict['sec'], srcdict['msec']) # Read in source source = instaseis.Source(latitude=latitude, longitude=longitude, depth_in_m=depth_in_m, m_rr=m_rr, m_tt=m_tt, m_pp=m_pp, m_rt=m_rt, m_rp=m_rp, m_tp=m_tp, origin_time=origin_time) # Read and loop through station list stalist = glob.glob(dir + '/*PICKLE') for s in range(len(stalist)): seis = read(stalist[s], format='PICKLE') for tr in seis.select(channel='BX*'): seis.remove(tr) # Fixing some old mistake (not sure if still present, check with Sanne) seis[0].stats['channel'] = 'BHZ' print(seis[0].stats['channel']) receiver = instaseis.Receiver(latitude=seis[0].stats['stla'], longitude=seis[0].stats['stlo'], network=seis[0].stats['network'], station=seis[0].stats['station']) start = seis[0].stats['starttime'] end = seis[0].stats['endtime'] st = db.get_seismograms(source=source, receiver=receiver, kind='displacement', dt=0.1) # Rotate synthetics stE = st.select(channel='BXE') stN = st.select(channel='BXN') stZ = st.select(channel='BXZ') [stRtmp, stTtmp] = obspy.signal.rotate.rotate_ne_rt(stN[0].data, stE[0].data, seis[0].stats['baz']) stR = stN[0].copy() stR.stats['channel'] = 'BXR' stR.data = stRtmp stT = stN[0].copy() stT.stats['channel'] = 'BXT' stT.data = stTtmp seis += stR seis += stT seis += stZ for x in seis: print(x.stats['channel']) # Overwrites previous PICKLE with synthetics included seis.write(stalist[s], format='PICKLE') print('Synthetics for this event have been successfully added')
window_min = 400.0 window_max = 3600.0 m_rr = 3.98e13 m_pp = 3.98e13 planet_radius = 1565.0 #planet_radius = 6371.0 distaz = gps2dist_azimuth(lat1=evla, lon1=evlo, lat2=stla, lon2=stlo, a=planet_radius*1000.0, f=0.0) # no flattening gcarc_m = distaz[0] dist_km = gcarc_m / 1000.0 #get instaseis seismogram instaseis_db = instaseis.open_db(insta_db_name) source = instaseis.Source(latitude=evla, longitude=evlo, depth_in_m=evdp*1000., m_rr = m_rr, m_pp = m_rr) receiver = instaseis.Receiver(latitude=stla, longitude=stlo) stream = instaseis_db.get_seismograms(source=source, receiver=receiver, components=components, kind = kind, remove_source_shift=True) stream = stream.slice(stream[0].stats.starttime + window_min, stream[0].stats.starttime + window_max) #stream.plot() time = np.linspace(window_min,
def test_seismogram_extraction(all_remote_dbs): """ Test the seismogram extraction from local and remote databases. """ # Remote and local database. r_db = all_remote_dbs l_db = instaseis.open_db(r_db._client.filepath) # Mock responses to get the tornado testing to work. _add_callback(r_db._client) source = instaseis.Source( latitude=4.0, longitude=3.0, depth_in_m=0, m_rr=4.71e17, m_tt=3.81e17, m_pp=-4.74e17, m_rt=3.99e17, m_rp=-8.05e17, m_tp=-1.23e17, ) receiver = instaseis.Receiver(latitude=10.0, longitude=20.0, depth_in_m=None) components = r_db.available_components kwargs = {"source": source, "receiver": receiver, "components": components} _compare_streams(r_db, l_db, kwargs) # Test velocity and acceleration. kwargs = { "source": source, "receiver": receiver, "components": components, "kind": "velocity", } _compare_streams(r_db, l_db, kwargs) kwargs = { "source": source, "receiver": receiver, "components": components, "kind": "acceleration", } _compare_streams(r_db, l_db, kwargs) # Test remove source shift. kwargs = { "source": source, "receiver": receiver, "components": components, "remove_source_shift": False, } _compare_streams(r_db, l_db, kwargs) # Test resampling. kwargs = { "source": source, "receiver": receiver, "components": components, "dt": 1.0, "kernelwidth": 6, } _compare_streams(r_db, l_db, kwargs) # Test force source. if "displ_only" in r_db._client.filepath: source = instaseis.ForceSource( latitude=89.91, longitude=0.0, depth_in_m=12000, f_r=1.23e10, f_t=2.55e10, f_p=1.73e10, ) kwargs = {"source": source, "receiver": receiver} _compare_streams(r_db, l_db, kwargs) # Fix receiver depth, network, and station codes. receiver = instaseis.Receiver( latitude=10.0, longitude=20.0, depth_in_m=0.0, station="ALTM", network="BW", ) kwargs = {"source": source, "receiver": receiver, "components": components} _compare_streams(r_db, l_db, kwargs)
def add_waveforms( self, instaseis_db_path: str, focal_mech: [float], M0: float = None, dt: float = 0.05, components: str = "ZRT", kind: str = "displacement", noise: bool = False, ): """ Add waveforms to event object using instaseis :param instaseis_db_path: path or url to instaseis database :param rec_lat: latitude receiver :param rec_lon: longitude receiver :param focal_mech: strike,dip,rake or m_rr, m_tt, m_pp, m_rt, m_rp, m_tp :param M0: scalar moment, only necessesary when focal_mech strike,dip,rake :param components: components of the seismogram (ZRT, ZNE, LQT) :param noise: real Martian noise will be added to the seismogram """ assert (M0 is None and len(focal_mech) == 6) or ( M0 is not None and len(focal_mech) == 3 ), ( "focal_mech length is incorrect. " "If you specify M0, focal_mech is [strike,dip,rake]. " "Otherwise focal_mech is [m_rr, m_tt, m_pp, m_rt, m_rp, m_tp]" ) receiver = instaseis.Receiver( latitude=self.lat_rec, longitude=self.lon_rec, network="XB", station="ELYSE", location="02", ) db = instaseis.open_db(instaseis_db_path) if len(focal_mech) == 3: focal_mech = GreensFunctions.convert_SDR( focal_mech[0], focal_mech[1], focal_mech[2], M0 ) m_rr = focal_mech[0] m_tt = focal_mech[1] m_pp = focal_mech[2] m_rt = focal_mech[3] m_rp = focal_mech[4] m_tp = focal_mech[5] print(m_rr, m_tt, m_pp, m_rt, m_rp, m_tp) src = instaseis.Source( latitude=self.event.latitude, longitude=self.event.longitude, depth_in_m=self.event.depth * 1000, m_rr=m_rr, m_tt=m_tt, m_pp=m_pp, m_rt=m_rt, m_rp=m_rp, m_tp=m_tp, time_shift=None, sliprate=None, dt=None, origin_time=self.event.origin_time, ) if components == "LQT": st_obs = db.get_seismograms( source=src, receiver=receiver, components=components, kind=kind, dt=dt ) st_obs.rotate(method="RT->NE", back_azimuth=self.event.baz) else: st_obs = db.get_seismograms( source=src, receiver=receiver, components=components, kind=kind, dt=dt ) st_obs[0].stats.channel = st_obs[0].stats.channel.replace("X", "H") st_obs[1].stats.channel = st_obs[1].stats.channel.replace("X", "H") st_obs[2].stats.channel = st_obs[2].stats.channel.replace("X", "H") st_obs.trim(starttime=self.event.origin_time, endtime=self.event.origin_time + 800.0) if noise: # Path = "/home/nienke/Data_2020/Noise/" Path = "/home/nienke/Documents/Research/Data/Noise/" File_names = [ "XB.02.ELYSE.BHE-2019.274T0809-2019.274T0920", "XB.02.ELYSE.BHN-2019.274T0809-2019.274T0920", "XB.02.ELYSE.BHZ-2019.274T0809-2019.274T0920", ] st_noise = obspy.Stream() for file in File_names: tr = obspy.read(Path + file) st_noise += tr if components == "LQT": raise ValueError("LQT orientation Not implemented yet") # TODO: implement LQT orientation else: st_noise.rotate(method="NE->RT", back_azimuth=self.event.baz) for trace in st_obs: chan = trace.stats.channel desired_dt = trace.stats.delta desired_npts = len(trace.data) noise_trace = st_noise.select(channel=chan)[0] noise = noise_trace.data[int(1200 / dt) : int(1200 / dt) + desired_npts] trace.data += noise self.event.waveforms_VBB = st_obs
station = "BBSR" origin_time = obspy.UTCDateTime(2019, 1, 2, 3, 4, 5) # Define output data parameters delta = 0.5 # Call Instaseis and retrieve seismograms receiver = instaseis.Receiver(latitude=rec_lat, longitude=rec_lon, network=network, station=station) source = instaseis.Source(latitude=source_lat, longitude=source_lon, depth_in_m=source_dep_m, m_rr=m_rr, m_tt=m_tt, m_pp=m_pp, m_rt=m_rt, m_rp=m_rp, m_tp=m_tp, origin_time=origin_time) st = db.get_seismograms(source=source, receiver=receiver, kind='displacement', dt=delta) print(st) # Save seismic traces into arrays trz = st[0] trn = st[1] tre = st[2]
# Open instaseis db db = instaseis.open_db( "/scratch/auerl/wavefield_pyffproc_10s_647km_prem_ani/bwd/") #db = instaseis.open_db('../wavefield/bwd') receiver = instaseis.Receiver(latitude=-51.68, longitude=-58.06, network="AB", station="EFI") source = instaseis.Source(latitude=-13.8200, longitude=-67.2500, depth_in_m=647100, m_rr=-7.590000e+27 / 1E7, m_tt=7.750000e+27 / 1E7, m_pp=-1.600000e+26 / 1E7, m_rt=-2.503000e+28 / 1E7, m_rp=4.200000e+26 / 1E7, m_tp=-2.480000e+27 / 1E7, time_shift=None, sliprate=stf, dt=dt) source.resample_sliprate(db.info.dt, db.info.npts) # create velocity and displacement seismograms st = db.get_seismograms(source, receiver, reconvolve_stf=True, kind="displacement", remove_source_shift=False) st.filter('lowpass', freq=1. / 10.0) tr_disp = st[0]
clean = True else: clean = False # Load database with Green Functions db = instaseis.open_db("syngine://prem_a_2s") # Directory needs to contain a CMTSOLUTION source text file!!! cat = obspy.read_events(dir + 'CMTSOLUTION') # Read in source source = instaseis.Source( latitude=cat[0].origins[0].latitude, longitude=cat[0].origins[0].longitude, depth_in_m=cat[0].origins[0].depth, m_rr=cat[0].focal_mechanisms[0].moment_tensor.tensor.m_rr, m_tt=cat[0].focal_mechanisms[0].moment_tensor.tensor.m_tt, m_pp=cat[0].focal_mechanisms[0].moment_tensor.tensor.m_pp, m_rt=cat[0].focal_mechanisms[0].moment_tensor.tensor.m_rt, m_rp=cat[0].focal_mechanisms[0].moment_tensor.tensor.m_rp, m_tp=cat[0].focal_mechanisms[0].moment_tensor.tensor.m_tp, origin_time=cat[0].origins[0].time) # Read and loop through stationlist stalist = glob.glob(dr + '*PICKLE') for s in range(0, len(stalist)): print(str(s) + '/' + str(len(stalist)) + ' of ' + event) seis = read(stalist[s], format='PICKLE') if clean: for tr in seis.select(channel='BX*'): seis.remove(tr)
mt_rt = 0.0 mt_rp = 0.0 mt_tp = 0.0 # Retrieve the waveform receiver = instaseis.Receiver(latitude=lat_st, longitude=lon_st, network="XB", station="ELYSE") source = instaseis.Source( latitude=lat_ev, longitude=lon_ev, depth_in_m=depth_ev, m_rr=mt_rr, m_tt=mt_tt, m_pp=mt_pp, m_rt=mt_rt, m_rp=mt_rp, m_tp=mt_tp, origin_time=time_ev, ) st_ins1 = db.get_seismograms(source=source, receiver=receiver) # Determine back azimuth and rotate x1_tan = np.sin((lon_st - lon_ev) * 180.0 / np.pi) x2_tan = np.cos(lat_ev * 180.0 / np.pi) * np.sin( lat_st * 180.0 / np.pi) - np.sin(lat_ev * 180.0 / np.pi) * np.cos( lat_st * 180.0 / np.pi) * np.cos((lon_ev - lon_st) * 180.0 / np.pi) azi = np.arctan2(x1_tan, x2_tan) * 180.0 / np.pi if azi <= 0:
# Load database with Green Functions db = instaseis.open_db("/raid2/sc845/Instaseis/DB/10s_PREM_ANI_FORCES/") # Directory needs to contain a cmt source text file!!! with open(dr + '/cmtsource.txt', 'r') as inf: srcdict = eval(inf.read()) # Read in source source = instaseis.Source(latitude=srcdict['latitude'], longitude=srcdict['longitude'], depth_in_m=srcdict['depth'] * 1.e3, m_rr=srcdict['Mrr'] / 1E7, m_tt=srcdict['Mtt'] / 1E7, m_pp=srcdict['Mpp'] / 1E7, m_rt=srcdict['Mrt'] / 1E7, m_rp=srcdict['Mrp'] / 1E7, m_tp=srcdict['Mtp'] / 1E7, origin_time=obspy.UTCDateTime( srcdict['year'], srcdict['month'], srcdict['day'], srcdict['hour'], srcdict['min'], srcdict['sec'], srcdict['msec'])) # Read and loop through stationlist stalist = glob.glob(dr + '/*PICKLE') for s in range(len(stalist)): seis = read(stalist[s], format='PICKLE') for tr in seis.select(channel='BX*'): seis.remove(tr)
# magnitude of randomness magn=1. #output streamfile = "synth1.pickle" qstfile = None #"SYNTH_OUT.QST" invfile = "synth1_inv.xml" catfile = "synth1_cat.xml" source = ins.Source( latitude=lat, longitude=lon, depth_in_m=depth, m_rr = 0.526e26 / 1E7, m_tt = -2.1e26 / 1E7, m_pp = -1.58e26 / 1E7, m_rt = 1.08e+26 / 1E7, m_rp = 2.05e+26 / 1E7, m_tp = 0.607e+26 / 1E7, origin_time=tofe ) x = [] station_range = np.linspace(0,aperture-1,no_of_stations) + 100. #r = np.random.randn(no_of_stations) #randrange = station_range + magn * r #randrange[0] = station_range[0] #randrange[no_of_stations-1] = station_range[no_of_stations-1] # while randrange.max() > randrange[19]: # i = randrange.argmax() # randrange[i] = randrange[i]-0.1
def update(): evdp = float(vardep.get()) * 1000 source_lat = float(varlat.get()) source_lon = float(varlon.get()) rec_lat = float(varstla.get()) rec_lon = float(varstlo.get()) source = instaseis.Source(latitude=source_lat, longitude=source_lon, depth_in_m=evdp, m_rr=m_rr, m_tt=m_tt, m_pp=m_pp, m_rt=m_rt, m_rp=m_rp, m_tp=m_tp, origin_time=origin_time) st = db.get_seismograms(source=source, receiver=receiver, kind='displacement', dt=delta) # Get three component seismic data trz = st[0] trn = st[1] tre = st[2] # Calculate great circle distance and azimuth gcarc, azimuth = su.haversine(source_lat, source_lon, rec_lat, rec_lon) # Get P arrival time for windowing arrivals = model.get_travel_times(source_depth_in_km=evdp / 1000, distance_in_degree=gcarc, phase_list=phases) p = arrivals[0] p410s = arrivals[1] p660s = arrivals[2] # Rotate data from N-E to R-T coordinate system trr, trt = su.seisrt(trn, tre, azimuth) # Get indices for cutting bidx = int(round((p.time - source_shift - 60) / delta) - 1) eidx = int(round((p.time - source_shift + 90) / delta)) # Cut trace trrc = trr[bidx:eidx] trzc = trz[bidx:eidx] NT = np.size(trzc) window = signal.tukey(NT, alpha=0.25) trrc = trrc * window trzc = trzc * window # Calculate receiver function tshift = 10.0 gw = 1.0 nit = 1000 errtol = 0.001 [rf, rms] = rfunc.iterdecon(trrc, trzc, 1 / sample_rate, NT, tshift, gw, nit, errtol) # Plot everything! f = plt.figure(1, figsize=(12, 10)) plt.clf() # Plot the radial trace p1 = f.add_subplot(221) p1.plot(t, trr, 'k', linewidth=0.5) p1.axvline(p.time, color='r', linewidth=0.25, label='P') p1.set_xlim(p.time - 60, p.time + 90) p1.set_ylim(np.min(trr[bidx:eidx]) * 1.2, np.max(trr[bidx:eidx]) * 1.2) p1.set_ylabel('Displacement (m)') p1.set_xlabel('Time after Origin (s)') p1.set_title(r"$u_R(t)$") p1.legend() # Plot the vertical trace p2 = f.add_subplot(223) p2.plot(t, trz, 'k', linewidth=0.5) p2.axvline(p.time, color='r', linewidth=0.25, label='P') p2.set_xlim(p.time - 60, p.time + 90) p2.set_ylim(np.min(trz[bidx:eidx]) * 1.2, np.max(trz[bidx:eidx]) * 1.2) p2.set_ylabel('Displacement (m)') p2.set_xlabel('Time after Origin (s)') p2.set_title(r"$u_Z(t)$") p2.legend() # Plot the receiver function p3 = f.add_subplot(224) p3.plot(trf, rf, 'k', linewidth=1) p3.axvline(tshift + (p410s.time - p.time), color='b', linewidth=0.25, label='P410s') p3.axvline(tshift + (p660s.time - p.time), color='g', linewidth=0.25, label='P660s') p3.set_xlim(np.min(trf), np.max(trf)) p3.set_ylim(np.min(rf) * 1.1, np.max(rf) * 1.1) p3.set_title(r"$f_{Z \rightarrow R}(t)$") p3.set_xlabel('Time (s)') p3.legend() # Plot a map! p4 = f.add_subplot(222) m = Basemap(projection='robin', lon_0=0, resolution='c', ax=p4) m.drawcoastlines(linewidth=0.1) m.drawparallels(np.arange(-90.0, 120.0, 30.0), linewidth=0.2) m.drawmeridians(np.arange(0.0, 360.0, 60.0), linewidth=0.2) # Color things m.fillcontinents(color=(0.9, 0.9, 0.9), lake_color=(1, 1, 1)) m.drawmapboundary(fill_color=(1, 1, 1)) # Add event - station data m.drawgreatcircle(source_lon, source_lat, rec_lon, rec_lat, linewidth=1, color=(1, 0, 0)) sx, sy = m(source_lon, source_lat) m.plot(sx, sy, '*', color=(0.9, 0.9, 0), markersize=18, markeredgecolor='black') rx, ry = m(rec_lon, rec_lat) m.plot(rx, ry, 'v', color=(1, 0, 0), markersize=12, markeredgecolor='black') # plt.subplots_adjust(hspace=0.35) f.canvas.draw()
def dosynthetics(database_path, quake_origins, inv=None, inv_list=None, stream=None, stream_file_name='insta_stream.pickle'): """ Routine to create synthetic data using instaseis. :param database_path: :type database_path: :param quake_origins: :type quake_origins: dict from create_quake_origins Example Honshu: m_rr = 1.730e29 m_tt = -0.281e29 m_pp = -1.450e29 m_rt = 2.120e29 m_rp = 4.550e29 m_tp = -0.657e29 event = read_cat('/Users/Simon/Documents/Studium/WWU/Master/Thesis/data_all/test_datasets/instaseis/honshu_data/HONSHU_cat.xml')[0] q_origins = create_quake_origins(None, None, None, None, m_rr, m_tt, m_pp, m_rt, m_rp, m_tp, event) dbpath = '~/dev/python/instaseis/10s_PREM_ANI_FORCES' stream, inv, cat = dosynthetics(db_path, q_origin, inv) """ if None in quake_origins.viewvalues(): msg = '"None" values in quake_origins are not allowed' raise IOError(msg) db = ins.open_db(database_path) source = ins.Source(latitude=quake_origins['latitude'], longitude=quake_origins['longitude'], depth_in_m=quake_origins['depth_in_m'], m_rr=quake_origins['m_rr'], m_tt=quake_origins['m_tt'], m_pp=quake_origins['m_pp'], m_rt=quake_origins['m_rt'], m_rp=quake_origins['m_rp'], m_tp=quake_origins['m_rp'], origin_time=quake_origins['tofe']) # Prepare synthetic stream and inv. if stream_file_name: prefix = stream_file_name.split('.') inv_file_name = prefix[0] + '_inv.xml' cat_file_name = prefix[0] + '_cat.xml' else: inv_file_name = 'inv_tmp.xml' cat_file_name = 'cat_tmp.xml' receiver_synth = [] if stream: for trace in stream: receiver_synth.append( ins.Receiver(latitude=str(trace.stats.coordinates['latitude']), longitude=str( trace.stats.coordinates['longitude']), network=str(trace.stats.network), station=str(trace.stats.station))) elif inv and not stream: network = inv[0] for station in network: receiver_synth.append( ins.Receiver(latitude=str(station.latitude), longitude=str(station.longitude), network=str(network.code), station=str(station.code))) elif inv_list: for i, station in enumerate(inv_list): receiver_synth.append( ins.Receiver(latitude=str(station[0]), longitude=str(station[1]), network=str('X'), station='X' + str(i))) st_synth = [] for i in range(len(x)): st_synth.append( db.get_seismograms(source=source, receiver=receiver_synth[i])) stream = st_synth[0] for i in range(len(st_synth))[1:]: stream.append(st_synth[i][0]) writeQuakeML(cat_file_name, quake_origins['tofe'], quake_origins['latitude'], quake_origins['longitude'], quake_origins['depth_in_m']) if not inv: writeStationML(inv_file_name) inv = read_inv(inv_file_name) cat = read_cat(cat_file_name) if stream_file_name: stream.write(stream_file_name, format='pickle') else: os.remove(cat_file_name) if inv: os.remove(inv_file_name) return stream, inv, cat
helptext = "Database 1 directory name. \n" parser.add_argument('db_1_name', help=helptext) helptext = "Database 2 directory name. \n" parser.add_argument('db_2_name', help=helptext) return parser if __name__ == "__main__": parser = define_arguments() args = parser.parse_args() db1 = instaseis.open_db(args.db_1_name) db2 = instaseis.open_db(args.db_2_name) src = instaseis.Source(latitude=0.0, longitude=0.0, m_rr=1e20) rec = instaseis.Receiver(latitude=45.0, longitude=0.0) st1 = db1.get_seismograms(src, rec) st2 = db2.get_seismograms(src, rec) plt.plot(st1[0].times(), st1[0].data, label=args.db_1_name) plt.plot(st2[0].times(), st2[0].data, label=args.db_2_name) plt.xlabel('time / seconds') plt.legend() plt.show()
src = instaseis.Source.from_strike_dip_rake(latitude=27.77, longitude=85.37, depth_in_m=12000.0, M0=1e+21, strike=32., dip=62., rake=90.) print(src) # Note that origin time was not provided and hence defaults to 1970. A non double-couple source can directly be specified in terms of its moment tensor (note that instaseis uses SI units, i.e. NM, while GCMT uses dyn cm). src = instaseis.Source(latitude=27.77, longitude=85.37, depth_in_m=12000.0, m_rr=8.29e+20, m_tt=-2.33e+20, m_pp=-5.96e+20, m_rt=2.96e+20, m_rp=4.74e+20, m_tp=-3.73e+20) print(src) # **Sidenote:** The moment tensor can be visualized using the Beachball function from obspy.imaging: # + from obspy.imaging.beachball import beachball mt = src.tensor / src.M0 # normalize the tensor to avoid problems in the plotting beachball(mt, size=200, linewidth=2, facecolor='b') # -
import instaseis db = instaseis.open_db('syngine://ak135f_2s') src = instaseis.Source(m_rr=1e10, latitude=0.0, longitude=0.0, depth_in_m=10e3) rec = instaseis.Receiver(latitude=50, longitude=8, network='YY', station='TEST') st = db.get_seismograms(src, rec, dt=0.1, kind='velocity') print(st) st.write('testdata.mseed', format='MSEED')
def make_GF( or_time: obspy.UTCDateTime, lat_src: float, lon_src: float, depth: float, distance: float, rec: instaseis.Receiver, db: instaseis.open_db, dt: float, comp: str, tstar: _Union[float, str] = None, LQT: bool = False, inc: float = None, baz: float = None, M0: float = 1e14, ) -> obspy.Stream: """ Create stream of different source components :param or_time: origin time :param lat_src: source latitude :param lon_src: source longitude :param depth: depth of event in km :param distance: the epicentral distance in degrees :param rec: instaseis.Receiver object of the single station :param db: instaseis database :param dt: timestep :param comp: component :param tstar: tstar value :param LQT: set to true if component system is LQT :param inc: inclination angle in degrees (needed when LQT = TRUE) :param baz: backazimuth angle in degrees (needed when LQT = TRUE) :param M0: scalar moment """ if tstar is not None and not isinstance(tstar, str): stf_len_sec = 30.0 stf = _STF.stf_tstar(tstar=tstar, dt=db.info.dt, npts=int(stf_len_sec / db.info.dt), nfft=db.info.nfft)[0] # from obspy.signal.filter import highpass, lowpass # stf = highpass(stf, df=1 / db.info.dt, freq=0.1, corners=4, zerophase=False) # stf = highpass(stf, df=1 / db.info.dt, freq=0.1, corners=4, zerophase=False) # stf = lowpass(stf, df=1 / db.info.dt, freq=0.7, corners=4, zerophase=False) # stf = lowpass(stf, df=1 / db.info.dt, freq=0.7, corners=4, zerophase=False) elif isinstance(tstar, str): stf = _STF.Create_stf_from_file(tstar, db.info.dt) mts = [ [M0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, M0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, M0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, M0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, M0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, M0], ] st = obspy.Stream() for mt in mts: src = instaseis.Source( latitude=lat_src, longitude=lon_src, depth_in_m=depth * 1e3, origin_time=or_time, m_rr=mt[0], m_tt=mt[1], m_pp=mt[2], m_rt=mt[3], m_rp=mt[4], m_tp=mt[5], ) reconvolve_stf = False remove_source_shift = True if tstar is not None and not isinstance(tstar, str): reconvolve_stf = True remove_source_shift = False src.set_sliprate(stf, dt=db.info.dt) # src.set_sliprate_lp(dt=db.info.dt, nsamp=50, freq=0.7) elif isinstance(tstar, str): reconvolve_stf = True remove_source_shift = False src.set_sliprate(stf, dt=db.info.dt, normalize=True) if LQT: st_rot = db.get_seismograms( src, rec, dt=dt, components="ZNE", kind="displacement", reconvolve_stf=reconvolve_stf, remove_source_shift=remove_source_shift, ) st_rot.rotate(method="ZNE->LQT", back_azimuth=baz, inclination=inc) tr_rot = st_rot.select(channel="BX" + comp[0])[0] st += tr_rot else: st += db.get_seismograms( src, rec, dt=dt, components=comp, kind="displacement", reconvolve_stf=reconvolve_stf, remove_source_shift=remove_source_shift, )[0] return st
def test_seismogram_extraction(syngine_client): """ Test the seismogram extraction from local and syngine databases. """ # syngine and local database. s_db = syngine_client l_db = instaseis.open_db(db_path) source = instaseis.Source( latitude=4.0, longitude=3.0, depth_in_m=0, m_rr=4.71e17, m_tt=3.81e17, m_pp=-4.74e17, m_rt=3.99e17, m_rp=-8.05e17, m_tp=-1.23e17, ) receiver = instaseis.Receiver(latitude=10.0, longitude=20.0, depth_in_m=None) kwargs = { "source": source, "receiver": receiver, "components": ["Z", "N", "E", "R", "T"], } _compare_streams(s_db, l_db, kwargs) # Test velocity and acceleration. kwargs = { "source": source, "receiver": receiver, "components": ["Z", "N", "E", "R", "T"], "kind": "velocity", } _compare_streams(s_db, l_db, kwargs) kwargs = { "source": source, "receiver": receiver, "components": ["Z", "N", "E", "R", "T"], "kind": "acceleration", } _compare_streams(s_db, l_db, kwargs) # Test remove source shift. kwargs = { "source": source, "receiver": receiver, "components": ["Z", "N", "E", "R", "T"], "remove_source_shift": False, } _compare_streams(s_db, l_db, kwargs) # Test resampling. kwargs = { "source": source, "receiver": receiver, "components": ["Z", "N", "E", "R", "T"], "dt": 1.0, "kernelwidth": 6, } _compare_streams(s_db, l_db, kwargs) # Force sources currently raise an error. source = instaseis.ForceSource( latitude=89.91, longitude=0.0, depth_in_m=12000, f_r=1.23e10, f_t=2.55e10, f_p=1.73e10, ) kwargs = {"source": source, "receiver": receiver} with pytest.raises(ValueError) as e: _compare_streams(s_db, l_db, kwargs) assert e.value.args[0] == ( "The Syngine Instaseis client does currently not " "support force sources. You can still download " "data from the Syngine service for force " "sources manually.") # Test less components and a latitude of 45 degrees to have the maximal # effect of geocentric vs geographic coordinates. source = instaseis.Source( latitude=45.0, longitude=3.0, depth_in_m=0, m_rr=4.71e17, m_tt=3.81e17, m_pp=-4.74e17, m_rt=3.99e17, m_rp=-8.05e17, m_tp=-1.23e17, ) receiver = instaseis.Receiver(latitude=-45.0, longitude=20.0, depth_in_m=None) kwargs = { "source": source, "receiver": receiver, "components": ["Z", "N", "E", "R", "T"], } _compare_streams(s_db, l_db, kwargs)
f.close() print sum(stf * dt) db = instaseis.open_db('../wavefield/bwd') receiver = instaseis.Receiver(latitude=30, longitude=0, network='MC', station='kerner') source = instaseis.Source(latitude=90.0, longitude=0.0, depth_in_m=0.0, m_rr=1.0e13, m_tt=1.0e13, m_pp=1.0e13, m_rt=0.0, m_rp=0.0, m_tp=0.0, time_shift=None, sliprate=stf, dt=dt) source.resample_sliprate(db.info.dt, db.info.npts) st = db.get_seismograms(source, receiver, reconvolve_stf=True, kind="displacement") st.filter('lowpass', freq=1. / 40.0) st.plot() tr_Z = st[0]
def get_max_accel(Mw, gcarc, Q=57822, units='dB', plot=False): ''' returns maximum acceleration for a Haskell source params: Mw: moment magnitude of earthquake gcarc: distance in degrees Q: quality factor (defaults to 600) units: only dB so far... 0 dB is defined as 1e-4 (i.e., 10 mgal) ''' #find scalar moment Mo = utils.Mw_to_Mo(Mw) print Mo #instaseis source (dipslip at equator) source = instaseis.Source(latitude=0.0, longitude=0.0, depth_in_m=300.0, m_rr=3.98e13, m_pp=-3.98e13) #receiver at 60 degrees distance receiver = instaseis.Receiver(latitude=0.0, longitude=gcarc) #get seismograms st = db.get_seismograms(source, receiver, components='Z', kind='displacement') st_accel = db.get_seismograms(source, receiver, components='Z', kind='acceleration') st.resample(2.0) st_accel.resample(2.0) #freqs,d_w = signal.periodogram(st[0].data,st[0].stats.sampling_rate) freqs, d_w = signal.welch(st[0].data, st[0].stats.sampling_rate) freqs, a_w = signal.welch(st_accel[0].data, st[0].stats.sampling_rate) #find corner frequency corner_freq = acceleration.get_corner_freq(Mo=Mo) #print 'corner_freq =', corner_freq #Aki and Richards 10.36 s_w = Mo / ((1.0 + ((freqs / corner_freq)**2))**(1.5)) #plt.loglog(freqs,s_w) #plt.show() #Haskell parameters t_rise, t_dur = acceleration.get_trise_tdur(corner_freq=corner_freq, scale_factor=8.) print 'trise, t_dur = ', t_rise, t_dur #Haskell source sinc1 = np.sinc((2 * np.pi * freqs * t_rise) / 2.) sinc2 = np.sinc((2 * np.pi * freqs * t_dur) / 2.) haskell = np.abs(sinc1 * sinc2) s1_arg = ((2 * np.pi * freqs * t_rise) / (2.)) s2_arg = ((2 * np.pi * freqs * t_dur) / (2.)) haskell_v2 = np.abs( ((np.sin(s1_arg) / s1_arg)) * ((np.sin(s2_arg) / s2_arg))) haskell_v2[0] = 1.0 #traveltime (use first arriving phase) #arrs = mars.get_travel_times(source.depth_in_m/1000.0,gcarc) #print arrs #tt = arrs[0].time d_km = gcarc * km_per_deg tt = d_km * (1. / vs_surface) print d_km, tt #attenuation factor atten = np.exp((-np.pi * corner_freq * tt) / (Q)) print Q, tt, atten #acceleration spectrum #A_w = (freqs**2)*d_w*atten*Mo*haskell A_w = ((2 * np.pi * freqs)**2) * d_w * atten * Mo A_w_max = np.max(A_w) print 'MAXIMUM ACCELERATION', A_w_max a_w = a_w * Mo * atten * haskell_v2 a_w_max = np.max(a_w) #plot if plot: #plt.loglog(freqs,A_w) fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(14, 8)) axes[0, 0].loglog(freqs, d_w) axes[0, 0].set_xlabel('Frequency (Hz)') axes[0, 0].set_ylabel('displacement PSD m^2/Hz)') axes[0, 1].loglog(freqs, A_w, label='calculated') axes[0, 1].loglog(freqs, a_w, label='instaseis') axes[0, 1].set_xlabel('Frequency (Hz)') axes[0, 1].set_ylabel('acceleration PSD (m/s^2)^2/Hz)') axes[0, 1].legend() axes[1, 1].semilogx(freqs, haskell) axes[1, 1].semilogx(freqs, haskell_v2) plt.show() if units == 'dB': #return 10*np.log10((A_w_max)/(1e-4)) return 10 * np.log10((a_w_max) / (1e-4)) else: raise ValueError('units not implemented')