Example #1
0
def test_eql_grav_jacobian():
    "EQLGravity produces the right Jacobian matrix for single source"
    model = PointGrid([-10, 10, -10, 10], 500, (2, 2))[0]
    model.addprop('density', 1)
    n = 1000
    x, y, z = gridder.scatter([-10, 10, -10, 10], n, z=-100, seed=42)
    data = sphere.gz(x, y, z, [model])

    eql = EQLGravity(x, y, z, data, [model])
    A = eql.jacobian(None)

    assert A.shape == (n, 1)
    assert_allclose(A[:, 0], data, rtol=0.01)
Example #2
0
def test_eqlgrav_prism_interp():
    "EQLGravity can interpolate data from a prism"
    model = [Prism(-300, 300, -500, 500, 100, 600, {'density': 400})]
    shape = (30, 30)
    n = shape[0]*shape[1]
    area = [-2000, 2000, -2000, 2000]
    x, y, z = gridder.scatter(area,  n, z=-100, seed=42)
    data = prism.gz(x, y, z, model)
    layer = PointGrid(area, 200, shape)
    eql = EQLGravity(x, y, z, data, layer) + 1e-23*Damping(layer.size)
    eql.fit()
    layer.addprop('density', eql.estimate_)

    assert_allclose(eql[0].predicted(), data, rtol=0.01)

    xp, yp, zp = gridder.regular(area, shape, z=-100)
    true = prism.gz(xp, yp, zp, model)
    calc = sphere.gz(xp, yp, zp, layer)

    assert_allclose(calc, true, rtol=0.05)
def test_gz_sphere():
    '''
    This test compare the results obtained by both function that calculates the vertical gravitational attraction due to a solid sphere. The model has the same dimensions and same value for the density. We use the function from Fatiando a Terra in order to compare with our function.
    '''

    density = 1500.

    # Modelo para o Fatiando
    xp, yp, zp = gridder.regular((-1000, 1000, -1000, 1000), (200, 200),
                                 z=-345.)
    model = [mesher.Sphere(-100., 400., 550., 380., {'density': density})]
    gz = sphere.gz(xp, yp, zp, model)
    gz = gz.reshape(200, 200)

    # Modelo para minha funcao
    x, y = numpy.meshgrid(numpy.linspace(-1000., 1000., 200),
                          numpy.linspace(-1000., 1000., 200))
    z = -345. * numpy.ones((200, 200))
    mymodel = [-100., 400., 550., 380., density]
    mygz = sphere_gz(y, x, z, mymodel)

    assert_almost_equal(gz, mygz, decimal=5)
Example #4
0
def test_pelgrav_prism_interp():
    "PELGravity can interpolate data from a prism"
    model = [Prism(-300, 300, -500, 500, 100, 600, {'density': 400})]
    shape = (40, 40)
    n = shape[0]*shape[1]
    area = [-2000, 2000, -2000, 2000]
    x, y, z = gridder.scatter(area,  n, z=-100, seed=42)
    data = prism.gz(x, y, z, model)

    layer = PointGrid(area, 100, shape)
    windows = (20, 20)
    degree = 1
    eql = (PELGravity(x, y, z, data, layer, windows, degree)
           + 5e-22*PELSmoothness(layer, windows, degree))
    eql.fit()
    layer.addprop('density', eql.estimate_)

    assert_allclose(eql[0].predicted(), data, rtol=0.01)

    xp, yp, zp = gridder.regular(area, shape, z=-100)
    true = prism.gz(xp, yp, zp, model)
    calc = sphere.gz(xp, yp, zp, layer)

    assert_allclose(calc, true, atol=0.001, rtol=0.05)
Example #5
0
# Estimate the density using enough damping so that won't try to fit the error
eql = EQLGravity(x, y, z, gz, layer) + 1e-22 * Damping(layer.size)
eql.fit()
# Now we add the estimated densities to our layer
layer.addprop('density', eql.estimate_)
# and print some statistics of how well the estimated layer fits the data
residuals = eql[0].residuals()
print("Residuals:")
print("  mean:", residuals.mean(), 'mGal')
print("  stddev:", residuals.std(), 'mGal')

