def test_MDC_Nvirtualsources(par):
    """Dot-test and comparison with pylops for MDC operator of N virtual source
    """
    if par['twosided']:
        par['nt2'] = 2*par['nt'] - 1
    else:
        par['nt2'] = par['nt']
    v = 1500
    it0_m = 25
    t0_m = it0_m * par['dt']
    theta_m = 0
    phi_m = 0
    amp_m = 1.

    it0_G = np.array([25, 50, 75])
    t0_G = it0_G * par['dt']
    theta_G = (0, 0, 0)
    phi_G = (0, 0, 0)
    amp_G = (1., 0.6, 2.)

    # Create axis
    t, _, x, y = makeaxis(par)

    # Create wavelet
    wav = ricker(t[:41], f0=par['f0'])[0]

    # Generate model
    _, mwav = linear3d(x, x, t, v, t0_m, theta_m, phi_m, amp_m, wav)

    # Generate operator
    _, Gwav = linear3d(x, y, t, v, t0_G, theta_G, phi_G, amp_G, wav)

    # Add negative part to data and model
    if par['twosided']:
        mwav = np.concatenate((np.zeros((par['nx'], par['nx'], par['nt'] - 1)),
                               mwav), axis=-1)
        Gwav = np.concatenate((np.zeros((par['ny'], par['nx'], par['nt'] - 1)),
                               Gwav), axis=-1)

    # Define MDC linear operator
    Gwav_fft = np.fft.fft(Gwav, par['nt2'], axis=-1)
    Gwav_fft = Gwav_fft[..., :par['nfmax']]

    dMDCop = dMDC(da.from_array(Gwav_fft.transpose(2, 0, 1)), nt=par['nt2'],
                  nv=par['nx'], dt=par['dt'], dr=par['dx'],
                  twosided=par['twosided'])
    MDCop = MDC(Gwav_fft.transpose(2, 0, 1), nt=par['nt2'], nv=par['nx'],
                dt=par['dt'], dr=par['dx'], twosided=par['twosided'],
                transpose=False, dtype='float32')

    dottest(dMDCop, par['nt2'] * par['ny'] * par['nx'],
            par['nt2'] * par['nx'] * par['nx'],
            chunks=((par['nt2'] * par['ny'] * par['nx'],
                     par['nt2'] * par['nx'] * par['nx'])))

    mwav = mwav.T
    dy = (dMDCop * da.from_array(mwav.flatten())).compute()
    y = MDCop * mwav.flatten()
    assert_array_almost_equal(dy, y, decimal=5)
Exemple #2
0
def MakeSeismic_paper(samples,
                      img_size=128,
                      freq_low=5,
                      freq_high=30,
                      num_events=6):
    """Simple generation of noisy synthetic linear seismic events. 
        Input:
        samples =  Number of samples in your dataset you want
        
        Output: 
        clean_signal, noise, noisy_signal"""
    random.seed(101)
    # empty list to be filled with numpy arrays
    clean_signal = []
    noise = []
    noisy_signal = []
    # Parameters for the seismic canvas
    par = {
        'ox': 0,
        'dx': 12.5,
        'nx': img_size,  # offsets
        'ot': 0,
        'dt': 0.004,
        'nt': img_size,  # time
        'f0': 20,
        'nfmax': 50
    }
    # Make canvas
    t, t2, x, y = makeaxis(par)
    # Make wavelet
    wav = ricker(np.arange(41) * par['dt'], f0=par['f0'])[0]
    # Parameters for events
    v = 1500
    ang_range = 50
    amp_range = 2
    i = 0
    amp_lim = 0.2
    t0 = [0.2, 0.3, 0.5, 0.8]
    amp = [-0.5, 1.2, -1.5, 0.8]
    theta = [10, -10, 5, -30]
    while i < samples:
        # Making events
        mlin, mlinwav = linear2d(x, t, v, t0, theta, amp, wav)
        # Creating noise
        n = np.random.normal(loc=0, scale=0.25, size=(
            img_size, img_size)) * random.uniform(-2, 2)
        # Adding noise
        s = mlinwav
        ns = s + n
        clean_signal.append(s)
        noise.append(n)
        noisy_signal.append(ns)
        i += 1

    return np.array(clean_signal).reshape(
        samples, img_size, img_size, 1), np.array(noise).reshape(
            samples, img_size, img_size,
            1), np.array(noisy_signal).reshape(samples, img_size, img_size, 1)
Exemple #3
0
def test_ChirpRadon3D(par):
    """Dot-test, forward, analytical inverse and sparse inverse
    for ChirpRadon3D operator
    """
    parmod = {
        "ot": 0,
        "dt": 0.004,
        "nt": par["nt"],
        "ox": par["nhx"] * 10 / 2,
        "dx": 10,
        "nx": par["nhx"],
        "oy": par["nhy"] * 10 / 2,
        "dy": 10,
        "ny": par["nhy"],
        "f0": 40,
    }
    theta = [
        20,
    ]
    phi = [
        0,
    ]
    t0 = [
        0.1,
    ]
    amp = [
        1.0,
    ]

    # Create axis
    t, t2, hx, hy = makeaxis(parmod)

    # Create wavelet
    wav, _, wav_c = ricker(t[:41], f0=parmod["f0"])

    # Generate model
    _, x = linear3d(hy, hx, t, 1500.0, t0, theta, phi, amp, wav)
    Rop = ChirpRadon3D(
        t,
        hy,
        hx,
        (par["pymax"], par["pxmax"]),
        engine=par["engine"],
        dtype="float64",
        **dict(flags=("FFTW_ESTIMATE",), threads=2)
    )
    assert dottest(
        Rop, par["nhy"] * par["nhx"] * par["nt"], par["nhy"] * par["nhx"] * par["nt"]
    )

    y = Rop * x.ravel()
    xinvana = Rop.inverse(y)
    assert_array_almost_equal(x.ravel(), xinvana, decimal=3)

    xinv, _, _ = FISTA(Rop, y, 30, eps=1e0, returninfo=True)
    assert_array_almost_equal(x.ravel(), xinv, decimal=3)
