def psrf_3D_raytracing(stadatar, YAxisRange, mod3d, srayp=None): """ Back ray trace the S wavs with a assumed ray parameter of P. Parameters -------------- stla: float The latitude of the station stlo: float The longitude of the station stadatar: object SACStation The data class including PRFs and more parameters YAxisRange: array_like The depth array with the same intervals mod3d: 'Mod3DPerturbation' object The 3D velocity model with fields of ``dep``, ``lat``, ``lon``, ``vp`` and ``vs``. """ R = 6371 - YAxisRange ddepth = np.mean(np.diff(YAxisRange)) pplat_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplon_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplat_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplon_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) x_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) x_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) Tpds = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) rayps = srad2skm(stadatar.rayp) if isinstance(srayp, str) or isinstance(srayp, np.lib.npyio.NpzFile): if isinstance(srayp, str): if not exists(srayp): raise FileNotFoundError('Ps rayp lib file not found') else: rayp_lib = np.load(srayp) else: rayp_lib = srayp elif srayp is None: pass else: raise TypeError('srayp should be path to Ps rayp lib') for i in range(stadatar.ev_num): if srayp is None: srayps = stadatar.rayp[i] else: srayps = get_psrayp(rayp_lib, stadatar.dis[i], stadatar.evdp[i], YAxisRange) srayps = skm2srad(sdeg2skm(srayps)) pplat_s[i][0] = pplat_p[i][0] = stadatar.stla pplon_s[i][0] = pplon_p[i][0] = stadatar.stlo x_s[i][0] = 0 x_p[i][0] = 0 vs = np.zeros_like(YAxisRange) vp = np.zeros_like(YAxisRange) for j, dep in enumerate(YAxisRange[:-1]): vs[j] = interpn( (mod3d.model['dep'], mod3d.model['lat'], mod3d.model['lon']), mod3d.model['vs'], (dep, pplat_s[i, j], pplon_s[i, j]), bounds_error=False, fill_value=None) vp[j] = interpn( (mod3d.model['dep'], mod3d.model['lat'], mod3d.model['lon']), mod3d.model['vp'], (dep, pplat_p[i, j], pplon_p[i, j]), bounds_error=False, fill_value=None) x_s[i, j + 1] = ddepth * tand(asind(vs[j] * rayps[i])) + x_s[i, j] x_p[i, j + 1] = ddepth * tand(asind(vp[j] * rayps[i])) + x_p[i, j] pplat_s[i, j + 1], pplon_s[i, j + 1] = latlon_from( stadatar.stla, stadatar.stlo, stadatar.bazi[i], km2deg(x_s[i, j + 1])) pplat_p[i, j + 1], pplon_p[i, j + 1] = latlon_from( stadatar.stla, stadatar.stlo, stadatar.bazi[i], km2deg(x_p[i, j + 1])) Tpds[i] = np.cumsum( (np.sqrt((R / vs)**2 - srayps**2) - np.sqrt((R / vp)**2 - stadatar.rayp[i]**2)) * (ddepth / R)) return pplat_s, pplon_s, pplat_p, pplon_p, Tpds
def psrf_1D_raytracing(stadatar, YAxisRange, velmod='iasp91', srayp=None): dep_mod = DepModel(YAxisRange, velmod) # x_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) raylength_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplat_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplon_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) # x_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) raylength_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplat_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplon_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) Tpds = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) if srayp is None: for i in range(stadatar.ev_num): x_s = np.cumsum((dep_mod.dz / dep_mod.R) / np.sqrt((1. / (stadatar.rayp[i]**2. * (dep_mod.R / dep_mod.vs)**-2)) - 1)) raylength_s[i] = (dep_mod.dz * dep_mod.R) / (np.sqrt( ((dep_mod.R / dep_mod.vs)**2) - (stadatar.rayp[i]**2)) * dep_mod.vs) x_p = np.cumsum((dep_mod.dz / dep_mod.R) / np.sqrt((1. / (stadatar.rayp[i]**2. * (dep_mod.R / dep_mod.vp)**-2)) - 1)) raylength_p[i] = (dep_mod.dz * dep_mod.R) / (np.sqrt( ((dep_mod.R / dep_mod.vp)**2) - (stadatar.rayp[i]**2)) * dep_mod.vp) Tpds[i] = np.cumsum( (np.sqrt((dep_mod.R / dep_mod.vs)**2 - stadatar.rayp[i]**2) - np.sqrt((dep_mod.R / dep_mod.vp)**2 - stadatar.rayp[i]**2)) * (dep_mod.dz / dep_mod.R)) pplat_s[i], pplon_s[i] = latlon_from(stadatar.stla, stadatar.stlo, stadatar.bazi[i], rad2deg(x_s)) pplat_p[i], pplon_p[i] = latlon_from(stadatar.stla, stadatar.stlo, stadatar.bazi[i], rad2deg(x_p)) elif isinstance(srayp, str) or isinstance(srayp, np.lib.npyio.NpzFile): if isinstance(srayp, str): if not exists(srayp): raise FileNotFoundError('Ps rayp lib file not found') else: rayp_lib = np.load(srayp) else: rayp_lib = srayp for i in range(stadatar.ev_num): rayp = get_psrayp(rayp_lib, stadatar.dis[i], stadatar.evdp[i], dep_mod.depths) rayp = skm2srad(sdeg2skm(rayp)) x_s = np.cumsum( (dep_mod.dz / dep_mod.R) / np.sqrt((1. / (rayp**2. * (dep_mod.R / dep_mod.vs)**-2)) - 1)) raylength_s[i] = (dep_mod.dz * dep_mod.R) / (np.sqrt(( (dep_mod.R / dep_mod.vs)**2) - (rayp**2)) * dep_mod.vs) x_p = np.cumsum((dep_mod.dz / dep_mod.R) / np.sqrt((1. / (stadatar.rayp[i]**2. * (dep_mod.R / dep_mod.vp)**-2)) - 1)) raylength_p[i] = (dep_mod.dz * dep_mod.R) / (np.sqrt( ((dep_mod.R / dep_mod.vp)**2) - (stadatar.rayp[i]**2)) * dep_mod.vp) Tpds[i] = np.cumsum( (np.sqrt((dep_mod.R / dep_mod.vs)**2 - rayp**2) - np.sqrt((dep_mod.R / dep_mod.vp)**2 - stadatar.rayp[i]**2)) * (dep_mod.dz / dep_mod.R)) x_s = _imag2nan(x_s) x_p = _imag2nan(x_p) pplat_s[i], pplon_s[i] = latlon_from(stadatar.stla, stadatar.stlo, stadatar.bazi[i], rad2deg(x_s)) pplat_p[i], pplon_p[i] = latlon_from(stadatar.stla, stadatar.stlo, stadatar.bazi[i], rad2deg(x_p)) else: raise TypeError('srayp should be path to Ps rayp lib') return pplat_s, pplon_s, pplat_p, pplon_p, raylength_s, raylength_p, Tpds
def psrf2depth(stadatar, YAxisRange, sampling, shift, velmod='iasp91', velmod_3d=None, srayp=None): """ :param stadatar: :param YAxisRange: :param sampling: :param shift: :param velmod: :return: """ dep_mod = DepModel(YAxisRange, velmod) if velmod_3d is not None: dep_mod.vp, dep_mod.vs = interp_depth_model(velmod_3d, stadatar.stla, stadatar.stlo, YAxisRange) x_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) x_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) Tpds = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) if srayp is None: for i in range(stadatar.ev_num): x_s[i] = np.cumsum( (dep_mod.dz / dep_mod.R) / np.sqrt((1. / (stadatar.rayp[i]**2. * (dep_mod.R / dep_mod.vs)**-2)) - 1)) x_p[i] = np.cumsum( (dep_mod.dz / dep_mod.R) / np.sqrt((1. / (stadatar.rayp[i]**2. * (dep_mod.R / dep_mod.vp)**-2)) - 1)) Tpds[i] = np.cumsum( (np.sqrt((dep_mod.R / dep_mod.vs)**2 - stadatar.rayp[i]**2) - np.sqrt((dep_mod.R / dep_mod.vp)**2 - stadatar.rayp[i]**2)) * (dep_mod.dz / dep_mod.R)) elif isinstance(srayp, str) or isinstance(srayp, np.lib.npyio.NpzFile): if isinstance(srayp, str): if not exists(srayp): raise FileNotFoundError('Ps rayp lib file not found') else: rayp_lib = np.load(srayp) else: rayp_lib = srayp for i in range(stadatar.ev_num): rayp = get_psrayp(rayp_lib, stadatar.dis[i], stadatar.evdp[i], dep_mod.depths) rayp = skm2srad(sdeg2skm(rayp)) x_s[i] = np.cumsum( (dep_mod.dz / dep_mod.R) / np.sqrt((1. / (rayp**2. * (dep_mod.R / dep_mod.vs)**-2)) - 1)) x_p[i] = np.cumsum( (dep_mod.dz / dep_mod.R) / np.sqrt((1. / (stadatar.rayp[i]**2. * (dep_mod.R / dep_mod.vp)**-2)) - 1)) Tpds[i] = np.cumsum( (np.sqrt((dep_mod.R / dep_mod.vs)**2 - rayp**2) - np.sqrt((dep_mod.R / dep_mod.vp)**2 - stadatar.rayp[i]**2)) * (dep_mod.dz / dep_mod.R)) else: raise TypeError('srayp should be path to Ps rayp lib') time_axis = np.arange(0, stadatar.RFlength) * sampling - shift PS_RFdepth = np.zeros([stadatar.ev_num, dep_mod.depths.shape[0]]) EndIndex = np.zeros(stadatar.ev_num) for i in range(stadatar.ev_num): TempTpds = Tpds[i, :] StopIndex = np.where(np.imag(TempTpds) == 1)[0] if StopIndex.size == 0: EndIndex[i] = dep_mod.depths.shape[0] DepthAxis = interp1d(TempTpds, dep_mod.depths, bounds_error=False)(time_axis) else: EndIndex[i] = StopIndex[0] - 1 DepthAxis = interp1d(TempTpds[0:StopIndex], dep_mod.depths[0:StopIndex], bounds_error=False)(time_axis) PS_RFTempAmps = stadatar.datar[i] ValueIndices = np.where(np.logical_not(np.isnan(DepthAxis)))[0] if ValueIndices.size == 0: continue elif np.max(ValueIndices) > PS_RFTempAmps.shape[0]: continue else: PS_RFAmps = interp1d(DepthAxis[ValueIndices], PS_RFTempAmps[ValueIndices], bounds_error=False)(YAxisRange) PS_RFdepth[i] = PS_RFAmps / np.nanmax(PS_RFAmps) return PS_RFdepth, EndIndex, x_s, x_p
def psrf_3D_raytracing(stadatar, YAxisRange, mod3d, srayp=None, elevation=0, sphere=True): """ Back ray trace the S wavs with a assumed ray parameter of P. :param stadatar: The data class including PRFs and more parameters :type stadatar: object RFStation :param YAxisRange: The depth array with the same intervals :type YAxisRange: numpy.ndarray :param mod3d: The 3D velocity model with fields of ``dep``, ``lat``, ``lon``, ``vp`` and ``vs``. :type mod3d: 'Mod3DPerturbation' object :param elevation: Elevation of this station relative to sea level :type elevation: float :return: pplat_s, pplon_s, pplat_p, pplon_p, tps :type: numpy.ndarray * 5 """ if sphere: R = 6371.0 - YAxisRange + elevation else: R = 6371.0 + elevation dep_range = YAxisRange.copy() YAxisRange -= elevation ddepth = np.mean(np.diff(YAxisRange)) pplat_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplon_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplat_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplon_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) x_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) x_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) tps = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) rayps = srad2skm(stadatar.rayp) if isinstance(srayp, str) or isinstance(srayp, np.lib.npyio.NpzFile): if isinstance(srayp, str): if not exists(srayp): raise FileNotFoundError('Ps rayp lib file not found') else: rayp_lib = np.load(srayp) else: rayp_lib = srayp elif srayp is None: pass else: raise TypeError('srayp should be path to Ps rayp lib') for i in range(stadatar.ev_num): if srayp is None: srayps = stadatar.rayp[i] else: srayps = get_psrayp(rayp_lib, stadatar.dis[i], stadatar.evdp[i], YAxisRange) srayps = skm2srad(sdeg2skm(srayps)) pplat_s[i][0] = pplat_p[i][0] = stadatar.stla pplon_s[i][0] = pplon_p[i][0] = stadatar.stlo x_s[i][0] = 0 x_p[i][0] = 0 vs = np.zeros_like(YAxisRange) vp = np.zeros_like(YAxisRange) for j, dep in enumerate(YAxisRange[:-1]): vs[j] = interpn( (mod3d.model['dep'], mod3d.model['lat'], mod3d.model['lon']), mod3d.model['vs'], (dep, pplat_s[i, j], pplon_s[i, j]), bounds_error=False, fill_value=None) vp[j] = interpn( (mod3d.model['dep'], mod3d.model['lat'], mod3d.model['lon']), mod3d.model['vp'], (dep, pplat_p[i, j], pplon_p[i, j]), bounds_error=False, fill_value=None) x_s[i, j + 1] = ddepth * tand(asind(vs[j] * rayps[i])) + x_s[i, j] x_p[i, j + 1] = ddepth * tand(asind(vp[j] * rayps[i])) + x_p[i, j] pplat_s[i, j + 1], pplon_s[i, j + 1] = latlon_from( stadatar.stla, stadatar.stlo, stadatar.bazi[i], km2deg(x_s[i, j + 1])) pplat_p[i, j + 1], pplon_p[i, j + 1] = latlon_from( stadatar.stla, stadatar.stlo, stadatar.bazi[i], km2deg(x_p[i, j + 1])) tps_corr = np.cumsum( (np.sqrt((R / vs)**2 - srayps**2) - np.sqrt((R / vp)**2 - stadatar.rayp[i]**2)) * (ddepth / R)) if elevation != 0: tps[i] = interp1d(YAxisRange, tps_corr)(dep_range) return pplat_s, pplon_s, pplat_p, pplon_p, tps
def psrf_1D_raytracing(stadatar, YAxisRange, velmod='iasp91', srayp=None, sphere=True, phase=1): dep_mod = DepModel(YAxisRange, velmod, stadatar.stel) # x_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) raylength_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplat_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplon_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) # x_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) raylength_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplat_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) pplon_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) tps = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) if srayp is None: for i in range(stadatar.ev_num): tps[i], x_s, x_p, raylength_s[i], raylength_p[i] = xps_tps_map( dep_mod, stadatar.rayp[i], stadatar.rayp[i], is_raylen=True, sphere=sphere, phase=phase) pplat_s[i], pplon_s[i] = latlon_from(stadatar.stla, stadatar.stlo, stadatar.bazi[i], rad2deg(x_s)) pplat_p[i], pplon_p[i] = latlon_from(stadatar.stla, stadatar.stlo, stadatar.bazi[i], rad2deg(x_p)) elif isinstance(srayp, str) or isinstance(srayp, np.lib.npyio.NpzFile): if isinstance(srayp, str): if not exists(srayp): raise FileNotFoundError('Ps rayp lib file not found') else: rayp_lib = np.load(srayp) else: rayp_lib = srayp for i in range(stadatar.ev_num): rayp = get_psrayp(rayp_lib, stadatar.dis[i], stadatar.evdp[i], dep_mod.depths_elev) rayp = skm2srad(sdeg2skm(rayp)) tps[i], x_s, x_p, raylength_s[i], raylength_p[i] = xps_tps_map( dep_mod, rayp, stadatar.rayp[i], is_raylen=True, sphere=sphere, phase=phase) x_s = _imag2nan(x_s) x_p = _imag2nan(x_p) pplat_s[i], pplon_s[i] = latlon_from(stadatar.stla, stadatar.stlo, stadatar.bazi[i], rad2deg(x_s)) pplat_p[i], pplon_p[i] = latlon_from(stadatar.stla, stadatar.stlo, stadatar.bazi[i], rad2deg(x_p)) else: raise TypeError('srayp should be path to Ps rayp lib') return pplat_s, pplon_s, pplat_p, pplon_p, raylength_s, raylength_p, tps
def psrf2depth(stadatar, YAxisRange, velmod='iasp91', srayp=None, normalize='single', sphere=True, phase=1): """ Time-to-depth conversion with S-wave backprojection. :param stadatar: Data class of RFStation :type stadatar: :meth:`RFStation` :param YAxisRange: Depth range for converison :type YAxisRange: numpy.ndarray :param velmod: Velocity for conversion, whcih can be a path to velocity file, defaults to 'iasp91' :type velmod: str, optional :param srayp: ray-parameter library of conversion phases. See :meth:`seispy.psrayp` in detail, defaults to None :type srayp: str or :meth:`seispy.psrayp.PsRayp`, optional :param normalize: method of normalization, defaults to 'single'. Please refer to :meth:`RFStation.normalize` :type normalize: str, optional :param sphere: Wether do earth-flattening transformation, defaults to True :type sphere: bool, optional Returns ------------ ps_rfdepth: 2-D numpy.ndarray, float RFs in depth with shape of ``(stadatar.ev_num, YAxisRange.size)``, ``stadatar.ev_num`` is the number of RFs in current station. ``YAxisRange.size`` is the size of depth axis. endindex: numpy.ndarray, int End index of each RF in depth x_s: 2-D numpy.ndarray, float Horizontal distance between station and S-wave conversion points with shape of ``(stadatar.ev_num, YAxisRange.size)`` x_p: 2-D numpy.ndarray, float Horizontal distance between station and P-wave conversion points with shape of ``(stadatar.ev_num, YAxisRange.size)`` """ if exists(velmod): try: dep_mod = DepModel(YAxisRange, velmod, elevation=stadatar.stel) except: dep_mod = DepModel(YAxisRange, 'iasp91', elevation=stadatar.stel) try: velmod_3d = np.load(velmod) dep_mod.vp, dep_mod.vs = interp_depth_model( velmod_3d, stadatar.stla, stadatar.stlo, dep_mod.depths_elev) except Exception as e: raise FileNotFoundError( 'Cannot load 1D or 3D velocity model of \'{}\''.format( velmod)) else: try: dep_mod = DepModel(YAxisRange, velmod, elevation=stadatar.stel) except: raise ValueError( 'Cannot recognize the velocity model of \'{}\''.format(velmod)) x_s = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) x_p = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) tps = np.zeros([stadatar.ev_num, YAxisRange.shape[0]]) if srayp is None: for i in range(stadatar.ev_num): tps[i], x_s[i], x_p[i] = xps_tps_map(dep_mod, stadatar.rayp[i], stadatar.rayp[i], sphere=sphere, phase=phase) elif isinstance(srayp, str) or isinstance(srayp, np.lib.npyio.NpzFile): if isinstance(srayp, str): if not exists(srayp): raise FileNotFoundError('Ps rayp lib file was not found') else: rayp_lib = np.load(srayp) else: rayp_lib = srayp for i in range(stadatar.ev_num): rayp = get_psrayp(rayp_lib, stadatar.dis[i], stadatar.evdp[i], dep_mod.depths_elev) rayp = skm2srad(sdeg2skm(rayp)) tps[i], x_s[i], x_p[i] = xps_tps_map(dep_mod, rayp, stadatar.rayp[i], sphere=sphere, phase=phase) else: raise TypeError('srayp should be path to Ps rayp lib') ps_rfdepth, endindex = time2depth(stadatar, dep_mod.depths, tps, normalize=normalize) return ps_rfdepth, endindex, x_s, x_p