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)
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)
# 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') # 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)
# 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') # 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)
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 gz_true = prism.gz(x, y, z - 500, model) gz_up = sphere.gz(x, y, z - 500, layer) mpl.figure()
# Make synthetic data props = {'density': 1000} model = [mesher.Prism(-500, 500, -1000, 1000, 500, 4000, props)] area = [-5000, 5000, -5000, 5000] x1, y1, z1 = gridder.scatter(area, 80, z=0, seed=0) gz = utils.contaminate(prism.gz(x1, y1, z1, model), 0.1, seed=0) x2, y2, z2 = gridder.regular(area, (10, 50), z=-200) gzz = utils.contaminate(prism.gzz(x2, y2, z2, model), 5, seed=0) # Setup the layer layer = mesher.PointGrid([-6000, 6000, -6000, 6000], 500, (50, 50)) # 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')
from fatiando.gravmag.eqlayer import EQLGravity from fatiando.inversion import Damping 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 solver = EQLGravity(x, y, z, gz, layer) + 1e-22*Damping(layer.size) solver.fit() 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')
from fatiando.gravmag.eqlayer import EQLGravity from fatiando.inversion.regularization import Damping 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) # Setup the layer layer = mesher.PointGrid([-6000, 6000, -6000, 6000], 500, (50, 50)) # Estimate the density # Need to apply enough damping so that won't try to fit the error as well solver = EQLGravity(x, y, z, gz, layer) + 10**-24*Damping(layer.size) solver.fit() layer.addprop('density', solver.estimate_) residuals = solver.residuals() print "Residuals:" print "mean:", residuals.mean() print "stddev:", residuals.std() # Plot the layer and the fit 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()