Exemple #4
0
def test_ricker(par):
    """Create ricker wavelet and check size and central value"""
    t = np.arange(par["nt"]) * par["dt"]
    wav, twav, wcenter = ricker(t, f0=20)

    assert twav.size == (par["nt"] - 1 if par["nt"] %
                         2 == 0 else par["nt"]) * 2 - 1
    assert wav.shape[0] == (par["nt"] - 1 if par["nt"] %
                            2 == 0 else par["nt"]) * 2 - 1
    assert wav[wcenter] == 1
Exemple #5
0
def test_MDC_1virtualsource(par):
    """Dot-test and inversion for MDC operator of 1 virtual source
    """
    if par['twosided']:
        par['nt2'] = 2*par['nt'] - 1
    else:
        par['nt2'] = par['nt']
    v = 1500
    t0_m = 0.2
    theta_m = 0
    amp_m = 1.

    t0_G = (0.1, 0.2, 0.3)
    theta_G = (0, 0, 0)
    phi_G = (0, 0, 0)
    amp_G = (1., 0.6, 2.)

    # Create axis
    t, _, x, y = makeaxis(par)

    # Create wavelet
    wav = ricker(t[:41], f0=par['f0'])[0]

    # Generate model
    _, mwav = linear2d(x, t, v, t0_m, theta_m, amp_m, wav)
    # Generate operator
    _, Gwav = linear3d(x, y, t, v, t0_G, theta_G, phi_G, amp_G, wav)

    # Add negative part to data and model
    if par['twosided']:
        mwav = np.concatenate((np.zeros((par['nx'], par['nt'] - 1)), mwav), axis=-1)
        Gwav = np.concatenate((np.zeros((par['ny'], par['nx'], par['nt'] - 1)), Gwav), axis=-1)

    # Define MDC linear operator
    Gwav_fft = np.fft.fft(Gwav, par['nt2'], axis=-1)
    Gwav_fft = Gwav_fft[..., :par['nfmax']]

    MDCop = MDC(Gwav_fft, nt=par['nt2'], nv=1,
                dt=par['dt'], dr=par['dx'],
                twosided=par['twosided'], dtype='float32')
    dottest(MDCop, par['nt2']*par['ny'], par['nt2']*par['nx'])

    # Create data
    d = MDCop * mwav.flatten()
    d = d.reshape(par['ny'], par['nt2'])

    # Apply mdd function
    minv = MDD(Gwav[:, :, par['nt']-1:] if par['twosided'] else Gwav,
               d[:, par['nt']-1:] if par['twosided'] else d,
               dt=par['dt'], dr=par['dx'], nfmax=par['nfmax'],
               twosided=par['twosided'], adjoint=False, psf=False, dtype='complex64',
               dottest=False,
               **dict(damp=1e-10, iter_lim=50, show=1))
    assert_array_almost_equal(mwav, minv, decimal=2)
def test_ChirpRadon3D(par):
    """Dot-test, forward, analytical inverse and sparse inverse
    for ChirpRadon3D operator
    """
    parmod = {
        'ot': 0,
        'dt': 0.004,
        'nt': par['nt'],
        'ox': par['nhx'] * 10 / 2,
        'dx': 10,
        'nx': par['nhx'],
        'oy': par['nhy'] * 10 / 2,
        'dy': 10,
        'ny': par['nhy'],
        'f0': 40
    }
    theta = [
        20,
    ]
    phi = [
        0,
    ]
    t0 = [
        0.1,
    ]
    amp = [
        1.,
    ]

    # Create axis
    t, t2, hx, hy = makeaxis(parmod)

    # Create wavelet
    wav, _, wav_c = ricker(t[:41], f0=parmod['f0'])

    # Generate model
    _, x = linear3d(hy, hx, t, 1500., t0, theta, phi, amp, wav)
    Rop = ChirpRadon3D(t,
                       hy,
                       hx, (par['pymax'], par['pxmax']),
                       engine=par['engine'],
                       dtype='float64',
                       **dict(flags=('FFTW_ESTIMATE', ), threads=2))
    assert dottest(Rop, par['nhy'] * par['nhx'] * par['nt'],
                   par['nhy'] * par['nhx'] * par['nt'])

    y = Rop * x.ravel()
    xinvana = Rop.inverse(y)
    assert_array_almost_equal(x.ravel(), xinvana, decimal=3)

    xinv, _, _ = FISTA(Rop, y, 30, eps=1e0, returninfo=True)
    assert_array_almost_equal(x.ravel(), xinv, decimal=3)
def test_MDC_compute(par):
    """Ensure that forward and adjoint of MDC return numpy array when
    compute=True
    """
    par['nt2'] = par['nt']
    v = 1500
    it0_m = 25
    t0_m = it0_m * par['dt']
    theta_m = 0
    amp_m = 1.

    it0_G = np.array([25, 50, 75])
    t0_G = it0_G * par['dt']
    theta_G = (0, 0, 0)
    phi_G = (0, 0, 0)
    amp_G = (1., 0.6, 2.)

    # Create axis
    t, _, x, y = makeaxis(par)

    # Create wavelet
    wav = ricker(t[:41], f0=par['f0'])[0]

    # Generate model
    _, mwav = linear2d(x, t, v, t0_m, theta_m, amp_m, wav)
    # Generate operator
    _, Gwav = linear3d(x, y, t, v, t0_G, theta_G, phi_G, amp_G, wav)

    # Define MDC linear operator
    Gwav_fft = np.fft.fft(Gwav, par['nt2'], axis=-1)
    Gwav_fft = Gwav_fft[..., :par['nfmax']]

    dMDCop = dMDC(da.from_array(Gwav_fft.transpose(2, 0, 1)),
                  nt=par['nt2'],
                  nv=1,
                  dt=par['dt'],
                  dr=par['dx'],
                  twosided=par['twosided'],
                  todask=(True, True),
                  compute=(True, True))

    assert isinstance(dMDCop.matvec(np.ones(dMDCop.shape[1])), np.ndarray)
    assert isinstance(dMDCop.rmatvec(np.ones(dMDCop.shape[0])), np.ndarray)