# Now I can forward model gravity data anywhere we want. For interpolation, we
# calculate it on a grid. For upward continuation, at a greater height. We can
# even combine both into a single operation.
x2, y2, z2 = gridder.regular(area, (50, 50), z=-1000)
gz_up = sphere.gz(x2, y2, z2, layer)

fig, axes = plt.subplots(1, 2, figsize=(8, 6))

ax = axes[0]
ax.set_title('Original data')
ax.set_aspect('equal')
tmp = ax.tricontourf(y / 1000, x / 1000, gz, 30, cmap='cubehelix_r')
fig.colorbar(tmp, ax=ax, pad=0.1, aspect=30,
             orientation='horizontal').set_label('mGal')
ax.plot(y / 1000, x / 1000, 'xk')
ax.set_xlabel('y (km)')
ax.set_ylabel('x (km)')

ax = axes[1]
ax.set_title('Gridded and upward continued')
Example #6
0
def test_gz():
    "gravmag.sphere.gz python vs cython implementation"
    py = _sphere_numpy.gz(xp, yp, zp, model)
    cy = sphere.gz(xp, yp, zp, model)
    diff = np.abs(py - cy)
    assert np.all(diff <= precision), 'max diff: %g' % (max(diff))
Example #7
0
 def sensitivity(self, grid):
     x, y, z = self.x, self.y, self.z
     sens = numpy.empty((self.size, len(grid)), dtype=float)
     for i, s in enumerate(grid):
         sens[:, i] = kernel.gz(x, y, z, [s], dens=1.)
     return sens
# Estimate the density
# Need to apply enough damping so that won't try to fit the error as well
misfit = EQLGravity(x, y, z, gz, layer)
regul = Damping(layer.size)
# Use an L-curve analysis to find the best regularization parameter
solver = LCurve(misfit, regul, [10**i for i in range(-30, -20)]).fit()
layer.addprop('density', solver.estimate_)
residuals = solver.residuals()
print "Residuals:"
print "mean:", residuals.mean()
print "stddev:", residuals.std()

# Now I can forward model the layer at a greater height and check against the
# true solution of the prism
gz_true = prism.gz(x, y, z - 500, model)
gz_up = sphere.gz(x, y, z - 500, layer)

mpl.figure()
mpl.suptitle('L-curve')
mpl.title("Estimated regularization parameter: %g" % (solver.regul_param_))
solver.plot_lcurve()
mpl.grid()

mpl.figure(figsize=(14, 4))
mpl.subplot(1, 3, 1)
mpl.axis('scaled')
mpl.title('Layer (kg.m^-3)')
mpl.pcolor(layer.y, layer.x, layer.props['density'], layer.shape)
mpl.colorbar()
mpl.m2km()
mpl.subplot(1, 3, 2)
Example #9
0
# and the inversion
# Apply a scaling factor to make both portions of the misfit the same order of
# magnitude
scale = np.linalg.norm(gz)**2 / np.linalg.norm(gzz)**2
misfit = (EQLGravity(x1, y1, z1, gz, layer) +
          scale * EQLGravity(x2, y2, z2, gzz, layer, field='gzz'))
regul = Smoothness2D(layer.shape)
# Use an L-curve analysis to find the best regularization parameter
solver = LCurve(misfit, regul, [10**i for i in range(-30, -20)]).fit()
layer.addprop('density', solver.estimate_)

# Now I can forward model gz using my layer to produce an integrated map in a
# much denser region
shape = (50, 50)
x, y, z = gridder.regular(area, shape, z=0)
gz_layer = sphere.gz(x, y, z, layer)
gz_true = prism.gz(x, y, z, model)

mpl.figure()
mpl.suptitle('L-curve')
mpl.title("Estimated regularization parameter: %g" % (solver.regul_param_))
solver.plot_lcurve()
mpl.grid()

