Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# 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, 'epsI': 1e-6,
'simultaneous': False} # regularized
par3 = {'epsR': None, 'epsRL1': None, 'epsI': None,
'simultaneous': True} # unregularized, simultaneous
par4 = {'epsR': 1e-4, 'epsRL1': None, 'epsI': 1e-6,
'simultaneous': True} # regularized, simultaneous
par5 = {'epsR': 1e-4, 'epsRL1': 1e-1, 'epsI': 1e-6,
'simultaneous': True} # blocky, simultaneous
@pytest.mark.parametrize("par", [(par1), (par2)])
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,
'oy': -100, 'dy': 2, 'ny': 101} # odd axis, centered to 0
@pytest.mark.parametrize("par", [(par1), (par2)])
def test_makeaxis(par):
"""Verify makeaxis creation
"""
# Create t, x, and y axis
t, _, x, y = makeaxis(par)
# produce the expected results (especially in the presence of noisy data),
# conversely using the :py:class:`pylops.optimization.sparsity.ISTA` and
# :py:class:`pylops.optimization.sparsity.FISTA` solvers allows us
# to succesfully retrieve the input signal even in the presence of noise.
# :py:class:`pylops.optimization.sparsity.FISTA` shows faster convergence which
# is particularly useful for this problem.
nt = 61
dt = 0.004
t = np.arange(nt)*dt
x = np.zeros(nt)
x[10] = -.4
x[int(nt/2)] = 1
x[nt-20] = 0.5
h, th, hcenter = pylops.utils.wavelets.ricker(t[:101], f0=20)
Cop = pylops.signalprocessing.Convolve1D(nt, h=h, offset=hcenter,
dtype='float32')
y = Cop*x
yn = y + np.random.normal(0, 0.1, y.shape)
# noise free
xls = Cop / y
xomp, nitero, costo = \
pylops.optimization.sparsity.OMP(Cop, y, niter_outer=200, sigma=1e-8)
xista, niteri, costi = \
pylops.optimization.sparsity.ISTA(Cop, y, niter=400, eps=5e-1,
tol=1e-8, returninfo=True)
t0 = np.arange(nt0)*dt0
thetamin, thetamax = 0, 40
theta = np.linspace(thetamin, thetamax, ntheta)
# Elastic property profiles
vp = 1200 + np.arange(nt0) + filtfilt(np.ones(5)/5., 1, np.random.normal(0, 80, nt0))
vs = 600 + vp/2 + filtfilt(np.ones(5)/5., 1, np.random.normal(0, 20, nt0))
rho = 1000 + vp + filtfilt(np.ones(5)/5., 1, np.random.normal(0, 30, nt0))
vp[201:] += 500
vs[201:] += 200
rho[201:] += 100
# Wavelet
ntwav = 41
wavoff = 10
wav, twav, wavc = ricker(t0[:ntwav//2+1], 20)
wav_phase = np.hstack((wav[wavoff:], np.zeros(wavoff)))
# vs/vp profile
vsvp = 0.5
vsvp_z = np.linspace(0.4, 0.6, nt0)
# Model
m = np.stack((np.log(vp), np.log(vs), np.log(rho)), axis=1)
fig, axs = plt.subplots(1, 3, figsize=(13, 7), sharey=True)
axs[0].plot(vp, t0, 'k')
axs[0].set_title('Vp')
axs[0].set_ylabel(r'$t(s)$')
axs[0].invert_yaxis()
axs[0].grid()
axs[1].plot(vs, t0, 'k')
plt.close('all')
############################################
# Let's first define the time and space axes as well as some auxiliary input
# parameters that we will use to create a Ricker wavelet
par = {'ox':-200, 'dx':2, 'nx':201,
'oy':-100, 'dy':2, 'ny':101,
'ot':0, 'dt':0.004, 'nt':501,
'f0': 20, 'nfmax': 210}
# Create axis
t, t2, x, y = pylops.utils.seismicevents.makeaxis(par)
# Create wavelet
wav = pylops.utils.wavelets.ricker(np.arange(41) * par['dt'],
f0=par['f0'])[0]
############################################
# We want to create a 2d data with a number of crossing linear events using the
# :py:func:`pylops.utils.seismicevents.linear2d` routine.
v = 1500
t0 = [0.2, 0.7, 1.6]
theta = [40, 0, -60]
amp = [1., 0.6, -2.]
mlin, mlinwav = pylops.utils.seismicevents.linear2d(x, t, v, t0,
theta, amp, wav)
############################################
# We can also create a 2d data with a number of crossing parabolic events using the
# :py:func:`pylops.utils.seismicevents.parabolic2d` routine.
plt.scatter(recs[0], recs[1], marker='v', s=150, c='b', edgecolors='k')
plt.scatter(sources[0], sources[1], marker='*', s=150, c='r', edgecolors='k')
plt.colorbar(im)
plt.axis('tight')
plt.xlabel('x [m]'),plt.ylabel('y [m]')
plt.title('Reflectivity')
plt.xlim(x[0], x[-1])
###############################################################################
# We can now create our LSM object and invert for the reflectivity using two
# different solvers: :py:func:`scipy.sparse.linalg.lsqr` (LS solution) and
# :py:func:`pylops.optimization.sparsity.FISTA` (LS solution with sparse model).
nt = 651
dt = 0.004
t = np.arange(nt)*dt
wav, wavt, wavc = pylops.utils.wavelets.ricker(t[:41], f0=20)
lsm = pylops.waveeqprocessing.LSM(z, x, t, sources, recs, v0, wav, wavc,
mode='analytic')
d = lsm.Demop * refl.ravel()
d = d.reshape(ns, nr, nt)
madj = lsm.Demop.H * d.ravel()
madj = madj.reshape(nx, nz)
minv = lsm.solve(d.ravel(), solver=lsqr, **dict(iter_lim=100))
minv = minv.reshape(nx, nz)
minv_sparse = lsm.solve(d.ravel(),
solver=pylops.optimization.sparsity.FISTA,
vrms_m = 1100.0
amp_m = 1.0
t0_G = (0.2, 0.5, 0.7)
vrms_G = (1200., 1500., 2000.)
amp_G = (1., 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), axis=-1)
t0 = np.arange(nt0)*dt0
thetamin, thetamax = 0, 40
theta = np.linspace(thetamin, thetamax, ntheta)
# Elastic property profiles
vp = 1200 + np.arange(nt0) + filtfilt(np.ones(5)/5., 1, np.random.normal(0, 80, nt0))
vs = 600 + vp/2 + filtfilt(np.ones(5)/5., 1, np.random.normal(0, 20, nt0))
rho = 1000 + vp + filtfilt(np.ones(5)/5., 1, np.random.normal(0, 30, nt0))
vp[201:] += 500
vs[201:] += 200
rho[201:] += 100
# Wavelet
ntwav = 41
wavoff = 10
wav, twav, wavc = ricker(t0[:ntwav//2+1], 20)
wav_phase = np.hstack((wav[wavoff:], np.zeros(wavoff)))
# vs/vp profile
vsvp = 0.5
vsvp_z = np.linspace(0.4, 0.6, nt0)
# Model
m = np.stack((np.log(vp), np.log(vs), np.log(rho)), axis=1)
###############################################################################
# We create now the operators to model the AVO responses for a set of
# elastic profiles
# constant vsvp
PPop_const = \
###############################################################################
# We see how inverting a dense matrix is in this case faster than solving
# for the linear operator (a good estimate of the model is in fact obtained
# only after 2000 iterations of lsqr). Nevertheless, having a linear operator
# is useful when we deal with larger dimensions (2d or 3d) and we want to
# couple our modelling operator with different types of spatial regularizations
# or preconditioning.
#
# Before we move onto a 2d example, let's consider the case of non-stationary
# wavelet and see how we can easily use the same routines in this case
# wavelet
ntwav = 41
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])
plt.figure(figsize=(5, 4))
plt.imshow(wavs.T, cmap='gray', extent=(t0[0], t0[-1], t0[ntwav], -t0[ntwav]))
plt.xlabel('t')
plt.title('Wavelets')
plt.axis('tight')
# operator
PPop = \
pylops.avo.poststack.PoststackLinearModelling(wavs / 2, nt0=nt0, explicit=True)
# data
d = PPop * m
# solve