def test_ChirpRadon2D(par):
    """Dot-test, forward, analytical inverse and sparse inverse
    for ChirpRadon2D operator
    """
    parmod = {
        'ot': 0,
        'dt': 0.004,
        'nt': par['nt'],
        'ox': par['nhx'] * 10 / 2,
        'dx': 10,
        'nx': par['nhx'],
        'f0': 40
    }
    theta = [
        20,
    ]
    t0 = [
        0.1,
    ]
    amp = [
        1.,
    ]

    # Create axis
    t, t2, hx, _ = makeaxis(parmod)

    # Create wavelet
    wav, _, wav_c = ricker(t[:41], f0=parmod['f0'])

    # Generate model
    _, x = linear2d(hx, t, 1500., t0, theta, amp, wav)

    Rop = ChirpRadon2D(t, hx, par['pxmax'], dtype='float64')
    assert dottest(Rop, par['nhx'] * par['nt'], par['nhx'] * par['nt'])

    y = Rop * x.ravel()
    xinvana = Rop.inverse(y)
    assert_array_almost_equal(x.ravel(), xinvana, decimal=3)

    xinv, _, _ = FISTA(Rop, y, 30, eps=1e0, returninfo=True)
    assert_array_almost_equal(x.ravel(), xinv, decimal=3)
Exemple #9
0
def test_ChirpRadon2D(par):
    """Dot-test, forward, analytical inverse and sparse inverse
    for ChirpRadon2D operator
    """
    parmod = {
        "ot": 0,
        "dt": 0.004,
        "nt": par["nt"],
        "ox": par["nhx"] * 10 / 2,
        "dx": 10,
        "nx": par["nhx"],
        "f0": 40,
    }
    theta = [
        20,
    ]
    t0 = [
        0.1,
    ]
    amp = [
        1.0,
    ]

    # Create axis
    t, t2, hx, _ = makeaxis(parmod)

    # Create wavelet
    wav, _, wav_c = ricker(t[:41], f0=parmod["f0"])

    # Generate model
    _, x = linear2d(hx, t, 1500.0, t0, theta, amp, wav)

    Rop = ChirpRadon2D(t, hx, par["pxmax"], dtype="float64")
    assert dottest(Rop, par["nhx"] * par["nt"], par["nhx"] * par["nt"])

    y = Rop * x.ravel()
    xinvana = Rop.inverse(y)
    assert_array_almost_equal(x.ravel(), xinvana, decimal=3)

    xinv, _, _ = FISTA(Rop, y, 30, eps=1e0, returninfo=True)
    assert_array_almost_equal(x.ravel(), xinv, decimal=3)