# Plot the layer and the fit
mpl.figure(figsize=(14, 4))
mpl.suptitle('Observed data (black) | Predicted by layer (red)')
mpl.subplot(1, 3, 1)
mpl.axis('scaled')
mpl.title('Layer (kg.m^-3)')
mpl.pcolor(layer.y, layer.x, layer.props['density'], layer.shape)
Example #10
0
"""
GravMag: Forward modeling of the gravity anomaly and gravity gradient tensor
using model
"""
from fatiando import mesher, gridder
from fatiando.gravmag import sphere
from fatiando.vis import mpl

model = [mesher.Sphere(0, 0, 2000, 1000, {'density': 1000})]
area = (-5000, 5000, -5000, 5000)
shape = (100, 100)
x, y, z = gridder.regular(area, shape, z=-100)
gz = sphere.gz(x, y, z, model)
tensor = [
    sphere.gxx(x, y, z, model),
    sphere.gxy(x, y, z, model),
    sphere.gxz(x, y, z, model),
    sphere.gyy(x, y, z, model),
    sphere.gyz(x, y, z, model),
    sphere.gzz(x, y, z, model)
]
mpl.figure()
mpl.axis('scaled')
mpl.title('gz')
mpl.contourf(y, x, gz, shape, 15)
mpl.colorbar()
mpl.m2km()
mpl.figure()
titles = ['gxx', 'gxy', 'gxz', 'gyy', 'gyz', 'gzz']
for i, field in enumerate(tensor):
    mpl.subplot(2, 3, i + 1)
# Create a model using geometric objects from fatiando.mesher
# Each model element has a dictionary with its physical properties.
# We'll use two spheres with opposite density contrast values.
model = [mesher.Sphere(x=10e3, y=10e3, z=1.5e3, radius=1.5e3,
                       props={'density': 500}),
         mesher.Sphere(x=20e3, y=20e3, z=1.5e3, radius=1.5e3,
                       props={'density': -500})]

# Create a regular grid at a constant height
shape = (300, 300)
area = [0, 30e3, 0, 30e3]
x, y, z = gridder.regular(area, shape, z=-100)

fields = [
    ['Gravity (mGal)', sphere.gz(x, y, z, model)],
    ['gxx (Eotvos)', sphere.gxx(x, y, z, model)],
    ['gyy (Eotvos)', sphere.gyy(x, y, z, model)],
    ['gzz (Eotvos)', sphere.gzz(x, y, z, model)],
    ['gxy (Eotvos)', sphere.gxy(x, y, z, model)],
    ['gxz (Eotvos)', sphere.gxz(x, y, z, model)],
    ['gyz (Eotvos)', sphere.gyz(x, y, z, model)],
]

# Make maps of all fields calculated
fig = plt.figure(figsize=(10, 8))
plt.rcParams['font.size'] = 10
X, Y = x.reshape(shape)/1000, y.reshape(shape)/1000
for i, tmp in enumerate(fields):
    ax = plt.subplot(3, 3, i + 3)
    field, data = tmp
Example #12
0
# and the inversion
# Apply a scaling factor to make both portions of the misfit the same order of
# magnitude
scale = np.linalg.norm(gz) ** 2 / np.linalg.norm(gzz) ** 2
misfit = (EQLGravity(x1, y1, z1, gz, layer)
          + scale * EQLGravity(x2, y2, z2, gzz, layer, field='gzz'))
regul = Smoothness2D(layer.shape)
# Use an L-curve analysis to find the best regularization parameter
solver = LCurve(misfit, regul, [10 ** i for i in range(-30, -20)]).fit()
layer.addprop('density', solver.estimate_)

# Now I can forward model gz using my layer to produce an integrated map in a
# much denser region
shape = (50, 50)
x, y, z = gridder.regular(area, shape, z=0)
gz_layer = sphere.gz(x, y, z, layer)
gz_true = prism.gz(x, y, z, model)

mpl.figure()
mpl.suptitle('L-curve')
mpl.title("Estimated regularization parameter: %g" % (solver.regul_param_))
solver.plot_lcurve()
mpl.grid()

