""" 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())
""" from fatiando.gravmag import prism, sphere from fatiando.gravmag.eqlayer import EQLTotalField from fatiando.inversion.regularization import Damping, LCurve from fatiando import gridder, utils, mesher from fatiando.vis import mpl # Make synthetic data inc, dec = -60, 23 props = {'magnetization': 10} 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) tf = utils.contaminate(prism.tf(x, y, z, model, inc, dec), 5, seed=0) # Setup the layer layer = mesher.PointGrid([-7000, 7000, -7000, 7000], 700, (50, 50)) # Estimate the magnetization intensity # Need to apply regularization so that won't try to fit the error as well misfit = EQLTotalField(x, y, z, tf, inc, dec, 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, -15)]).fit() residuals = solver.residuals() layer.addprop('magnetization', solver.estimate_) print "Residuals:" print "mean:", residuals.mean() print "stddev:", residuals.std() # Now I can forward model the layer at the south pole and check against the # true solution of the prism tfpole = prism.tf(x, y, z, model, -90, 0)
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') # 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)
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 gz_true = prism.gz(x, y, z - 500, model)
inc, dec = -5, 23 props = {'magnetization': utils.ang2vec(5, inc, dec)} model = [mesher.Prism(-2000, 2000, -200, 200, 100, 4000, props)] # The synthetic data will be generated on a regular grid area = [-8000, 8000, -5000, 5000] shape = (40, 40) x, y, z = gridder.regular(area, shape, z=-150) # Generate some noisy data from our model data = utils.contaminate(prism.tf(x, y, z, model, inc, dec), 5, seed=0) # Now for the equivalent layer. We must setup a layer of dipoles where we'll # estimate a magnetization intensity distribution that fits our synthetic data. # Notice that we only estimate the intensity. We must provide the magnetization # direction of the layer through the sinc and sdec parameters. layer = mesher.PointGrid(area, 700, shape) eql = (EQLTotalField(x, y, z, data, inc, dec, layer, sinc=inc, sdec=dec) + 1e-15*Damping(layer.size)) eql.fit() # Print some statistics of how well the estimated layer fits the data residuals = eql[0].residuals() print("Residuals:") print(" mean:", residuals.mean(), 'nT') print(" stddev:", residuals.std(), 'nT') # Now I can forward model data anywhere we want. To reduce to the pole, we must # provide inc = 90 (or -90) for the Earth's field as well as to the layer's # magnetization. layer.addprop('magnetization', utils.ang2vec(eql.estimate_, inc=-90, dec=0)) atpole = sphere.tf(x, y, z, layer, inc=-90, dec=0)
""" Meshing: Making a grid of 3D point sources """ from fatiando import mesher, utils, gravmag, gridder from fatiando.vis import mpl grid = mesher.PointGrid([0, 1000, 0, 2000], 500, (50, 50)) # Add some density to the grid grid.addprop( 'density', 1000000000 * utils.gaussian2d(grid.x, grid.y, 100, 500, x0=500, y0=1000, angle=-60)) # and some magnetization inc, dec = -45, 0 grid.addprop( 'magnetization', [d / 100. * utils.ang2vec(1, inc, dec) for d in grid.props['density']]) # plot the layer mpl.figure() 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()