Ejemplo n.º 1
0
def fwd_grav_fatiando():
    """
    GravMag: 3D imaging using the migration method on synthetic gravity data
    (more complex model + noisy data)
    """

    # Make some synthetic gravity data from a simple prism model
    za = 5000
    zb = 7000
    model = [mesher.Prism(-4000, 0, -4000, -2000, za, zb,
                          {'density': 1200})]  #,
    #         mesher.Prism(-1000, 1000, -1000, 1000, 1000, 7000, {'density': -800}),
    #         mesher.Prism(2000, 4000, 3000, 4000, 0, 2000, {'density': 600})]
    # Calculate on a scatter of points to show that migration doesn't need gridded
    # data
    # xp, yp, zp = gridder.scatter((-6000, 6000, -6000, 6000), 1000, z=0)
    shape = (25, 25)
    xp, yp, zp = gridder.regular((-5000, 5000, -5000, 5000), shape, z=0)

    #gz = utils.contaminate(prism.gz(xp, yp, zp, model), 0.1)
    gz = prism.gz(xp, yp, zp, model)

    # Plot the data
    shape = (50, 50)
    mpl.figure()
    mpl.axis('scaled')
    mpl.contourf(yp, xp, gz, shape, 30, interp=True)
    mpl.colorbar()
    mpl.plot(yp, xp, '.k')
    mpl.xlabel('East (km)')
    mpl.ylabel('North (km)')
    mpl.m2km()
    mpl.show()

    return xp, yp, zp, gz, shape, model