# Plot the layer and the fit
mpl.figure(figsize=(14, 4))
mpl.suptitle('Observed data (black) | Predicted by layer (red)')
mpl.subplot(1, 3, 1)
mpl.axis('scaled')
mpl.title('Layer (kg.m^-3)')
mpl.pcolor(layer.y, layer.x, layer.props['density'], layer.shape)
Example #13
0
 def sensitivity(self, grid):
     x, y, z = self.x, self.y, self.z
     sens = numpy.empty((self.size, len(grid)), dtype=float)
     for i, s in enumerate(grid):
         sens[:,i] = kernel.gz(x, y, z, [s], dens=1.)
     return sens
Example #14
0
mpl.subplot(2, 1, 1)
mpl.axis('scaled')
mpl.title('Density (mass)')
mpl.pcolor(grid.y, grid.x, grid.props['density'], grid.shape)
mpl.colorbar()
mpl.subplot(2, 1, 2)
mpl.axis('scaled')
mpl.title('Magnetization intensity (dipole moment)')
mpl.pcolor(grid.y, grid.x, utils.vecnorm(grid.props['magnetization']),
           grid.shape)
mpl.colorbar()
mpl.show()

# Now do some calculations with the grid
shape = (100, 100)
x, y, z = gridder.regular(grid.area, shape, z=0)
gz = sphere.gz(x, y, z, grid)
tf = sphere.tf(x, y, z, grid, inc, dec)
mpl.figure()
mpl.subplot(2, 1, 1)
mpl.axis('scaled')
mpl.title('Gravity anomaly')
mpl.contourf(y, x, gz, shape, 30)
mpl.colorbar()
mpl.subplot(2, 1, 2)
mpl.axis('scaled')
mpl.title('Magnetic total field anomaly')
mpl.contourf(y, x, tf, shape, 30)
mpl.colorbar()
mpl.show()
                  radius=1.5e3,
                  props={'density': 500}),
    mesher.Sphere(x=20e3,
                  y=20e3,
                  z=1.5e3,
                  radius=1.5e3,
                  props={'density': -500})
]

# Create a regular grid at a constant height
shape = (300, 300)
area = [0, 30e3, 0, 30e3]
x, y, z = gridder.regular(area, shape, z=-100)

fields = [
    ['Gravity (mGal)', sphere.gz(x, y, z, model)],
    ['gxx (Eotvos)', sphere.gxx(x, y, z, model)],
    ['gyy (Eotvos)', sphere.gyy(x, y, z, model)],
    ['gzz (Eotvos)', sphere.gzz(x, y, z, model)],
    ['gxy (Eotvos)', sphere.gxy(x, y, z, model)],
    ['gxz (Eotvos)', sphere.gxz(x, y, z, model)],
    ['gyz (Eotvos)', sphere.gyz(x, y, z, model)],
]

# Make maps of all fields calculated
fig = plt.figure(figsize=(10, 8))
plt.rcParams['font.size'] = 10
X, Y = x.reshape(shape) / 1000, y.reshape(shape) / 1000
for i, tmp in enumerate(fields):
    ax = plt.subplot(3, 3, i + 3)
    field, data = tmp
mpl.axis('scaled')
mpl.title('Density (mass)')
mpl.pcolor(grid.y, grid.x, grid.props['density'], grid.shape)
mpl.colorbar()
mpl.subplot(2, 1, 2)
mpl.axis('scaled')
mpl.title('Magnetization intensity (dipole moment)')
mpl.pcolor(grid.y, grid.x, utils.vecnorm(grid.props['magnetization']),
    grid.shape)
mpl.colorbar()
mpl.show()

# Now do some calculations with the grid
shape = (100, 100)
x, y, z = gridder.regular(grid.area, shape, z=0)
gz = sphere.gz(x, y, z, grid)
tf = sphere.tf(x, y, z, grid, inc, dec)
mpl.figure()
mpl.subplot(2, 1, 1)
mpl.axis('scaled')
mpl.title('Gravity anomaly')
mpl.contourf(y, x, gz, shape, 30)
mpl.colorbar()
mpl.subplot(2, 1, 2)
mpl.axis('scaled')
mpl.title('Magnetic total field anomaly')
mpl.contourf(y, x, tf, shape, 30)
mpl.colorbar()
mpl.show()