def test_MDC_1virtualsource(par):
    """Dot-test and inversion for MDC operator of 1 virtual source"""
    if par["twosided"]:
        par["nt2"] = 2 * par["nt"] - 1
    else:
        par["nt2"] = par["nt"]
    v = 1500
    it0_m = 25
    t0_m = it0_m * par["dt"]
    theta_m = 0
    amp_m = 1.0

    it0_G = np.array([25, 50, 75])
    t0_G = it0_G * par["dt"]
    theta_G = (0, 0, 0)
    phi_G = (0, 0, 0)
    amp_G = (1.0, 0.6, 2.0)

    # Create axis
    t, _, x, y = makeaxis(par)

    # Create wavelet
    wav = ricker(t[:41], f0=par["f0"])[0]

    # Generate model
    _, mwav = linear2d(x, t, v, t0_m, theta_m, amp_m, wav)
    # Generate operator
    _, Gwav = linear3d(x, y, t, v, t0_G, theta_G, phi_G, amp_G, wav)

    # Add negative part to data and model
    if par["twosided"]:
        mwav = np.concatenate((np.zeros((par["nx"], par["nt"] - 1)), mwav),
                              axis=-1)
        Gwav = np.concatenate((np.zeros(
            (par["ny"], par["nx"], par["nt"] - 1)), Gwav),
                              axis=-1)

    # Define MDC linear operator
    Gwav_fft = np.fft.fft(Gwav, par["nt2"], axis=-1)
    Gwav_fft = Gwav_fft[..., :par["nfmax"]]
    MDCop = MDC(
        Gwav_fft,
        nt=par["nt2"],
        nv=1,
        dt=par["dt"],
        dr=par["dx"],
        fftengine="fftw",
        twosided=par["twosided"],
        dtype="float32",
    )
    dottest(MDCop, par["nt2"] * par["ny"], par["nt2"] * par["nx"])
    # Create data
    d = MDCop * mwav.ravel()
    d = d.reshape(par["ny"], par["nt2"])

    # Check that events are at correct time and correct amplitude
    for it, amp in zip(it0_G, amp_G):
        ittot = it0_m + it
        if par["twosided"]:
            ittot += par["nt"] - 1
        assert (np.abs(d[par["ny"] // 2, ittot] -
                       np.abs(wav**2).sum() * amp_m * amp * par["nx"] *
                       par["dx"] * par["dt"] * np.sqrt(par["nt2"])) < 1e-2)

    # Check that MDC with prescaled=True gives same result
    MDCpreop = MDC(
        np.sqrt(par["nt2"]) * par["dt"] * par["dx"] * Gwav_fft,
        nt=par["nt2"],
        nv=1,
        dt=par["dt"],
        dr=par["dx"],
        fftengine="fftw",
        twosided=par["twosided"],
        prescaled=True,
        dtype="float32",
    )
    dottest(MDCpreop, par["nt2"] * par["ny"], par["nt2"] * par["nx"])
    dpre = MDCpreop * mwav.ravel()
    dpre = dpre.reshape(par["ny"], par["nt2"])
    assert_array_equal(d, dpre)

    # Apply mdd function
    minv = MDD(Gwav[:, :, par["nt"] - 1:] if par["twosided"] else Gwav,
               d[:, par["nt"] - 1:] if par["twosided"] else d,
               dt=par["dt"],
               dr=par["dx"],
               nfmax=par["nfmax"],
               twosided=par["twosided"],
               adjoint=False,
               psf=False,
               dtype="complex64",
               dottest=False,
               **dict(damp=1e-10, iter_lim=50, show=0))
    assert_array_almost_equal(mwav, minv, decimal=2)

    # Same tests for future behaviour (remove tests above in v2.0.0)
    MDCop = MDC(
        Gwav_fft.transpose(2, 0, 1),
        nt=par["nt2"],
        nv=1,
        dt=par["dt"],
        dr=par["dx"],
        twosided=par["twosided"],
        transpose=False,
        dtype="float32",
    )
    dottest(MDCop, par["nt2"] * par["ny"], par["nt2"] * par["nx"])
    mwav = mwav.T
    d = MDCop * mwav.ravel()
    d = d.reshape(par["nt2"], par["ny"])

    for it, amp in zip(it0_G, amp_G):
        ittot = it0_m + it
        if par["twosided"]:
            ittot += par["nt"] - 1
        assert (np.abs(d[ittot, par["ny"] // 2] -
                       np.abs(wav**2).sum() * amp_m * amp * par["nx"] *
                       par["dx"] * par["dt"] * np.sqrt(par["nt2"])) < 1e-2)

    minv = MDD(Gwav[:, :, par["nt"] - 1:] if par["twosided"] else Gwav,
               d[par["nt"] - 1:].T if par["twosided"] else d.T,
               dt=par["dt"],
               dr=par["dx"],
               nfmax=par["nfmax"],
               twosided=par["twosided"],
               add_negative=True,
               adjoint=False,
               psf=False,
               dtype="complex64",
               dottest=False,
               **dict(damp=1e-10, iter_lim=50, show=0))
    assert_array_almost_equal(mwav, minv.T, decimal=2)
Exemple #11
0
m = np.log(vp * rho)
mback = filtfilt(np.ones(nsmooth) / float(nsmooth), 1, m)

# 2d model
inputfile = 'testdata/avo/poststack_model.npz'
model = np.load(inputfile)
x, z, m2d = model['x'][::3], model['z'][::3], \
            np.log(model['model'][::3, ::3])
nx, nz = len(x), len(z)

mback2d = filtfilt(np.ones(nsmooth) / float(nsmooth), 1, m2d, axis=0)
mback2d = filtfilt(np.ones(nsmooth) / float(nsmooth), 1, mback2d, axis=1)

# wavelet
wav = ricker(t0[:ntwav // 2 + 1], 20)[0]

par1 = {
    'epsR': None,
    'epsRL1': None,
    'epsI': None,
    'simultaneous': False
}  # unregularized
par2 = {
    'epsR': 1e-4,
    'epsRL1': None,
    'epsI': 1e-6,
    'simultaneous': False
}  # regularized
par3 = {
    'epsR': None,
Exemple #12
0
par1 = PAR.copy() # analytical
par1['kind'] = 'analytical'
par2 = PAR.copy() # inverse
par2['kind'] = 'inverse'

# separation params
vel_sep = 1000.0 # velocity at separation level
rho_sep = 1000.0 # density at separation level
critical = 0.9
ntaper = 41
nfftf = 2**8
nfftk = 2**7

# axes and wavelet
t, t2, x, y = makeaxis(PAR)
wav = ricker(t[:41], f0=PAR['f0'])[0]


@pytest.fixture(scope="module")
def create_data2D():
    """Create 2d dataset
    """
    t0_plus = np.array([0.05, 0.12])
    t0_minus = t0_plus + 0.04
    vrms = np.array([1400., 1800.])
    amp = np.array([1., -0.6])

    _, p2d_minus = hyperbolic2d(x, t, t0_minus, vrms, amp, wav)
    _, p2d_plus = hyperbolic2d(x, t, t0_plus, vrms, amp, wav)

    UPop = \
Exemple #13
0
sy = np.linspace(y.min(), y.max(), PAR['nsy'])
sx = np.linspace(x.min(), x.max(), PAR['nsx'])
syy, sxx = np.meshgrid(sy, sx, indexing='ij')
s2d = np.vstack((sx, 2 * np.ones(PAR['nsx'])))
s3d = np.vstack(
    (syy.ravel(), sxx.ravel(), 2 * np.ones(PAR['nsx'] * PAR['nsy'])))

ry = np.linspace(y.min(), y.max(), PAR['nry'])
rx = np.linspace(x.min(), x.max(), PAR['nrx'])
ryy, rxx = np.meshgrid(ry, rx, indexing='ij')
r2d = np.vstack((rx, 2 * np.ones(PAR['nrx'])))
r3d = np.vstack(
    (ryy.ravel(), rxx.ravel(), 2 * np.ones(PAR['nrx'] * PAR['nry'])))

wav, _, wavc = ricker(t[:41], f0=40)

par1 = {'mode': 'analytic'}
par2 = {'mode': 'eikonal'}
par3 = {'mode': 'byot'}


def test_identify_geometry():
    """Identify geometry, check expected outputs
    """
    # 2d
    ndims, shiftdim, dims, ny, nx, nz, ns, nr, dy, dx, dz, dsamp, origin = \
        _identify_geometry(z, x, s2d, r2d)
    assert ndims == 2
    assert shiftdim == 0
    assert [1, 2] == [1, 2]
def test_MDC_Nvirtualsources(par):
    """Dot-test and inversion for MDC operator of N virtual source
    """
    if par['twosided']:
        par['nt2'] = 2 * par['nt'] - 1
    else:
        par['nt2'] = par['nt']
    v = 1500
    it0_m = 25
    t0_m = it0_m * par['dt']
    theta_m = 0
    phi_m = 0
    amp_m = 1.

    it0_G = np.array([25, 50, 75])
    t0_G = it0_G * par['dt']
    theta_G = (0, 0, 0)
    phi_G = (0, 0, 0)
    amp_G = (1., 0.6, 2.)

    # Create axis
    t, _, x, y = makeaxis(par)

    # Create wavelet
    wav = ricker(t[:41], f0=par['f0'])[0]

    # Generate model
    _, mwav = linear3d(x, x, t, v, t0_m, theta_m, phi_m, amp_m, wav)

    # Generate operator
    _, Gwav = linear3d(x, y, t, v, t0_G, theta_G, phi_G, amp_G, wav)

    # Add negative part to data and model
    if par['twosided']:
        mwav = np.concatenate((np.zeros(
            (par['nx'], par['nx'], par['nt'] - 1)), mwav),
                              axis=-1)
        Gwav = np.concatenate((np.zeros(
            (par['ny'], par['nx'], par['nt'] - 1)), Gwav),
                              axis=-1)

    # Define MDC linear operator
    Gwav_fft = np.fft.fft(Gwav, par['nt2'], axis=-1)
    Gwav_fft = Gwav_fft[..., :par['nfmax']]

    MDCop = MDC(Gwav_fft,
                nt=par['nt2'],
                nv=par['nx'],
                dt=par['dt'],
                dr=par['dx'],
                twosided=par['twosided'],
                dtype='float32')
    dottest(MDCop, par['nt2'] * par['ny'] * par['nx'],
            par['nt2'] * par['nx'] * par['nx'])

    # Create data
    d = MDCop * mwav.flatten()
    d = d.reshape(par['ny'], par['nx'], par['nt2'])

    # Check that events are at correct time
    for it, amp in zip(it0_G, amp_G):
        ittot = it0_m + it
        if par['twosided']:
            ittot += par['nt'] - 1
        assert d[par['ny'] // 2, par['nx'] // 2, ittot] > \
               d[par['ny'] // 2, par['nx'] // 2, ittot - 1]
        assert d[par['ny'] // 2, par['nx'] // 2, ittot] > \
               d[par['ny'] // 2, par['nx'] // 2, ittot + 1]

    # Apply mdd function
    minv = MDD(Gwav[:, :, par['nt'] - 1:] if par['twosided'] else Gwav,
               d[:, :, par['nt'] - 1:] if par['twosided'] else d,
               dt=par['dt'],
               dr=par['dx'],
               nfmax=par['nfmax'],
               twosided=par['twosided'],
               adjoint=False,
               psf=False,
               dtype='complex64',
               dottest=False,
               **dict(damp=1e-10, iter_lim=50, show=1))
    assert_array_almost_equal(mwav, minv, decimal=2)

    # Same tests for future behaviour (remove tests above in v2.0.0)
    MDCop = MDC(Gwav_fft.transpose(2, 0, 1),
                nt=par['nt2'],
                nv=par['nx'],
                dt=par['dt'],
                dr=par['dx'],
                twosided=par['twosided'],
                transpose=False,
                dtype='float32')
    dottest(MDCop, par['nt2'] * par['ny'] * par['nx'],
            par['nt2'] * par['nx'] * par['nx'])

    mwav = mwav.transpose(2, 0, 1)
    d = MDCop * mwav.flatten()
    d = d.reshape(par['nt2'], par['ny'], par['nx'])

    for it, amp in zip(it0_G, amp_G):
        ittot = it0_m + it
        if par['twosided']:
            ittot += par['nt'] - 1
        assert d[ittot, par['ny'] // 2, par['nx'] // 2] > \
               d[ittot - 1, par['ny'] // 2, par['nx'] // 2]
        assert d[ittot, par['ny'] // 2, par['nx'] // 2] > \
               d[ittot + 1, par['ny'] // 2, par['nx'] // 2]

    minv = MDD(
        Gwav[:, :, par['nt'] - 1:] if par['twosided'] else Gwav,
        d[par['nt'] -
          1:].transpose(1, 2, 0) if par['twosided'] else d.transpose(1, 2, 0),
        dt=par['dt'],
        dr=par['dx'],
        nfmax=par['nfmax'],
        twosided=par['twosided'],
        add_negative=True,
        adjoint=False,
        psf=False,
        dtype='complex64',
        dottest=False,
        **dict(damp=1e-10, iter_lim=50, show=1))
    assert_array_almost_equal(mwav, minv.transpose(2, 0, 1), decimal=2)
Exemple #15
0
m = np.log(vp * rho)
mback = filtfilt(np.ones(nsmooth) / float(nsmooth), 1, m)

# 2d model
inputfile = 'testdata/avo/poststack_model.npz'
model = np.load(inputfile)
x, z, m2d = model['x'][::3], model['z'][::3], \
            np.log(model['model'][::3, ::3])
nx, nz = len(x), len(z)

mback2d = filtfilt(np.ones(nsmooth) / float(nsmooth), 1, m2d, axis=0)
mback2d = filtfilt(np.ones(nsmooth) / float(nsmooth), 1, mback2d, axis=1)

# stationary wavelet
wav = ricker(t0[:ntwav // 2 + 1], 20)[0]

# non-stationary wavelet
f0s = np.flip(np.arange(nt0) * 0.05 + 3)
wavs = np.array([ricker(t0[:ntwav], f0)[0] for f0 in f0s])
wavc = np.argmax(wavs[0])

par1 = {
    'epsR': None,
    'epsRL1': None,
    'epsI': None,
    'simultaneous': False
}  # unregularized
par2 = {
    'epsR': 1e-4,
    'epsRL1': None,
Exemple #16
0
# steps, such as angle muting.
#
# To get started, let us create a 2D seismic dataset containing some hyperbolic
# events representing reflections from flat reflectors.
# Events are created with a true RMS velocity, which we will be using as if we
# picked them from, for example, a semblance panel.

par = dict(ox=0, dx=40, nx=80, ot=0, dt=0.004, nt=520)
t, _, x, _ = makeaxis(par)

t0s_true = np.array([0.5, 1.22, 1.65])
vrms_true = np.array([2000.0, 2400.0, 2500.0])
amps = np.array([1, 0.2, 0.5])

freq = 10  # Hz
wav, *_ = ricker(t[:41], f0=freq)

_, data = hyperbolic2d(x, t, t0s_true, vrms_true, amp=amps, wav=wav)


###############################################################################

# NMO correction plot
pclip = 0.5
dmax = np.max(np.abs(data))
opts = dict(
    cmap="gray_r",
    extent=[x[0], x[-1], t[-1], t[0]],
    aspect="auto",
    vmin=-pclip * dmax,
    vmax=pclip * dmax,
Exemple #17
0
###############################################################################
# Let's start by creating a very simple 2d data composed of 3 linear events
# input parameters
par = {'ox': 0, 'dx': 2, 'nx': 70, 'ot': 0, 'dt': 0.004, 'nt': 80, 'f0': 20}

v = 1500
t0_m = [0.1, 0.2, 0.28]
theta_m = [0, 30, -80]
phi_m = [0]
amp_m = [1., -2, 0.5]

# axis
taxis, t2, xaxis, y = makeaxis(par)

# wavelet
wav = ricker(taxis[:41], f0=par['f0'])[0]

# model
_, x = linear2d(xaxis, taxis, v, t0_m, theta_m, amp_m, wav)

###############################################################################
# We can now define the spatial locations along which the data has been
# sampled. In this specific example we will assume that we have access only to
# 40% of the 'original' locations.
perc_subsampling = 0.6
nxsub = int(np.round(par['nx'] * perc_subsampling))

iava = np.sort(np.random.permutation(np.arange(par['nx']))[:nxsub])

# restriction operator
Rop = pylops.Restriction(par['nx'] * par['nt'],
Exemple #18
0
dt0 = 0.004
t0 = np.arange(nt0) * dt0
vp = 1200 + np.arange(nt0) + filtfilt(
    np.ones(5) / 5., 1, np.random.normal(0, 80, nt0))
rho = 1000 + vp + filtfilt(np.ones(5) / 5., 1, np.random.normal(0, 30, nt0))
vp[201:] += 500
rho[201:] += 100
m = np.log(vp * rho)

# smooth model
nsmooth = 100
mback = filtfilt(np.ones(nsmooth) / float(nsmooth), 1, m)

# wavelet
ntwav = 41
wav, twav, wavc = ricker(t0[:ntwav // 2 + 1], 20)

# dense operator
PPop_dense = pylops.avo.poststack.PoststackLinearModelling(wav,
                                                           nt0=nt0,
                                                           explicit=True)

# lop operator
PPop = pylops.avo.poststack.PoststackLinearModelling(wav, nt0=nt0)

# data
d_dense = PPop_dense * m.flatten()
d = PPop * m

# add noise
dn_dense = d_dense + np.random.normal(0, 2e-2, d_dense.shape)
Exemple #19
0
v = 1500
t0 = [0.1, 0.2, 0.3]
theta = [0, 0, 0]
amp = [1.0, -2, 0.5]

# parabolic event
tp0 = [0.13]
px = [0]
pxx = [5e-7]
ampp = [0.7]

# create axis
taxis, taxis2, xaxis, yaxis = pylops.utils.seismicevents.makeaxis(par)

# create wavelet
wav = ricker(taxis[:41], f0=par["f0"])[0]

# generate model
y = (pylops.utils.seismicevents.linear2d(xaxis, taxis, v, t0, theta, amp,
                                         wav)[1] +
     pylops.utils.seismicevents.parabolic2d(xaxis, taxis, tp0, px, pxx, ampp,
                                            wav)[1])

###############################################################################
# We can now create the :py:class:`pylops.signalprocessing.Radon2D` operator.
# We also apply its adjoint to the data to obtain a representation of those
# 3 linear events overlapping to a parabolic event in the Radon domain.
# Similarly, we feed the operator to a sparse solver like
# :py:class:`pylops.optimization.sparsity.FISTA` to obtain a sparse
# represention of the data in the Radon domain. At this point we try to filter
# out the unwanted event. We can see how this is much easier for the sparse
Exemple #20
0
import pytest

import numpy as np
from numpy.testing import assert_array_equal

from pylops.utils.wavelets import ricker
from pylops.utils.seismicevents import makeaxis, linear2d, linear3d
from pylops.utils.seismicevents import parabolic2d, hyperbolic2d, hyperbolic3d

# Wavelet
wav = ricker(np.arange(41) * 0.004, f0=10)[0]

par1 = {
    'ot': 0,
    'dt': 1,
    'nt': 300,
    'ox': 0,
    'dx': 2,
    'nx': 200,
    'oy': 0,
    'dy': 2,
    'ny': 100
}  # even axis

par2 = {
    'ot': 0,
    'dt': 1,
    'nt': 301,
    'ox': -200,
    'dx': 2,
    'nx': 201,
Exemple #21
0
rho[131:] += 100
vsvp = 0.5
m = np.stack((np.log(vp), np.log(vs), np.log(rho)), axis=1)

# background model
nsmooth = 50
mback = filtfilt(np.ones(nsmooth) / float(nsmooth), 1, m, axis=0)

# angles
ntheta = 21
thetamin, thetamax = 0, 40
theta = np.linspace(thetamin, thetamax, ntheta)

# wavelet
ntwav = 41
wav = ricker(t0[: ntwav // 2 + 1], 15)[0]

# lop
PPop = pylops.avo.prestack.PrestackLinearModelling(
    wav, theta, vsvp=vsvp, nt0=nt0, linearization="akirich"
)

# dense
PPop_dense = pylops.avo.prestack.PrestackLinearModelling(
    wav, theta, vsvp=vsvp, nt0=nt0, linearization="akirich", explicit=True
)

# data lop
dPP = PPop * m.ravel()
dPP = dPP.reshape(nt0, ntheta)
def test_MDC_1virtualsource(par):
    """Dot-test and comparison with pylops for MDC operator of 1 virtual source
    """
    if par['twosided']:
        par['nt2'] = 2 * par['nt'] - 1
    else:
        par['nt2'] = par['nt']
    v = 1500
    it0_m = 25
    t0_m = it0_m * par['dt']
    theta_m = 0
    amp_m = 1.

    it0_G = np.array([25, 50, 75])
    t0_G = it0_G * par['dt']
    theta_G = (0, 0, 0)
    phi_G = (0, 0, 0)
    amp_G = (1., 0.6, 2.)

    # Create axis
    t, _, x, y = makeaxis(par)

    # Create wavelet
    wav = ricker(t[:41], f0=par['f0'])[0]

    # Generate model
    _, mwav = linear2d(x, t, v, t0_m, theta_m, amp_m, wav)
    # Generate operator
    _, Gwav = linear3d(x, y, t, v, t0_G, theta_G, phi_G, amp_G, wav)

    # Add negative part to data and model
    if par['twosided']:
        mwav = np.concatenate((np.zeros((par['nx'], par['nt'] - 1)), mwav),
                              axis=-1)
        Gwav = np.concatenate((np.zeros(
            (par['ny'], par['nx'], par['nt'] - 1)), Gwav),
                              axis=-1)

    # Define MDC linear operator
    Gwav_fft = np.fft.fft(Gwav, par['nt2'], axis=-1)
    Gwav_fft = Gwav_fft[..., :par['nfmax']]
    dGwav_fft = da.from_array(Gwav_fft.transpose(2, 0, 1))

    dMDCop = dMDC(dGwav_fft,
                  nt=par['nt2'],
                  nv=1,
                  dt=par['dt'],
                  dr=par['dx'],
                  twosided=par['twosided'])
    MDCop = MDC(Gwav_fft.transpose(2, 0, 1),
                nt=par['nt2'],
                nv=1,
                dt=par['dt'],
                dr=par['dx'],
                twosided=par['twosided'],
                transpose=False,
                dtype='float32')
    dottest(dMDCop,
            par['nt2'] * par['ny'],
            par['nt2'] * par['nx'],
            chunks=((par['nt2'] * par['ny'], par['nt2'] * par['nx'])))

    # Compare results with pylops implementation
    mwav = mwav.T
    dy = dMDCop * da.from_array(mwav.flatten())
    y = MDCop * mwav.flatten()
    assert_array_almost_equal(dy.compute(), y, decimal=5)

    # Apply mdd function
    dy = dy.reshape(par['nt2'], par['ny'])
    print(dy)
    minv = MDD(dGwav_fft,
               dy[par['nt'] - 1:] if par['twosided'] else dy,
               dt=par['dt'],
               dr=par['dx'],
               nfmax=par['nfmax'],
               twosided=par['twosided'],
               adjoint=False,
               dottest=False,
               **dict(niter=50))
    print('minv', minv)
    assert_array_almost_equal(mwav, minv.compute(), decimal=2)
Exemple #23
0
t0_m = [0.2]
vrms_m = [700.0]
amp_m = [1.0]

t0_G = [0.2, 0.5, 0.7]
vrms_G = [800.0, 1200.0, 1500.0]
amp_G = [1.0, 0.6, 0.5]

# Taper
tap = taper3d(par["nt"], [par["ny"], par["nx"]], (5, 5), tapertype="hanning")

# Create axis
t, t2, x, y = makeaxis(par)

# Create wavelet
wav = ricker(t[:41], f0=par["f0"])[0]

# Generate model
m, mwav = hyperbolic2d(x, t, t0_m, vrms_m, amp_m, wav)

# Generate operator
G, Gwav = np.zeros((par["ny"], par["nx"], par["nt"])), np.zeros(
    (par["ny"], par["nx"], par["nt"]))
for iy, y0 in enumerate(y):
    G[iy], Gwav[iy] = hyperbolic2d(x - y0, t, t0_G, vrms_G, amp_G, wav)
G, Gwav = G * tap, Gwav * tap

# Add negative part to data and model
m = np.concatenate((np.zeros((par["nx"], par["nt"] - 1)), m), axis=-1)
mwav = np.concatenate((np.zeros((par["nx"], par["nt"] - 1)), mwav), axis=-1)
Gwav2 = np.concatenate((np.zeros((par["ny"], par["nx"], par["nt"] - 1)), Gwav),
par1 = PAR.copy()  # analytical
par1["kind"] = "analytical"
par2 = PAR.copy()  # inverse
par2["kind"] = "inverse"

# separation params
vel_sep = 1000.0  # velocity at separation level
rho_sep = 1000.0  # density at separation level
critical = 0.99
ntaper = 5
nfftf = 2**6
nfftk = 2**6

# axes and wavelet
t, t2, x, y = makeaxis(PAR)
wav = ricker(t[:41], f0=PAR["f0"])[0]


@pytest.fixture(scope="module")
def create_data2D():
    """Create 2d dataset"""
    t0_plus = np.array([0.05, 0.12])
    t0_minus = t0_plus + 0.04
    vrms = np.array([1400.0, 1800.0])
    amp = np.array([1.0, -0.6])

    _, p2d_minus = hyperbolic2d(x, t, t0_minus, vrms, amp, wav)
    _, p2d_plus = hyperbolic2d(x, t, t0_plus, vrms, amp, wav)

    UPop = UpDownComposition2D(
        PAR["nt"],
Exemple #25
0
    'nt': 200,
    'f0': 40
}

t0_plus = np.array([0.2, 0.5, 0.7])
t0_minus = t0_plus + 0.04
vrms = np.array([1400., 1500., 2000.])
amp = np.array([1., -0.6, 0.5])
vel_sep = 1000.0  # velocity at separation level
rho_sep = 1000.0  # density at separation level

# Create axis
t, t2, x, y = makeaxis(par)

# Create wavelet
wav = ricker(t[:41], f0=par['f0'])[0]

# Create data
_, p_minus = hyperbolic2d(x, t, t0_minus, vrms, amp, wav)
_, p_plus = hyperbolic2d(x, t, t0_plus, vrms, amp, wav)

###############################################################################
# We can now combine them to create pressure and particle velocity data
critical = 1.1
ntaper = 51
nfft = 2**10

# 2d fft operator
FFTop = pylops.signalprocessing.FFT2D(dims=[par['nx'], par['nt']],
                                      nffts=[nfft, nfft],
                                      sampling=[par['dx'], par['dt']])
def MakeSeismic(samples, img_size=128, freq_low=5, freq_high=30, num_events=6):
    """Simple generation of noisy synthetic linear seismic events. 
        Input:
        samples =  Number of samples in your dataset you want
        
        Output: 
        clean_signal, noise, noisy_signal"""
    random.seed(101)
    # empty list to be filled with numpy arrays
    clean_signal = []
    noise = []
    noisy_signal = []
    # Parameters for the seismic canvas
    par = {
        'ox': 0,
        'dx': 12.5,
        'nx': img_size,  # offsets
        'ot': 0,
        'dt': 0.004,
        'nt': img_size,  # time
        'f0': random.randint(5, 70),
        'nfmax': 50
    }
    # initial tests, max freq was 30
    # Make canvas
    t, t2, x, y = makeaxis(par)
    # Make wavelet
    wav = ricker(np.arange(41) * par['dt'], f0=par['f0'])[0]
    # Parameters for events
    v = 1500
    ang_range = 50
    amp_range = 2
    i = 0
    amp_lim = 0.2
    while i < samples:
        iEv = 0
        t0 = []
        theta = []
        amp = []
        while iEv <= num_events:
            # Time of events
            t0.append(random.uniform(t.min(), t.max()) * 0.7)
            # Angle of events
            theta.append(random.uniform(-ang_range, ang_range))
            # Amplitude of events
            amp.append(random.uniform(-amp_range, amp_range))
            # clipping events to be above -0.2 and 0.2
            if amp[iEv] < 0:
                amp[iEv] = np.min([-amp_lim, amp[iEv]])
            else:
                amp[iEv] = np.max([amp_lim, amp[iEv]])
            iEv += 1

        # Making events
        mlin, mlinwav = linear2d(x, t, v, t0, theta, amp, wav)
        # Creating noise
        n = np.random.normal(loc=0, scale=0.25, size=(img_size, img_size))

        # Adding noise
        s = mlinwav
        ns = s + n
        clean_signal.append(s)
        noise.append(n)
        noisy_signal.append(ns)
        i += 1

    return np.array(clean_signal).reshape(
        samples, img_size, img_size, 1), np.array(noise).reshape(
            samples, img_size, img_size,
            1), np.array(noisy_signal).reshape(samples, img_size, img_size, 1)
Exemple #27
0
print('PyLops-gpu working on %s...' % dev)
plt.close('all')

###############################################################################
# We will start by creating a zero signal of length :math:`nt` and we will
# place a unitary spike at its center. We also create our filter to be
# applied by means of :py:class:`pylops_gpu.signalprocessing.Convolve1D`
# operator.
nt = 1001
dt = 0.004
t = np.arange(nt)*dt

x = torch.zeros(nt, dtype=torch.float32)
x[int(nt/2)] = 1

h, th, hcenter = ricker(t[:101], f0=30)
h = torch.from_numpy(h.astype(np.float32))
Cop = pylops_gpu.signalprocessing.Convolve1D(nt, h=h, offset=hcenter,
                                             dtype=torch.float32)
y = Cop*x

xinv = Cop / y

fig, ax = plt.subplots(1, 1, figsize=(10, 3))
ax.plot(t, x.cpu().numpy(), 'k', lw=2, label=r'$x$')
ax.plot(t, y.cpu().numpy(), 'r', lw=2, label=r'$y=Ax$')
ax.plot(t, xinv.cpu().numpy(), '--g', lw=2, label=r'$x_{ext}$')
ax.set_title('Convolve in 1st direction', fontsize=14, fontweight='bold')
ax.legend()
ax.set_xlim(1.9, 2.1)
def MakeSeismic_VN(samples, img_size=256, num_events=10):
    """Simple generation of noisy synthetic linear seismic events. 
        Input:
        samples =  Number of samples in your dataset you want
        
        Output: 
        clean_signal, noise, noisy_signal"""
    random.seed(101)
    # empty list to be filled with numpy arrays
    clean_signal = []
    noise = []
    noisy_signal = []
    # Parameters for the seismic canvas

    par = {
        'ox': 0,
        'dx': 12.5,
        'nx': img_size,  # offsets
        'ot': 0,
        'dt': 0.004,
        'nt': img_size,  # time
        'f0': random.randint(5, 70),
        'nfmax': 50
    }
    # initial tests, max freq was 50
    # Make canvas
    t, t2, x, y = makeaxis(par)
    # Make wavelet
    wav = ricker(np.arange(41) * par['dt'], f0=par['f0'])[0]
    # Parameters for events
    v = 1500
    # orig amp range was 50
    ang_range = 80
    amp_range = 2
    i = 0
    amp_lim = 0.8
    lv = 1500
    hv = 5000
    while i < samples:
        iEv_l = 0
        iEv_h = 0
        t0_l = []
        t0_h = []
        theta_l = []
        amp_l = []
        amp_h = []
        vel_h = []
        num_lin = random.randint(2, num_events)
        num_hyp = num_events - num_lin
        while iEv_l <= num_lin:
            # Time of events
            t0_l.append(random.uniform(t.min(), t.max()) * 0.7)
            # Angle of events
            theta_l.append(random.uniform(-ang_range, ang_range))
            # Amplitude of events
            amp_l.append(random.uniform(-amp_range, amp_range))
            # clipping events to be above -0.2 and 0.2
            if amp_l[iEv_l] < 0:
                amp_l[iEv_l] = np.min([-amp_lim, amp_l[iEv_l]])
            else:
                amp_l[iEv_l] = np.max([amp_lim, amp_l[iEv_l]])
            iEv_l += 1
        while iEv_h <= num_hyp:
            # Time of events
            t0_h.append(random.uniform(t.min(), t.max()) * 0.7)
            # Amplitude of events
            amp_h.append(random.uniform(-amp_range, amp_range))
            # velocity of hyperbolic events
            vel_h.append(random.uniform(lv, hv))
            # clipping events to be above -0.2 and 0.2
            if amp_h[iEv_h] < 0:
                amp_h[iEv_h] = np.min([-amp_lim, amp_h[iEv_h]])
            else:
                amp_h[iEv_h] = np.max([amp_lim, amp_h[iEv_h]])
            iEv_h += 1

        # Making events
        mlin, mlinwav = linear2d(x, t, v, t0_l, theta_l, amp_l, wav)
        # print (t0_h, vel_h, amp_h)
        # Generate model
        m, mwav = hyperbolic2d(x, t, t0_h, vel_h, amp_h, wav)
        s = mwav + mlinwav

        # Creating and adding noise
        ns1 = random_noise(s,
                           'speckle',
                           clip=False,
                           var=random.uniform(0.2, 2))
        ns2 = random_noise(s,
                           'gaussian',
                           clip=False,
                           var=random.uniform(0.05, 0.5))
        ns3 = random_noise(s,
                           's&p',
                           clip=False,
                           amount=random.uniform(0.05, 0.2))

        # Noise
        n1 = ns1 - s
        n2 = ns2 - s
        n3 = ns3 - s

        clean_signal.append(s)
        clean_signal.append(s)
        clean_signal.append(s)

        noise.append(n1)
        noise.append(n2)
        noise.append(n3)

        noisy_signal.append(ns1)
        noisy_signal.append(ns2)
        noisy_signal.append(ns3)

        i += 1

    return np.array(clean_signal).reshape(
        samples * 3, img_size, img_size, 1), np.array(noise).reshape(
            samples * 3, img_size, img_size,
            1), np.array(noisy_signal).reshape(samples * 3, img_size, img_size,
                                               1)