def test_gz_prism():
    '''
    This test compare the results obtained by both function that calculates the vertical gravitational attraction due to a rectangular prism. 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 = 2600.

    # Modelo para o Fatiando
    xp, yp, zp = gridder.regular((-1000, 1000, -1000, 1000), (200, 200),
                                 z=-345.)
    model = [
        mesher.Prism(-200., 200., -250., 180., 120., 1000.,
                     {'density': density})
    ]
    gz = prism.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 = [-200., 200., -250., 180., 120., 1000., density]
    mygz = prism_gz(y, x, z, mymodel)

    assert_almost_equal(gz, mygz, decimal=5)
def test_gz():
    "polyprism.gz against prism"
    resprism = prism.gz(xp, yp, zp, prismmodel)
    respoly = polyprism.gz(xp, yp, zp, model)
    diff = np.abs(resprism - respoly)
    errormsg = 'max diff: %g | max polyprism: %g | max prism: %g' % (
        max(diff), max(respoly), max(resprism))
    assert np.all(diff <= precision), errormsg
Ejemplo n.º 4
0
def test_gz():
    "polyprism.gz against prism"
    resprism = prism.gz(xp, yp, zp, prismmodel)
    respoly = polyprism.gz(xp, yp, zp, model)
    diff = np.abs(resprism - respoly)
    errormsg = 'max diff: %g | max polyprism: %g | max prism: %g' % (
        max(diff), max(respoly), max(resprism))
    assert np.all(diff <= precision), errormsg
Ejemplo n.º 5
0
def migrate(x, y, z, gz, zmin, zmax, meshshape, power=0.5, scale=1):
    """
    3D potential field migration (Zhdanov et al., 2011).

    Actually uses the formula of Fedi and Pilkington (2012), which are
    comprehensible.

    .. note:: Only works on **gravity** data for now.

    .. note:: The data **do not** need to be leveled or on a regular grid.

    .. note:: The coordinate system adopted is x->North, y->East, and z->Down

    Parameters:

    * x, y : 1D-arrays
        The x and y coordinates of the grid points
    * z : float or 1D-array
        The z coordinate of the grid points
    * gz : 1D-array
        The gravity anomaly data at the grid points
    * zmin, zmax : float
        The top and bottom, respectively, of the region where the physical
        property distribution is calculated
    * meshshape : tuple = (nz, ny, nx)
        Number of prisms in the output mesh in the x, y, and z directions,
        respectively
    * power : float
        The power law used for the depth weighting. This controls what depth
        the bulk of the solution will be.
    * scale : float
        A scale factor for the depth weights. Simply changes the scale of the
        physical property values.

    Returns:

    * mesh : :class:`fatiando.mesher.PrismMesh`
        The estimated physical property distribution set in a prism mesh (for
        easy 3D plotting)

    """
    nlayers, ny, nx = meshshape
    mesh = _makemesh(x, y, (ny, nx), zmin, zmax, nlayers)
    # This way, if z is not an array, it is now
    z = z * numpy.ones_like(x)
    dx, dy, dz = mesh.dims
    # Synthetic tests show that its not good to offset the weights with the
    # data z coordinate. No idea why
    depths = mesh.get_zs()[:-1] + 0.5 * dz
    weights = numpy.abs(depths)**power / (2 * G * numpy.sqrt(numpy.pi))
    density = []
    for l in xrange(nlayers):
        sensibility_T = numpy.array(
            [pot_prism.gz(x, y, z, [p], dens=1) for p in mesh.get_layer(l)])
        density.extend(scale * weights[l] * numpy.dot(sensibility_T, gz))
    mesh.addprop('density', numpy.array(density))
    return mesh
def migrate(x, y, z, gz, zmin, zmax, meshshape, power=0.5, scale=1):
    """
    3D potential field migration (Zhdanov et al., 2011).

    Actually uses the formula of Fedi and Pilkington (2012), which are
    comprehensible.

    .. note:: Only works on **gravity** data for now.

    .. note:: The data **do not** need to be leveled or on a regular grid.

    .. note:: The coordinate system adopted is x->North, y->East, and z->Down

    Parameters:

    * x, y : 1D-arrays
        The x and y coordinates of the grid points
    * z : float or 1D-array
        The z coordinate of the grid points
    * gz : 1D-array
        The gravity anomaly data at the grid points
    * zmin, zmax : float
        The top and bottom, respectively, of the region where the physical
        property distribution is calculated
    * meshshape : tuple = (nz, ny, nx)
        Number of prisms in the output mesh in the x, y, and z directions,
        respectively
    * power : float
        The power law used for the depth weighting. This controls what depth
        the bulk of the solution will be.
    * scale : float
        A scale factor for the depth weights. Simply changes the scale of the
        physical property values.

    Returns:

    * mesh : :class:`fatiando.mesher.PrismMesh`
        The estimated physical property distribution set in a prism mesh (for
        easy 3D plotting)

    """
    nlayers, ny, nx = meshshape
    mesh = _makemesh(x, y, (ny, nx), zmin, zmax, nlayers)
    # This way, if z is not an array, it is now
    z = z*numpy.ones_like(x)
    dx, dy, dz = mesh.dims
    # Synthetic tests show that its not good to offset the weights with the data
    # z coordinate. No idea why
    depths = mesh.get_zs()[:-1] + 0.5*dz
    weights = numpy.abs(depths)**power/(2*G*numpy.sqrt(numpy.pi))
    density = []
    for l in xrange(nlayers):
        sensibility_T = numpy.array(
            [pot_prism.gz(x, y, z, [p], dens=1) for p in mesh.get_layer(l)])
        density.extend(scale*weights[l]*numpy.dot(sensibility_T, gz))
    mesh.addprop('density', numpy.array(density))
    return mesh
Ejemplo n.º 7
0
def test_upcontinue_warning():
    "gravmag.transform upward continuation raises warning if height <= 0"
    model = [Prism(-1000, 1000, -500, 500, 0, 1000, {'density': 1000})]
    shape = (100, 100)
    x, y, z = gridder.regular([-5000, 5000, -5000, 5000], shape, z=-500)
    data = prism.gz(x, y, z, model)
    with pytest.warns(UserWarning):
        up = transform.upcontinue(x, y, data, shape, height=0)
    with pytest.warns(UserWarning):
        up = transform.upcontinue(x, y, data, shape, height=-100)
Ejemplo n.º 8
0
def test_upcontinue_warning():
    "gravmag.transform upward continuation raises warning if height <= 0"
    model = [Prism(-1000, 1000, -500, 500, 0, 1000, {'density': 1000})]
    shape = (100, 100)
    x, y, z = gridder.regular([-5000, 5000, -5000, 5000], shape, z=-500)
    data = prism.gz(x, y, z, model)
    with pytest.warns(UserWarning):
        up = transform.upcontinue(x, y, data, shape, height=0)
    with pytest.warns(UserWarning):
        up = transform.upcontinue(x, y, data, shape, height=-100)
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
def test_derivatives_uneven_shape():
    "gravmag.transform FFT derivatives work if grid spacing is uneven"
    model = [Prism(-1000, 1000, -500, 500, 0, 2000, {'density': 100})]
    shape = (150, 300)
    x, y, z = gridder.regular([-10000, 10000, -10000, 10000], shape, z=-100)
    grav = utils.mgal2si(prism.gz(x, y, z, model))
    analytical = prism.gzz(x, y, z, model)
    calculated = utils.si2eotvos(transform.derivz(x, y, grav, shape,
                                                  method='fft'))
    diff = _trim(np.abs(analytical - calculated), shape)
    assert np.all(diff <= 0.005*np.abs(analytical).max()), \
        "Failed for gzz"
Ejemplo n.º 11
0
def test_tilt_analytical_derivatives():
    "gravmag.transform tilt returns same values given analytical derivatives"
    model = [Prism(-100, 100, -100, 100, 0, 100, {'density': 1000})]
    shape = (400, 400)
    x, y, z = gridder.regular([-10000, 10000, -10000, 10000], shape, z=-100)
    data = utils.mgal2si(prism.gz(x, y, z, model))
    dx = utils.eotvos2si(prism.gxz(x, y, z, model))
    dy = utils.eotvos2si(prism.gyz(x, y, z, model))
    dz = utils.eotvos2si(prism.gzz(x, y, z, model))
    tilt_analytical = transform.tilt(x, y, data, shape, dx, dy, dz)
    tilt_numerical = transform.tilt(x, y, data, shape)
    npt.assert_allclose(tilt_numerical, tilt_analytical, rtol=0.10)
Ejemplo n.º 12
0
def test_derivatives_uneven_shape():
    "gravmag.transform FFT derivatives work if grid spacing is uneven"
    model = [Prism(-1000, 1000, -500, 500, 0, 2000, {'density': 100})]
    shape = (150, 300)
    x, y, z = gridder.regular([-10000, 10000, -10000, 10000], shape, z=-100)
    grav = utils.mgal2si(prism.gz(x, y, z, model))
    analytical = prism.gzz(x, y, z, model)
    calculated = utils.si2eotvos(
        transform.derivz(x, y, grav, shape, method='fft'))
    diff = _trim(np.abs(analytical - calculated), shape)
    assert np.all(diff <= 0.005*np.abs(analytical).max()), \
        "Failed for gzz"
Ejemplo n.º 13
0
def test_tilt_analytical_derivatives():
    "gravmag.transform tilt returns same values given analytical derivatives"
    model = [Prism(-100, 100, -100, 100, 0, 100, {'density': 1000})]
    shape = (400, 400)
    x, y, z = gridder.regular([-10000, 10000, -10000, 10000], shape, z=-100)
    data = utils.mgal2si(prism.gz(x, y, z, model))
    dx = utils.eotvos2si(prism.gxz(x, y, z, model))
    dy = utils.eotvos2si(prism.gyz(x, y, z, model))
    dz = utils.eotvos2si(prism.gzz(x, y, z, model))
    tilt_analytical = transform.tilt(x, y, data, shape, dx, dy, dz)
    tilt_numerical = transform.tilt(x, y, data, shape)
    npt.assert_allclose(tilt_numerical, tilt_analytical, rtol=0.10)
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
def test_horizontal_derivatives_fd():
    "gravmag.transform 1st xy derivatives by finite diff against analytical"
    model = [Prism(-1000, 1000, -500, 500, 0, 2000, {'density': 100})]
    shape = (300, 300)
    x, y, z = gridder.regular([-5000, 5000, -5000, 5000], shape, z=-200)
    derivatives = 'x y'.split()
    grav = utils.mgal2si(prism.gz(x, y, z, model))
    for deriv in derivatives:
        analytical = getattr(prism, 'g{}z'.format(deriv))(x, y, z, model)
        func = getattr(transform, 'deriv' + deriv)
        calculated = utils.si2eotvos(func(x, y, grav, shape, method='fd'))
        diff = np.abs(analytical - calculated)
        assert np.all(diff <= 0.005*np.abs(analytical).max()), \
            "Failed for g{}. Max: {} Mean: {} STD: {}".format(
                deriv, diff.max(), diff.mean(), diff.std())
Ejemplo n.º 16
0
def test_gz_derivatives():
    "gravmag.transform FFT 1st derivatives of gz against analytical solutions"
    model = [Prism(-1000, 1000, -500, 500, 0, 2000, {'density': 100})]
    shape = (300, 300)
    x, y, z = gridder.regular([-10000, 10000, -10000, 10000], shape, z=-100)
    derivatives = 'x y z'.split()
    grav = utils.mgal2si(prism.gz(x, y, z, model))
    for deriv in derivatives:
        analytical = getattr(prism, 'g{}z'.format(deriv))(x, y, z, model)
        calculated = utils.si2eotvos(
            getattr(transform, 'deriv' + deriv)(x, y, grav, shape,
                                                method='fft'))
        diff = _trim(np.abs(analytical - calculated), shape)
        assert np.all(diff <= 0.005*np.abs(analytical).max()), \
            "Failed for g{}z".format(deriv)
Ejemplo n.º 17
0
def test_horizontal_derivatives_fd():
    "gravmag.transform 1st xy derivatives by finite diff against analytical"
    model = [Prism(-1000, 1000, -500, 500, 0, 2000, {'density': 100})]
    shape = (300, 300)
    x, y, z = gridder.regular([-5000, 5000, -5000, 5000], shape, z=-200)
    derivatives = 'x y'.split()
    grav = utils.mgal2si(prism.gz(x, y, z, model))
    for deriv in derivatives:
        analytical = getattr(prism, 'g{}z'.format(deriv))(x, y, z, model)
        func = getattr(transform, 'deriv' + deriv)
        calculated = utils.si2eotvos(func(x, y, grav, shape, method='fd'))
        diff = np.abs(analytical - calculated)
        assert np.all(diff <= 0.005*np.abs(analytical).max()), \
            "Failed for g{}. Max: {} Mean: {} STD: {}".format(
                deriv, diff.max(), diff.mean(), diff.std())
Ejemplo n.º 18
0
def anomaly_calculation(x, y, w, t, rho):
    from fatiando import utils
    from fatiando.mesher import Prism
    from fatiando.gravmag import prism

    ny, nx = np.shape(x)
    prismas = []
    for i in xrange(ny-1):
        for j in xrange(nx-1):
            prisma = Prism(y[i][j], y[i+1][j+1], x[i][j], x[i+1][j+1], t,
                        t + (w[i][j] + w[i+1][j] + w[i][j+1] + w[i+1][j+1])/4.)
            prismas.append(prisma)
    
    gz = -prism.gz(y.ravel(),x.ravel(),np.zeros(nx*ny),prismas,dens=rho)
    gz = utils.mgal2si(np.reshape(gz,(ny,nx)))
    return gz
Ejemplo n.º 19
0
def test_harvest_restrict():
    def fill(i, case):
        # Returns density of 10 for center prism and prism given by 'case'
        cdir = {'above': 4, 'below': 22, 'north': 14, 'south': 12, 'east': 16,
                'west': 10}
        if i == 13:
            return 10
        for key in cdir:
            if case == key and i == cdir.get(key):
                return 10
        return 0
    # The test cases as string list
    cases = ['above', 'below', 'north', 'south', 'east', 'west']
    # Create reference model
    bounds = (0, 3, 0, 3, 0, 3)
    shape = (3, 3, 3)
    shapegz = (10, 10)
    for testcase in cases:
        mref = PrismMesh(bounds, shape)
        mesh = mref.copy()
        mref.addprop('density', [fill(i, testcase) for i in xrange(mref.size)])
        # Calculate reference gravity field
        xp, yp, zp = gridder.regular(bounds[:4], shapegz, z=-1)
        gzref = prism.gz(xp, yp, zp, mref)
        # Initiate harvest
        hgref = [harvester.Gz(xp, yp, zp, gzref)]
        loc = [[1.5, 1.5, 1.5, {'density': 10}]]
        seeds = harvester.sow(loc, mesh)
        # est0 should be incorrect and thus fail wilst est1 should yield the
        # same geometry as mref
        est0, pred0 = harvester.harvest(hgref, seeds, mesh, compactness=0.1,
                                        threshold=0.001, restrict=[testcase])
        est1, pred1 = harvester.harvest(hgref, seeds, mesh, compactness=0.1,
                                        threshold=0.001)
        res0 = mesh.copy()
        res0.addprop('density', est0['density'])
        res1 = mesh.copy()
        res1.addprop('density', est1['density'])
        l0 = []
        l1 = []
        for i, p in enumerate(res0):
            l0.append(p.props['density'] == mref[i].props['density'])
        for i, p in enumerate(res1):
            l1.append(p.props['density'] == mref[i].props['density'])
        assert not np.all(l0)
        assert np.all(l1)
Ejemplo n.º 20
0
def test_gz_derivatives():
    "gravmag.transform FFT 1st derivatives of gz against analytical solutions"
    model = [Prism(-1000, 1000, -500, 500, 0, 2000, {'density': 100})]
    shape = (300, 300)
    x, y, z = gridder.regular([-10000, 10000, -10000, 10000], shape, z=-100)
    derivatives = 'x y z'.split()
    grav = utils.mgal2si(prism.gz(x, y, z, model))
    for deriv in derivatives:
        analytical = getattr(prism, 'g{}z'.format(deriv))(x, y, z, model)
        calculated = utils.si2eotvos(
            getattr(transform, 'deriv' + deriv)(x,
                                                y,
                                                grav,
                                                shape,
                                                method='fft'))
        diff = _trim(np.abs(analytical - calculated), shape)
        assert np.all(diff <= 0.005*np.abs(analytical).max()), \
            "Failed for g{}z".format(deriv)
Ejemplo n.º 21
0
Here we'll show how the Generalized Inverse imaging method can be used on some
synthetic data. We'll plot the final result as slices across the x, y, z axis.
"""
from __future__ import division
from fatiando import gridder, mesher
from fatiando.gravmag import prism, imaging
from fatiando.vis.mpl import square
import matplotlib.pyplot as plt
import numpy as np

# Make some synthetic gravity data from a simple prism model
model = [mesher.Prism(-1000, 1000, -3000, 3000, 0, 2000, {'density': 800})]
shape = (25, 25)
xp, yp, zp = gridder.regular((-5000, 5000, -5000, 5000), shape, z=-10)
data = prism.gz(xp, yp, zp, model)

# Run the Generalized Inverse
mesh = imaging.geninv(xp, yp, zp, data, shape, zmin=0, zmax=5000, nlayers=25)

# Plot the results
fig = plt.figure()

X, Y = xp.reshape(shape)/1000, yp.reshape(shape)/1000
image = mesh.props['density'].reshape(mesh.shape)

# First plot the original gravity data
ax = plt.subplot(2, 2, 1)
ax.set_title('Gravity data (mGal)')
ax.set_aspect('equal')
scale = np.abs([data.min(), data.max()]).max()
Ejemplo n.º 22
0
from fatiando.vis import myv, mpl

area = (-150, 150, -300, 300)
shape = (30, 15)
x, y = gridder.regular(area, shape)
height = (-80 * utils.gaussian2d(x, y, 100, 200, x0=-50, y0=-100, angle=-60) +
          200 * utils.gaussian2d(x, y, 50, 100, x0=80, y0=170))

nodes = (x, y, -1 * height)
relief = mesher.PrismRelief(0, gridder.spacing(area, shape), nodes)
relief.addprop('density', (2670 for i in xrange(relief.size)))

gridarea = (-80, 80, -220, 220)
gridshape = (100, 100)
xp, yp, zp = gridder.regular(gridarea, gridshape, z=-200)
gz = prism.gz(xp, yp, zp, relief)

mpl.figure(figsize=(10, 7))
mpl.subplot(1, 2, 1)
mpl.title("Synthetic topography")
mpl.axis('scaled')
mpl.pcolor(x, y, height, shape)
cb = mpl.colorbar()
cb.set_label("meters")
mpl.square(gridarea, label='Computation grid')
mpl.legend()
mpl.subplot(1, 2, 2)
mpl.title("Topographic effect")
mpl.axis('scaled')
mpl.pcolor(xp, yp, gz, gridshape)
cb = mpl.colorbar()
Ejemplo n.º 23
0
Here we'll show how the Generalized Inverse imaging method can be used on some
synthetic data. We'll plot the final result as slices across the x, y, z axis.
"""
from __future__ import division
from fatiando import gridder, mesher
from fatiando.gravmag import prism, imaging
from fatiando.vis.mpl import square
import matplotlib.pyplot as plt
import numpy as np

# Make some synthetic gravity data from a simple prism model
model = [mesher.Prism(-1000, 1000, -3000, 3000, 0, 2000, {'density': 800})]
shape = (25, 25)
xp, yp, zp = gridder.regular((-5000, 5000, -5000, 5000), shape, z=-10)
data = prism.gz(xp, yp, zp, model)

# Run the Generalized Inverse
mesh = imaging.geninv(xp, yp, zp, data, shape, zmin=0, zmax=5000, nlayers=25)

# Plot the results
fig = plt.figure()

X, Y = xp.reshape(shape) / 1000, yp.reshape(shape) / 1000
image = mesh.props['density'].reshape(mesh.shape)

# First plot the original gravity data
ax = plt.subplot(2, 2, 1)
ax.set_title('Gravity data (mGal)')
ax.set_aspect('equal')
scale = np.abs([data.min(), data.max()]).max()
Ejemplo n.º 24
0
GravMag: Upward continuation of noisy gz data
"""
from fatiando import mesher, gridder, utils
from fatiando.gravmag import prism, transform
from fatiando.vis import mpl
import numpy as np

model = [
    mesher.Prism(-3000, -2000, -3000, -2000, 500, 2000, {'density': 1000}),
    mesher.Prism(-1000, 1000, -1000, 1000, 0, 2000, {'density': -800}),
    mesher.Prism(1000, 3000, 2000, 3000, 0, 1000, {'density': 900})]
area = (-5000, 5000, -5000, 5000)
shape = (50, 50)
z0 = -100
x, y, z = gridder.regular(area, shape, z=z0)
gz = utils.contaminate(prism.gz(x, y, z, model), 0.5, seed=0)

height = 1000  # How much higher to go
gzcontf = transform.upcontinue(x, y, gz, shape, height)

# Compute the true value at the new height for comparison
gztrue = prism.gz(x, y, z - height, model)

args = dict(shape=shape, levels=20, cmap=mpl.cm.RdBu_r)
fig, axes = mpl.subplots(1, 3, figsize=(12, 3.5))
axes = axes.ravel()
mpl.sca(axes[0])
mpl.title("Original")
mpl.axis('scaled')
mpl.contourf(x, y, gz, **args)
mpl.colorbar(pad=0).set_label('mGal')
"""
GravMag: Use an equivalent layer to upward continue gravity data
"""
from fatiando.gravmag import prism, sphere
from fatiando.gravmag.eqlayer import EQLGravity
from fatiando.inversion.regularization import Damping, LCurve
from fatiando import gridder, utils, mesher
from fatiando.vis import mpl

# Make synthetic data
props = {'density':1000}
model = [mesher.Prism(-500, 500, -1000, 1000, 500, 4000, props)]
shape = (25, 25)
x, y, z = gridder.regular([-5000, 5000, -5000, 5000], shape, z=0)
gz = utils.contaminate(prism.gz(x, y, z, model), 0.1, seed=0)
# Setup the layer
layer = mesher.PointGrid([-6000, 6000, -6000, 6000], 1000, (50, 50))
# 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
Ejemplo n.º 26
0
simname = 'za' + str(za) + '_zb' + str(zb) + '_l' + str(l) + '_ofs' + str(
    offset) + '_dens' + str(dens)

# model = [mesher.Prism(-l-offset, l-offset, -l-offset/20, l-offset, za, zb, {'density': dens})]
# simname= 'mod_asy_rect_z3.2km_rectArea'
simname = 'sym_square_z3.2km_rectArea'

# model = [mesher.Prism(-4000, 0, -4000, -3500, za, zb, {'density': 1200})]
model = [mesher.Prism(-1000, 1000, -1000, 1000, za, zb, {'density': 1200})]

shape = (200, 200)
#xp, yp, zp = gridder.scatter((-6000, 6000, -6000, 6000), shape[0]*shape[1], z=0)
xp, yp, zp = gridder.regular((-12000, 12000, -6000, 6000), shape, z=0)

# gz = utils.contaminate(prism.gz(xp, yp, zp, model), 0.1)
gz = prism.gz(xp, yp, zp, model)

x1, x2, y1, y2, z1, z2 = np.array(model[0].get_bounds())

import pickle
d = {"xyzg": [xp, yp, zp, gz], "shape": shape, "model": model, "density": dens}
afile = open(simname + '.pkl', 'wb')
pickle.dump(d, afile)
afile.close()

# import pickle

#reload object from file

# file2 = open(simname + '.pkl', 'rb')
# u = pickle._Unpickler(file2)
Ejemplo n.º 27
0
"""
from fatiando import mesher, gridder, utils
from fatiando.gravmag import prism, transform
from fatiando.vis import mpl
import numpy as np

model = [
    mesher.Prism(-3000, -2000, -3000, -2000, 500, 2000, {'density': 1000}),
    mesher.Prism(-1000, 1000, -1000, 1000, 0, 2000, {'density': -800}),
    mesher.Prism(1000, 3000, 2000, 3000, 0, 1000, {'density': 900})
]
area = (-5000, 5000, -5000, 5000)
shape = (50, 50)
z0 = -100
x, y, z = gridder.regular(area, shape, z=z0)
gz = utils.contaminate(prism.gz(x, y, z, model), 0.5, seed=0)

height = 1000  # How much higher to go
gzcontf = transform.upcontinue(x, y, gz, shape, height)

# Compute the true value at the new height for comparison
gztrue = prism.gz(x, y, z - height, model)

args = dict(shape=shape, levels=20, cmap=mpl.cm.RdBu_r)
fig, axes = mpl.subplots(1, 3, figsize=(12, 3.5))
axes = axes.ravel()
mpl.sca(axes[0])
mpl.title("Original")
mpl.axis('scaled')
mpl.contourf(x, y, gz, **args)
mpl.colorbar(pad=0).set_label('mGal')
Ejemplo n.º 28
0
import matplotlib.pyplot as plt
from fatiando.gravmag import prism, sphere
from fatiando.gravmag.eqlayer import EQLGravity
from fatiando.inversion import Damping
from fatiando import gridder, utils, mesher

# First thing to do is make some synthetic data to test the method. We'll use a
# single prism to keep it simple
props = {'density': 500}
model = [mesher.Prism(-5000, 5000, -200, 200, 100, 4000, props)]

# The synthetic data will be generated on a random scatter of points
area = [-8000, 8000, -5000, 5000]
x, y, z = gridder.scatter(area, 300, z=0, seed=42)
# Generate some noisy data from our model
gz = utils.contaminate(prism.gz(x, y, z, model), 0.2, seed=0)

# Now for the equivalent layer. We must setup a layer of point masses where
# we'll estimate a density distribution that fits our synthetic data
layer = mesher.PointGrid(area, 500, (20, 20))
# 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')
"""
GravMag: Upward continuation of noisy gz data using the analytical formula
"""
from fatiando import mesher, gridder, utils
from fatiando.gravmag import prism, transform
from fatiando.vis import mpl

model = [mesher.Prism(-3000,-2000,-3000,-2000,500,2000,{'density':1000}),
         mesher.Prism(-1000,1000,-1000,1000,0,2000,{'density':-800}),
         mesher.Prism(1000,3000,2000,3000,0,1000,{'density':500})]
area = (-5000, 5000, -5000, 5000)
shape = (50, 50)
z0 = -100
xp, yp, zp = gridder.regular(area, shape, z=z0)
gz = utils.contaminate(prism.gz(xp, yp, zp, model), 0.5)

# Now do the upward continuation using the analytical formula
height = 2000
dims = gridder.spacing(area, shape)
gzcont = transform.upcontinue(gz, height, xp, yp, dims)

gztrue = prism.gz(xp, yp, zp - height, model)

mpl.figure(figsize=(14,6))
mpl.subplot(1, 2, 1)
mpl.title("Original")
mpl.axis('scaled')
mpl.contourf(xp, yp, gz, shape, 15)
mpl.contour(xp, yp, gz, shape, 15)
mpl.subplot(1, 2, 2)
mpl.title("Continued + true")
# Make a model
bounds = [-5000, 5000, -5000, 5000, 0, 5000]
model = [
    Prism(-1500, -500, -1500, -500, 500, 1500, {'density': 1000}),
    Prism(500, 1500, 1000, 2000, 500, 1500, {'density': 1000})
]
# Generate some data from the model
shape = (100, 100)
area = bounds[0:4]
xp, yp, zp = gridder.regular(area, shape, z=-1)
# Add a constant baselevel
baselevel = 10
# Convert the data from mGal to SI because Euler and FFT derivation require
# data in SI
gz = utils.mgal2si(prism.gz(xp, yp, zp, model)) + baselevel
xderiv = transform.derivx(xp, yp, gz, shape)
yderiv = transform.derivy(xp, yp, gz, shape)
zderiv = transform.derivz(xp, yp, gz, shape)

mpl.figure()
titles = ['Gravity anomaly', 'x derivative', 'y derivative', 'z derivative']
for i, f in enumerate([gz, xderiv, yderiv, zderiv]):
    mpl.subplot(2, 2, i + 1)
    mpl.title(titles[i])
    mpl.axis('scaled')
    mpl.contourf(yp, xp, f, shape, 50)
    mpl.colorbar()
    mpl.m2km()
mpl.show()
Ejemplo n.º 31
0
"""
GravMag: Calculating the derivatives of the gravity anomaly using FFT
"""
from fatiando import mesher, gridder, utils
from fatiando.gravmag import prism, transform
from fatiando.vis import mpl

model = [mesher.Prism(-1000, 1000, -1000, 1000, 0, 2000, {'density': 100})]
area = (-5000, 5000, -5000, 5000)
shape = (51, 51)
z0 = -500
xp, yp, zp = gridder.regular(area, shape, z=z0)
gz = utils.contaminate(prism.gz(xp, yp, zp, model), 0.001)

# Need to convert gz to SI units so that the result can be converted to Eotvos
gxz = utils.si2eotvos(transform.derivx(xp, yp, utils.mgal2si(gz), shape))
gyz = utils.si2eotvos(transform.derivy(xp, yp, utils.mgal2si(gz), shape))
gzz = utils.si2eotvos(transform.derivz(xp, yp, utils.mgal2si(gz), shape))

gxz_true = prism.gxz(xp, yp, zp, model)
gyz_true = prism.gyz(xp, yp, zp, model)
gzz_true = prism.gzz(xp, yp, zp, model)

mpl.figure()
mpl.title("Original gravity anomaly")
mpl.axis('scaled')
mpl.contourf(xp, yp, gz, shape, 15)
mpl.colorbar(shrink=0.7)
mpl.m2km()

mpl.figure(figsize=(14, 10))
"""
GravMag: Iterate through a 3D gravity inversion by planting anomalous densities
"""
from fatiando import gridder
from fatiando.gravmag import prism, harvester
from fatiando.mesher import Prism, PrismMesh
from fatiando.vis import myv

model = [Prism(200, 800, 400, 600, 200, 400, {'density': 1000})]
shape = (20, 20)
bounds = [0, 1000, 0, 1000, 0, 1000]
area = bounds[0:4]
x, y, z = gridder.regular(area, shape, z=-1)
gz = prism.gz(x, y, z, model)
mesh = PrismMesh(bounds, (10, 10, 10))
data = [harvester.Gz(x, y, z, gz)]
seeds = harvester.sow([[500, 500, 250, {'density': 1000}]], mesh)

fig = myv.figure(size=(700, 700))
plot = myv.prisms(model, style='wireframe', linewidth=4)
plot.actor.mapper.scalar_visibility = False
myv.prisms(seeds, 'density')
myv.outline(bounds)
myv.wall_bottom(bounds)
myv.wall_east(bounds)
for update in harvester.iharvest(data, seeds, mesh, compactness=0.5,
                                 threshold=0.001):
    best, neighborhood = update[2:4]
    if best is not None:
        myv.prisms([mesh[best.i]])
        plot = myv.prisms(
Ejemplo n.º 33
0
         if case == key and i == cdir.get(key):
             return 10
     return 0
 # The test cases as string list
 cases = ['above', 'below', 'north', 'south', 'east', 'west']
 # Create reference model
 bounds = (0, 3, 0, 3, 0, 3)
 shape = (3, 3, 3)
 shapegz = (10, 10)
 for testcase in cases:
     mref = PrismMesh(bounds, shape)
     mesh = mref.copy()
     mref.addprop('density', [fill(i, testcase) for i in xrange(mref.size)])
     # Calculate reference gravity field
     xp, yp, zp = gridder.regular(bounds[:4], shapegz, z=-1)
     gzref = prism.gz(xp, yp, zp, mref)
     # Initiate harvest
     hgref = [harvester.Gz(xp, yp, zp, gzref)]
     loc = [[1.5, 1.5, 1.5, {'density': 10}]]
     seeds = harvester.sow(loc, mesh)
     # est0 should be incorrect and thus fail wilst est1 should yield the
     # same geometry as mref
     est0, pred0 = harvester.harvest(hgref, seeds, mesh, compactness=0.1,
                                     threshold=0.001, restrict=[testcase])
     est1, pred1 = harvester.harvest(hgref, seeds, mesh, compactness=0.1,
                                     threshold=0.001)
     res0 = mesh.copy()
     res0.addprop('density', est0['density'])
     res1 = mesh.copy()
     res1.addprop('density', est1['density'])
     l0 = []
"""
GravMag: Use the polynomial equivalent layer to upward continue gravity data
"""
from fatiando.gravmag import prism, sphere
from fatiando.gravmag.eqlayer import PELGravity, PELSmoothness
from fatiando import gridder, utils, mesher
from fatiando.vis import mpl

# Make synthetic data
props = {'density': 1000}
model = [mesher.Prism(-500, 500, -1000, 1000, 500, 4000, props)]
shape = (50, 50)
x, y, z = gridder.regular([-5000, 5000, -5000, 5000], shape, z=0)
gz = utils.contaminate(prism.gz(x, y, z, model), 0.1, seed=0)
# Setup the layer
layer = mesher.PointGrid([-5000, 5000, -5000, 5000], 200, (100, 100))
# Estimate the density using the PEL (it is faster and more memory efficient
# than the traditional equivalent layer).
windows = (20, 20)
degree = 1
misfit = PELGravity(x, y, z, gz, layer, windows, degree)
# 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())
Ejemplo n.º 35
0
def test_around():
    "gravmag.prism gravitational results are consistent around the prism"
    funcs = ['potential', 'gx', 'gy', 'gz',
             'gxx', 'gxy', 'gxz', 'gyy', 'gyz', 'gzz']
    model = [Prism(-300, 300, -300, 300, -300, 300, {'density': 1000})]
    # Make the computation points surround the prism
    shape = (101, 101)
    area = [-600, 600, -600, 600]
    distance = 310
    grids = [gridder.regular(area, shape, z=-distance),
             gridder.regular(area, shape, z=distance),
             gridder.regular(area, shape, z=distance)[::-1],
             gridder.regular(area, shape, z=-distance)[::-1],
             np.array(gridder.regular(area, shape, z=distance))[[0, 2, 1]],
             np.array(gridder.regular(area, shape, z=-distance))[[0, 2, 1]]]
    xp, yp, zp = grids[0]
    # Test if each component is consistent
    # POTENTIAL
    face = [prism.potential(x, y, z, model) for x, y, z in grids]
    for i in range(6):
        for j in range(i + 1, 6):
            assert_almost(face[i], face[j], 10,
                          'Failed potential, faces %d and %d' % (i, j))
    # GX
    top, bottom, north, south, east, west = [prism.gx(x, y, z, model)
                                             for x, y, z in grids]
    assert_almost(top, bottom, 10, 'Failed gx, top and bottom')
    assert_almost(north, -south, 10, 'Failed gx, north and south')
    assert_almost(east, west, 10, 'Failed gx, east and west')
    assert_almost(east, top, 10, 'Failed gx, east and top')
    assert_almost(north, -prism.gz(xp, yp, zp, model), 10,
                  'Failed gx, north and gz')
    assert_almost(south, prism.gz(xp, yp, zp, model), 10,
                  'Failed gx, south and gz')
    # GY
    top, bottom, north, south, east, west = [prism.gy(x, y, z, model)
                                             for x, y, z in grids]
    assert_almost(top, bottom, 10, 'Failed gy, top and bottom')
    assert_almost(north, south, 10, 'Failed gy, north and south')
    assert_almost(east, -west, 10, 'Failed gy, east and west')
    assert_almost(north, top, 10, 'Failed gy, north and top')
    assert_almost(east, -prism.gz(xp, yp, zp, model), 10,
                  'Failed gy, east and gz')
    assert_almost(west, prism.gz(xp, yp, zp, model), 10,
                  'Failed gy, west and gz')
    # GZ
    top, bottom, north, south, east, west = [prism.gz(x, y, z, model)
                                             for x, y, z in grids]
    assert_almost(top, -bottom, 10, 'Failed gz, top and bottom')
    assert_almost(north, south, 10, 'Failed gz, north and south')
    assert_almost(east, west, 10, 'Failed gz, east and west')
    assert_almost(north, prism.gx(xp, yp, zp, model), 10,
                  'Failed gz, north and gx')
    assert_almost(south, prism.gx(xp, yp, zp, model), 10,
                  'Failed gz, south and gx')
    assert_almost(east, prism.gy(xp, yp, zp, model), 10,
                  'Failed gz, east and gy')
    assert_almost(west, prism.gy(xp, yp, zp, model), 10,
                  'Failed gz, west and gy')
    # GXX
    top, bottom, north, south, east, west = [prism.gxx(x, y, z, model)
                                             for x, y, z in grids]
    assert_almost(top, bottom, 10, 'Failed gxx, top and bottom')
    assert_almost(north, south, 10, 'Failed gxx, north and south')
    assert_almost(east, west, 10, 'Failed gxx, east and west')
    assert_almost(east, top, 10, 'Failed gxx, east and top')
    assert_almost(north, prism.gzz(xp, yp, zp, model), 10,
                  'Failed gxx, north and gzz')
    assert_almost(south, prism.gzz(xp, yp, zp, model), 10,
                  'Failed gxx, south and gzz')
    # GXY
    top, bottom, north, south, east, west = [prism.gxy(x, y, z, model)
                                             for x, y, z in grids]
    assert_almost(top, bottom, 4, 'Failed gxy, top and bottom')
    assert_almost(north, -south, 10, 'Failed gxy, north and south')
    assert_almost(east, -west, 10, 'Failed gxy, east and west')
    assert_almost(north, -prism.gyz(xp, yp, zp, model), 10,
                  'Failed gxy, north and gyz')
    assert_almost(south, prism.gyz(xp, yp, zp, model), 10,
                  'Failed gxy, south and gyz')
    # GXZ
    top, bottom, north, south, east, west = [prism.gxz(x, y, z, model)
                                             for x, y, z in grids]
    assert_almost(top, -bottom, 10, 'Failed gxz, top and bottom')
    assert_almost(north, -south, 10, 'Failed gxz, north and south')
    assert_almost(east, west, 4, 'Failed gxz, east and west')
    assert_almost(bottom, north, 10, 'Failed gxz, bottom and north')
    assert_almost(top, south, 10, 'Failed gxz, top and south')
    assert_almost(east, prism.gxy(xp, yp, zp, model), 4,
                  'Failed gxz, east and gxy')
    assert_almost(west, prism.gxy(xp, yp, zp, model), 10,
                  'Failed gxz, west and gxy')
    # GYY
    top, bottom, north, south, east, west = [prism.gyy(x, y, z, model)
                                             for x, y, z in grids]
    assert_almost(top, bottom, 10, 'Failed gyy, top and bottom')
    assert_almost(north, south, 10, 'Failed gyy, north and south')
    assert_almost(east, west, 10, 'Failed gyy, east and west')
    assert_almost(top, north, 10, 'Failed gyy, top and north')
    assert_almost(east, prism.gzz(xp, yp, zp, model), 10,
                  'Failed gyy, east and gzz')
    assert_almost(west, prism.gzz(xp, yp, zp, model), 10,
                  'Failed gyy, west and gzz')
    # GYZ
    top, bottom, north, south, east, west = [prism.gyz(x, y, z, model)
                                             for x, y, z in grids]
    assert_almost(top, -bottom, 10, 'Failed gyz, top and bottom')
    assert_almost(north, south, 4, 'Failed gyz, north and south')
    assert_almost(east, -west, 10, 'Failed gyz, east and west')
    assert_almost(top, west, 10, 'Failed gyz, top and west')
    assert_almost(bottom, east, 10, 'Failed gyz, bottom and east')
    assert_almost(north, prism.gxy(xp, yp, zp, model), 4,
                  'Failed gyz, north and gxy')
    assert_almost(south, prism.gxy(xp, yp, zp, model), 10,
                  'Failed gyz, south and gxy')
    # GZZ
    top, bottom, north, south, east, west = [prism.gzz(x, y, z, model)
                                             for x, y, z in grids]
    assert_almost(top, bottom, 10, 'Failed gzz, top and bottom')
    assert_almost(north, south, 10, 'Failed gzz, north and south')
    assert_almost(east, west, 10, 'Failed gzz, east and west')
    assert_almost(north, prism.gxx(xp, yp, zp, model), 10,
                  'Failed gzz, north and gxx')
    assert_almost(south, prism.gxx(xp, yp, zp, model), 10,
                  'Failed gzz, south and gxx')
    assert_almost(east, prism.gyy(xp, yp, zp, model), 10,
                  'Failed gzz, east and gyy')
    assert_almost(west, prism.gyy(xp, yp, zp, model), 10,
                  'Failed gzz, west and gyy')
Ejemplo n.º 36
0
(more complex model + noisy data)
"""
from fatiando import gridder, mesher, utils
from fatiando.gravmag import prism, imaging
from fatiando.vis import mpl, myv

# Make some synthetic gravity data from a simple prism model
model = [
    mesher.Prism(-4000, 0, -4000, -2000, 2000, 5000, {'density': 1200}),
    mesher.Prism(-1000, 1000, -1000, 1000, 1000, 7000, {'density': -800}),
    mesher.Prism(2000, 4000, 3000, 4000, 0, 2000, {'density': 600})
]
# Calculate on a scatter of points to show that migration doesn't need gridded
# data
xp, yp, zp = gridder.scatter((-6000, 6000, -6000, 6000), 1000, z=-10)
gz = utils.contaminate(prism.gz(xp, yp, zp, model), 0.1)

# Plot the data
shape = (50, 50)
mpl.figure()
mpl.axis('scaled')
mpl.contourf(yp, xp, gz, shape, 30, interp=True)
mpl.colorbar()
mpl.plot(yp, xp, '.k')
mpl.xlabel('East (km)')
mpl.ylabel('North (km)')
mpl.m2km()
mpl.show()

mesh = imaging.migrate(xp, yp, zp, gz, 0, 10000, (30, 30, 30), power=0.8)
Ejemplo n.º 37
0
from fatiando.vis import mpl, myv

# Generate some synthetic total field anomaly data
bounds = [0, 10000, 0, 10000, 0, 5000]
props = {'density': 500}
props2 = {'density': 1000}
model = [
    mesher.Prism(4000, 6000, 4000, 6000, 500, 2500, props),
    mesher.Prism(2000, 2500, 2000, 2500, 500, 1000, props2),
    mesher.Prism(7500, 8000, 5500, 6500, 500, 1000, props2),
    mesher.Prism(1500, 2000, 4000, 5000, 500, 1000, props2)
]
area = bounds[:4]
shape = (50, 50)
x, y, z = gridder.regular(area, shape, z=-1)
gz = utils.contaminate(prism.gz(x, y, z, model), 0.1)
mesh = mesher.PrismMesh(bounds, (20, 40, 40))
seeds = harvester.sow([[5000, 5000, 1000, props]], mesh)

# Run the inversion without using weights
data = [harvester.Gz(x, y, z, gz)]
estimate, predicted = harvester.harvest(data,
                                        seeds,
                                        mesh,
                                        compactness=1.5,
                                        threshold=0.001)
mesh.addprop('density', estimate['density'])
bodies = mesher.vremove(0, 'density', mesh)
mpl.figure()
mpl.axis('scaled')
mpl.title('No weights: Observed (color) vs Predicted (black)')
GravMag: Forward modeling of the gravitational potential and its derivatives
using 3D model
"""
from fatiando import mesher, gridder
from fatiando.gravmag import prism
from fatiando.vis import mpl, myv

model = [mesher.Prism(-4000,-3000,-4000,-3000,0,2000,{'density':1000}),
          mesher.Prism(-1000,1000,-1000,1000,0,2000,{'density':-900}),
          mesher.Prism(2000,4000,3000,4000,0,2000,{'density':1300})]
shape = (100,100)
xp, yp, zp = gridder.regular((-5000, 5000, -5000, 5000), shape, z=-150)
fields = [prism.potential(xp, yp, zp, model),
          prism.gx(xp, yp, zp, model),
          prism.gy(xp, yp, zp, model),
          prism.gz(xp, yp, zp, model),
          prism.gxx(xp, yp, zp, model),
          prism.gxy(xp, yp, zp, model),
          prism.gxz(xp, yp, zp, model),
          prism.gyy(xp, yp, zp, model),
          prism.gyz(xp, yp, zp, model),
          prism.gzz(xp, yp, zp, model)]
titles = ['potential', 'gx', 'gy', 'gz',
          'gxx', 'gxy', 'gxz', 'gyy', 'gyz', 'gzz']
mpl.figure(figsize=(8, 9))
mpl.subplots_adjust(left=0.03, right=0.95, bottom=0.05, top=0.92, hspace=0.3)
mpl.suptitle("Potential fields produced by a 3 prism model")
for i, field in enumerate(fields):
    mpl.subplot(4, 3, i + 3)
    mpl.axis('scaled')
    mpl.title(titles[i])
Ejemplo n.º 39
0
    iVoxelCount = 0

    oTimeBeforeMapping = datetime.now()
    for oVoxel in lModel:  #NOTE each oVoxel can be sent to a different mapper
        #for each prism:
        #calculate forward model for each prism and create mFmodelDiff
        #mFmodelDiff contains all prisms' forward modelled vectors
        #also return superposition of all prisms' signals in form of lCalc1
        #Each one of these calcs could be done by a mapreduce task

        oVoxel.z2 += aMetricChange[
            iVoxelCount]  #update the voxel metric by the residual vector from the inversion
        oVoxel.z2 = iMinDepth if oVoxel.z2 < 0 else oVoxel.z2  #make sure depths are non negative

        #calculate first forward model
        aPrismCalc1 = prism.gz(aXGridCoords, aYGridCoords, aZGridCoords,
                               [oVoxel])
        oVoxel.z2 += iDeltaZ

        #calculate second forward model
        aPrismCalc2 = prism.gz(aXGridCoords, aYGridCoords, aZGridCoords,
                               [oVoxel])

        #compare computed signal change due to the model change and store for each prism
        mFmodelDiff[:, iVoxelCount] = (aPrismCalc2 - aPrismCalc1) / iDeltaZ

        iVoxelCount += 1

        #superimpose the signal for each prism into an array for the whole area
        aCalcSignal += aPrismCalc1  #NOTE this would be done in the reducer

        #--- end forward modelling each voxel
from fatiando import utils, gridder, mesher
from fatiando.gravmag import prism, harvester
from fatiando.vis import mpl, myv

# Generate some synthetic total field anomaly data
bounds = [0, 10000, 0, 10000, 0, 5000]
props = {'density':500}
props2 = {'density':1000}
model = [mesher.Prism(4000, 6000, 4000, 6000, 500, 2500, props),
         mesher.Prism(2000, 2500, 2000, 2500, 500, 1000, props2),
         mesher.Prism(7500, 8000, 5500, 6500, 500, 1000, props2),
         mesher.Prism(1500, 2000, 4000, 5000, 500, 1000, props2)]
area = bounds[:4]
shape = (50, 50)
x, y, z = gridder.regular(area, shape, z=-1)
gz = utils.contaminate(prism.gz(x, y, z, model), 0.1)
mesh = mesher.PrismMesh(bounds, (20, 40, 40))
seeds = harvester.sow([[5000, 5000, 1000, props]], mesh)

# Run the inversion without using weights
data = [harvester.Gz(x, y, z, gz)]
estimate, predicted = harvester.harvest(data, seeds, mesh,
    compactness=1.5, threshold=0.001)
mesh.addprop('density', estimate['density'])
bodies = mesher.vremove(0, 'density', mesh)
mpl.figure()
mpl.axis('scaled')
mpl.title('No weights: Observed (color) vs Predicted (black)')
levels = mpl.contourf(y, x, gz, shape, 17)
mpl.colorbar()
mpl.contour(y, x, predicted[0], shape, levels, color='k')
from fatiando.vis import mpl, myv

# Make a model
bounds = [-5000, 5000, -5000, 5000, 0, 5000]
model = [
    Prism(-1500, -500, -1500, -500, 500, 1500, {'density': 1000}),
    Prism(500, 1500, 1000, 2000, 500, 1500, {'density': 1000})]
# Generate some data from the model
shape = (100, 100)
area = bounds[0:4]
xp, yp, zp = gridder.regular(area, shape, z=-1)
# Add a constant baselevel
baselevel = 10
# Convert the data from mGal to SI because Euler and FFT derivation require
# data in SI
gz = utils.mgal2si(prism.gz(xp, yp, zp, model)) + baselevel
xderiv = transform.derivx(xp, yp, gz, shape)
yderiv = transform.derivy(xp, yp, gz, shape)
zderiv = transform.derivz(xp, yp, gz, shape)

mpl.figure()
titles = ['Gravity anomaly', 'x derivative', 'y derivative', 'z derivative']
for i, f in enumerate([gz, xderiv, yderiv, zderiv]):
    mpl.subplot(2, 2, i + 1)
    mpl.title(titles[i])
    mpl.axis('scaled')
    mpl.contourf(yp, xp, f, shape, 50)
    mpl.colorbar()
    mpl.m2km()
mpl.show()
Ejemplo n.º 42
0
``harvester`` (simple example)
"""
from fatiando import gridder, utils
from fatiando.gravmag import prism, harvester
from fatiando.mesher import Prism, PrismMesh, vremove
from fatiando.vis import mpl, myv

# Create a synthetic model
model = [Prism(250, 750, 250, 750, 200, 700, {'density': 1000})]
# and generate synthetic data from it
shape = (25, 25)
bounds = [0, 1000, 0, 1000, 0, 1000]
area = bounds[0:4]
xp, yp, zp = gridder.regular(area, shape, z=-1)
noise = 0.1  # 0.1 mGal noise
gz = utils.contaminate(prism.gz(xp, yp, zp, model), noise)
# plot the data
mpl.figure()
mpl.title("Synthetic gravity anomaly (mGal)")
mpl.axis('scaled')
levels = mpl.contourf(yp, xp, gz, shape, 12)
mpl.colorbar()
mpl.xlabel('Horizontal coordinate y (km)')
mpl.ylabel('Horizontal coordinate x (km)')
mpl.m2km()
mpl.show()

# Inversion setup
# Create a mesh
mesh = PrismMesh(bounds, (25, 25, 25))
# Wrap the data so that harvester can use it
Ejemplo n.º 43
0
def test_gz():
    "gravmag.prism.gz python vs cython implementation"
    py = _prism_numpy.gz(xp, yp, zp, model)
    cy = prism.gz(xp, yp, zp, model)
    diff = np.abs(py - cy)
    assert np.all(diff <= precision), 'max diff: %g' % (max(diff))
Ejemplo n.º 44
0
import matplotlib.pyplot as plt
from fatiando.gravmag import prism, sphere
from fatiando.gravmag.eqlayer import EQLGravity
from fatiando.inversion import Damping
from fatiando import gridder, utils, mesher

# First thing to do is make some synthetic data to test the method. We'll use a
# single prism to keep it simple
props = {'density': 500}
model = [mesher.Prism(-5000, 5000, -200, 200, 100, 4000, props)]

# The synthetic data will be generated on a random scatter of points
area = [-8000, 8000, -5000, 5000]
x, y, z = gridder.scatter(area, 300, z=0, seed=42)
# Generate some noisy data from our model
gz = utils.contaminate(prism.gz(x, y, z, model), 0.2, seed=0)

# Now for the equivalent layer. We must setup a layer of point masses where
# we'll estimate a density distribution that fits our synthetic data
layer = mesher.PointGrid(area, 500, (20, 20))
# 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')
Ejemplo n.º 45
0
 
 iVoxelCount = 0
 
 oTimeBeforeMapping = datetime.now()
 for oVoxel in lModel:       #NOTE each oVoxel can be sent to a different mapper
     #for each prism:
         #calculate forward model for each prism and create mFmodelDiff
             #mFmodelDiff contains all prisms' forward modelled vectors
         #also return superposition of all prisms' signals in form of lCalc1
         #Each one of these calcs could be done by a mapreduce task
     
     oVoxel.z2 += aMetricChange[iVoxelCount]     #update the voxel metric by the residual vector from the inversion
     oVoxel.z2 = iMinDepth if oVoxel.z2 < 0 else oVoxel.z2   #make sure depths are non negative
     
     #calculate first forward model
     aPrismCalc1 = prism.gz(aXGridCoords, aYGridCoords, aZGridCoords, [oVoxel])
     oVoxel.z2 += iDeltaZ
     
     #calculate second forward model
     aPrismCalc2 = prism.gz(aXGridCoords, aYGridCoords, aZGridCoords, [oVoxel])
     
     #compare computed signal change due to the model change and store for each prism
     mFmodelDiff[:, iVoxelCount] = (aPrismCalc2 - aPrismCalc1)/iDeltaZ
     
     iVoxelCount += 1
     
     
     #superimpose the signal for each prism into an array for the whole area
     aCalcSignal += aPrismCalc1      #NOTE this would be done in the reducer
     
     #--- end forward modelling each voxel