# Apply a smoothness constraint to the borders of the equivalent layer windows
# to avoid gaps in the physical property distribution
solver = misfit + 1e-18 * PELSmoothness(layer, windows, degree)
solver.fit()
# Add the estimated density distribution to the layer object for plotting and
# forward modeling
layer.addprop('density', solver.estimate_)
residuals = solver[0].residuals()
print("Residuals:")
print("mean:", residuals.mean())
print("stddev:", residuals.std())

# Now I can forward model the layer at a greater height and check against the
# true solution of the prism
gz_true = prism.gz(x, y, z - 500, model)
gz_up = sphere.gz(x, y, z - 500, layer)

mpl.figure(figsize=(14, 4))
mpl.subplot(1, 3, 1)
mpl.axis('scaled')
mpl.title('Layer (kg.m^-3)')
mpl.pcolor(layer.y, layer.x, layer.props['density'], layer.shape)
mpl.colorbar()
mpl.m2km()
mpl.subplot(1, 3, 2)
mpl.axis('scaled')
mpl.title('Fit (mGal)')
levels = mpl.contour(y, x, gz, shape, 15, color='r')
mpl.contour(y, x, solver[0].predicted(), shape, levels, color='k')
mpl.m2km()
mpl.subplot(1, 3, 3)
Example #18
0
"""
GravMag: Forward modeling of the gravity anomaly and gravity gradient tensor
using model
"""
from fatiando import mesher, gridder
from fatiando.gravmag import sphere
from fatiando.vis import mpl

model = [mesher.Sphere(0, 0, 2000, 1000, {'density': 1000})]
area = (-5000, 5000, -5000, 5000)
shape = (100, 100)
x, y, z = gridder.regular(area, shape, z=-100)
gz = sphere.gz(x, y, z, model)
tensor = [sphere.gxx(x, y, z, model),
          sphere.gxy(x, y, z, model),
          sphere.gxz(x, y, z, model),
          sphere.gyy(x, y, z, model),
          sphere.gyz(x, y, z, model),
          sphere.gzz(x, y, z, model)]
mpl.figure()
mpl.axis('scaled')
mpl.title('gz')
mpl.contourf(y, x, gz, shape, 15)
mpl.colorbar()
mpl.m2km()
mpl.figure()
titles = ['gxx', 'gxy', 'gxz', 'gyy', 'gyz', 'gzz']
for i, field in enumerate(tensor):
    mpl.subplot(2, 3, i + 1)
    mpl.axis('scaled')
    mpl.title(titles[i])
Example #19
0
# Estimate the density using enough damping so that won't try to fit the error
eql = EQLGravity(x, y, z, gz, layer) + 1e-22*Damping(layer.size)
eql.fit()
# Now we add the estimated densities to our layer
layer.addprop('density', eql.estimate_)
# and print some statistics of how well the estimated layer fits the data
residuals = eql[0].residuals()
print("Residuals:")
print("  mean:", residuals.mean(), 'mGal')
print("  stddev:", residuals.std(), 'mGal')

# Now I can forward model gravity data anywhere we want. For interpolation, we
# calculate it on a grid. For upward continuation, at a greater height. We can
# even combine both into a single operation.
x2, y2, z2 = gridder.regular(area, (50, 50), z=-1000)
gz_up = sphere.gz(x2, y2, z2, layer)


fig, axes = plt.subplots(1, 2, figsize=(8, 6))

ax = axes[0]
ax.set_title('Original data')
ax.set_aspect('equal')
tmp = ax.tricontourf(y/1000, x/1000, gz, 30, cmap='viridis')
fig.colorbar(tmp, ax=ax, pad=0.1, aspect=30,
             orientation='horizontal').set_label('mGal')
ax.plot(y/1000, x/1000, 'xk')
ax.set_xlabel('y (km)')
ax.set_ylabel('x (km)')

ax = axes[1]
Example #20
0
def test_gz():
    "gravmag.sphere.gz python vs cython implementation"
    py = _sphere_numpy.gz(xp, yp, zp, model)
    cy = sphere.gz(xp, yp, zp, model)
    diff = np.abs(py - cy)
    assert np.all(diff <= precision), 'max diff: %g' % (max(diff))