def test_eql_mag_jacobian(): "EQLTotalField produces the right Jacobian matrix for single source" inc, dec = -30, 20 model = PointGrid([-10, 10, -10, 10], 500, (2, 2))[0] model.addprop('magnetization', utils.ang2vec(1, inc, dec)) n = 1000 x, y, z = gridder.scatter([-10, 10, -10, 10], n, z=-100, seed=42) data = sphere.tf(x, y, z, [model], inc, dec) eql = EQLTotalField(x, y, z, data, inc, dec, [model]) A = eql.jacobian(None) assert A.shape == (n, 1) assert_allclose(A[:, 0], data, rtol=0.01)
def test_eqlayer_polereduce(): "EQLTotalField can reduce data to the pole" # Use remanent magnetization sinc, sdec = -70, 30 model = [Prism(-100, 100, -500, 500, 0, 100, {'magnetization': utils.ang2vec(5, sinc, sdec)})] inc, dec = -60, -15 shape = (50, 50) area = [-2000, 2000, -2000, 2000] x, y, z = gridder.regular(area, shape, z=-100) data = prism.tf(x, y, z, model, inc, dec) true = prism.tf(x, y, z, model, -90, 0, pmag=utils.ang2vec(5, -90, 0)) layer = PointGrid(area, 200, shape) eql = (EQLTotalField(x, y, z, data, inc, dec, layer, sinc, sdec) + 1e-24*Damping(layer.size)) eql.fit() assert_allclose(eql[0].predicted(), data, rtol=0.01) layer.addprop('magnetization', utils.ang2vec(eql.estimate_, inc=-90, dec=0)) calc = sphere.tf(x, y, z, layer, inc=-90, dec=0) assert_allclose(calc, true, atol=10, rtol=0.05)
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) tfreduced = sphere.tf(x, y, z, layer, -90, 0) mpl.figure()
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)