示例#1
0
def _obliquity3D(
    nt,
    nr,
    dt,
    dr,
    rho,
    vel,
    nffts,
    critical=100.0,
    ntaper=10,
    composition=True,
    backend="numpy",
    dtype="complex128",
):
    r"""3D Obliquity operator and FFT operator

    Parameters
    ----------
    nt : :obj:`int`
        Number of samples along the time axis
    nr : :obj:`tuple`
        Number of samples along the receiver axes
    dt : :obj:`float`
        Sampling along the time axis
    dr : :obj:`tuple`
        Samplings along the receiver array
    rho : :obj:`float`
        Density along the receiver array (must be constant)
    vel : :obj:`float`
        Velocity along the receiver array (must be constant)
    nffts : :obj:`tuple`, optional
        Number of samples along the wavenumber and frequency axes
    critical : :obj:`float`, optional
        Percentage of angles to retain in obliquity factor. For example, if
        ``critical=100`` only angles below the critical angle
        :math:`\sqrt{k_y^2 + k_x^2} < \frac{\omega}{vel}` will be retained
    ntaper : :obj:`float`, optional
        Number of samples of taper applied to obliquity factor around critical
        angle
    composition : :obj:`bool`, optional
        Create obliquity factor for composition (``True``) or
        decomposition (``False``)
    backend : :obj:`str`, optional
        Backend used for creation of obliquity factor operator
        (``numpy`` or ``cupy``)
    dtype : :obj:`str`, optional
        Type of elements in input array.

    Returns
    -------
    FFTop : :obj:`pylops.LinearOperator`
        FFT operator
    OBLop : :obj:`pylops.LinearOperator`
        Obliquity factor operator

    """
    # create Fourier operator
    FFTop = FFTND(dims=[nr[0], nr[1], nt],
                  nffts=nffts,
                  sampling=[dr[0], dr[1], dt],
                  dtype=dtype)

    # create obliquity operator
    [Ky, Kx, F] = np.meshgrid(FFTop.fs[0],
                              FFTop.fs[1],
                              FFTop.fs[2],
                              indexing="ij")
    k = F / vel
    Kz = np.sqrt((k**2 - Ky**2 - Kx**2).astype(dtype))
    Kz[np.isnan(Kz)] = 0
    if composition:
        OBL = Kz / (rho * np.abs(F))
        OBL[F == 0] = 0
    else:
        OBL = rho * (np.abs(F) / Kz)
        OBL[Kz == 0] = 0

    # cut off and taper
    OBL = _filter_obliquity(OBL, F, Kx, vel, critical, ntaper, Ky=Ky)
    OBL = get_module(backend).asarray(OBL)
    OBLop = Diagonal(OBL.ravel(), dtype=dtype)
    return FFTop, OBLop