def test_pel_polereduce(): "PELTotalField 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 = (40, 40) 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, 100, shape) windows = (20, 20) degree = 3 pel = PELTotalField(x, y, z, data, inc, dec, layer, windows, degree, sinc, sdec) eql = pel + 1e-25*PELSmoothness(layer, windows, degree) eql.fit() assert_array_almost_equal(eql[0].predicted(), data, decimal=1) 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)
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)
def test_totalfield_sphere(): ''' This test compare the results obtained by both function that calculates the total field anomaly due to a solid sphere. The model has the same dimensions, magnetization intensity and also the same pair for inclination and declination. We use the function from Fatiando a Terra in order to compare with our function. ''' incf = 30. decf = 30. incs = 60. decs = 45. magnetization = 2.345 # Modelo para o Fatiando xp, yp, zp = gridder.regular((-1000, 1000, -1000, 1000), (200, 200), z=-345.) model = [ mesher.Sphere( -100., 400., 550., 380., {'magnetization': utils.ang2vec(magnetization, incs, decs)}) ] tf = sphere.tf(xp, yp, zp, model, incf, decf) tf = tf.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., magnetization] mytf = sphere_tfa(y, x, z, mymodel, incf, decf, incs, decs) assert_almost_equal(tf, mytf, decimal=5)
def sensitivity(self, grid): x, y, z = self.x, self.y, self.z inc, dec = self.inc, self.dec mag = utils.dircos(self.sinc, self.sdec) sens = numpy.empty((self.size, len(grid)), dtype=float) for i, s in enumerate(grid): sens[:,i] = kernel.tf(x, y, z, [s], inc, dec, pmag=mag) return sens
def test_tf(): "gravmag.sphere.tf python vs cython implementation" py = _sphere_numpy.tf(xp, yp, zp, model, inc, dec) cy = sphere.tf(xp, yp, zp, model, inc, dec) diff = np.abs(py - cy) # Lower precison because python calculates using Blakely and cython using # the gravity kernels assert np.all(diff <= 10 ** -9), 'max diff: %g' % (max(diff))
def test_tf(): "gravmag.sphere.tf python vs cython implementation" py = _sphere_numpy.tf(xp, yp, zp, model, inc, dec) cy = sphere.tf(xp, yp, zp, model, inc, dec) diff = np.abs(py - cy) # Lower precison because python calculates using Blakely and cython using # the gravity kernels assert np.all(diff <= 10**-9), 'max diff: %g' % (max(diff))
def sensitivity(self, grid): x, y, z = self.x, self.y, self.z inc, dec = self.inc, self.dec mag = utils.dircos(self.sinc, self.sdec) sens = numpy.empty((self.size, len(grid)), dtype=float) for i, s in enumerate(grid): sens[:, i] = kernel.tf(x, y, z, [s], inc, dec, pmag=mag) return sens
def fwd_model(model, shape=(300, 300), area=[0, 30e3, 0, 30e3]): # Set the inclination and declination of the geomagnetic field. inc, dec = -10, 13 # Create a regular grid at a constant height shape = shape area = area x, y, z = gridder.regular(area, shape, z=-10) field = ['Total field Anomaly (nt)', sphere.tf(x, y, z, model, inc, dec)] return x, y, z, field, shape
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 setup(): global model, x, y, z, inc, dec, struct_ind, field, xderiv, yderiv, \ zderiv, base, pos inc, dec = -30, 50 pos = np.array([1000, 1000, 200]) model = Sphere(pos[0], pos[1], pos[2], 1, {'magnetization': utils.ang2vec(10000, inc, dec)}) struct_ind = 3 shape = (128, 128) x, y, z = gridder.regular((0, 3000, 0, 3000), shape, z=-1) base = 10 field = utils.nt2si(sphere.tf(x, y, z, [model], inc, dec)) + base xderiv = fourier.derivx(x, y, field, shape) yderiv = fourier.derivy(x, y, field, shape) zderiv = fourier.derivz(x, y, field, shape)
def setup(): global model, x, y, z, inc, dec, struct_ind, field, xderiv, yderiv, zderiv, base, pos inc, dec = -30, 50 pos = np.array([1000, 1200, 200]) model = Sphere(pos[0], pos[1], pos[2], 1, {"magnetization": utils.ang2vec(10000, inc, dec)}) struct_ind = 3 shape = (200, 200) x, y, z = gridder.regular((0, 3000, 0, 3000), shape, z=-100) base = 10 field = sphere.tf(x, y, z, [model], inc, dec) + base # Use finite difference derivatives so that these tests don't depend on the # performance of the FFT derivatives. xderiv = (sphere.tf(x + 1, y, z, [model], inc, dec) - sphere.tf(x - 1, y, z, [model], inc, dec)) / 2 yderiv = (sphere.tf(x, y + 1, z, [model], inc, dec) - sphere.tf(x, y - 1, z, [model], inc, dec)) / 2 zderiv = (sphere.tf(x, y, z + 1, [model], inc, dec) - sphere.tf(x, y, z - 1, [model], inc, dec)) / 2
def setup(): global model, x, y, z, inc, dec, struct_ind, field, dx, dy, dz, base, pos inc, dec = -30, 50 pos = np.array([1000, 1200, 200]) model = Sphere(pos[0], pos[1], pos[2], 1, {'magnetization': utils.ang2vec(10000, inc, dec)}) struct_ind = 3 shape = (200, 200) x, y, z = gridder.regular((0, 3000, 0, 3000), shape, z=-100) base = 10 field = sphere.tf(x, y, z, [model], inc, dec) + base # Use finite difference derivatives so that these tests don't depend on the # performance of the FFT derivatives. dx = (sphere.tf(x + 1, y, z, [model], inc, dec) - sphere.tf(x - 1, y, z, [model], inc, dec)) / 2 dy = (sphere.tf(x, y + 1, z, [model], inc, dec) - sphere.tf(x, y - 1, z, [model], inc, dec)) / 2 dz = (sphere.tf(x, y, z + 1, [model], inc, dec) - sphere.tf(x, y, z - 1, [model], inc, dec)) / 2
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()
# 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() 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 (A/m)') mpl.pcolor(layer.y, layer.x, layer.props['magnetization'], layer.shape) mpl.colorbar() mpl.m2km() mpl.subplot(1, 3, 2)
# declination into a 3 component vector for easier handling. model = [ mesher.Sphere(x=10e3, y=10e3, z=2e3, radius=1.5e3, props={'magnetization': utils.ang2vec(1, inc=50, dec=-30)}), mesher.Sphere(x=20e3, y=20e3, z=2e3, radius=1.5e3, props={'magnetization': utils.ang2vec(1, inc=-70, dec=30)})] # Set the inclination and declination of the geomagnetic field. inc, dec = -10, 13 # Create a regular grid at a constant height shape = (300, 300) area = [0, 30e3, 0, 30e3] x, y, z = gridder.regular(area, shape, z=-10) fields = [ ['Total field Anomaly (nt)', sphere.tf(x, y, z, model, inc, dec)], ['Bx (nT)', sphere.bx(x, y, z, model)], ['By (nT)', sphere.by(x, y, z, model)], ['Bz (nT)', sphere.bz(x, y, z, model)], ] # Make maps of all fields calculated fig = plt.figure(figsize=(7, 6)) plt.rcParams['font.size'] = 10 X, Y = x.reshape(shape)/1000, y.reshape(shape)/1000 for i, tmp in enumerate(fields): ax = plt.subplot(2, 2, i + 1) field, data = tmp scale = np.abs([data.min(), data.max()]).max() ax.set_title(field) plot = ax.pcolormesh(Y, X, data.reshape(shape), cmap='RdBu_r',
from fatiando.gravmag import sphere from fatiando.vis import mpl from fatiando.gravmag.magdir import DipoleMagDir from fatiando.constants import CM # Make noise-corrupted synthetic data inc, dec = -10.0, -15.0 # inclination and declination of the Geomagnetic Field model = [ mesher.Sphere(3000, 3000, 1000, 1000, {'magnetization': ang2vec(6.0, -20.0, -10.0)}), mesher.Sphere(7000, 7000, 1000, 1000, {'magnetization': ang2vec(10.0, 3.0, -67.0)}) ] area = (0, 10000, 0, 10000) x, y, z = gridder.scatter(area, 1000, z=-150, seed=0) tf = contaminate(sphere.tf(x, y, z, model, inc, dec), 5.0, seed=0) # Give the centers of the dipoles centers = [[3000, 3000, 1000], [7000, 7000, 1000]] # Estimate the magnetization vectors solver = DipoleMagDir(x, y, z, tf, inc, dec, centers).fit() # Print the estimated and true dipole monents, inclinations and declinations print 'Estimated magnetization (intensity, inclination, declination)' for e in solver.estimate_: print e # Plot the fit and the normalized histogram of the residuals mpl.figure(figsize=(14, 5)) mpl.subplot(1, 2, 1)
N = shape[0] * shape[1] M = shapej[0] * shapej[1] regul = np.logspace(-20, -11, 10) #From Fatiando layer = PointGrid(areaj, zj, shapej) #to the L curve plot phi_list = [] p_list = [] G = np.empty((N, M), dtype=float) for i, c in enumerate(layer): #From Fatiando G[:, i] = sphere.tf(xi, yi, zi, [c], inc_o, dec_o, pmag=F) for i, lambida in enumerate(regul): lambida = float(format(lambida, '.3e')) print '\niteration %d lambida=%1.3e \n' % (i, lambida) # mu=1e-20 I = np.identity(M) GTG = np.dot(G.T, G) GTd = np.dot(G.T, tf.ravel()) p = np.linalg.solve(GTG + lambida * I, GTd) I = None GTd = None
mesher.Sphere(x=-1000, y=-1000, z=1500, radius=1000, props={'magnetization': utils.ang2vec(2, inc, dec)}), mesher.Sphere(x=1000, y=1500, z=1000, radius=1000, props={'magnetization': utils.ang2vec(1, inc, dec)}) ] # Generate some magnetic data from the model shape = (100, 100) area = [-5000, 5000, -5000, 5000] x, y, z = gridder.regular(area, shape, z=-150) data = sphere.tf(x, y, z, model, inc, dec) # We also need the derivatives of our data xderiv = transform.derivx(x, y, data, shape) yderiv = transform.derivy(x, y, data, shape) zderiv = transform.derivz(x, y, data, shape) # Now we can run our Euler deconv solver using expanding windows. We'll run 2 # solvers, each one expanding windows from points close to the anomalies. # We use a structural index of 3 to indicate that we think the sources are # spheres. # Make the solver and use fit() to obtain the estimate for the lower right # anomaly print("Euler solutions:")
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()
# 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) fig, axes = plt.subplots(1, 2, figsize=(8, 6)) ax = axes[0] ax.set_title(u'Data at {}° inclination'.format(inc)) ax.set_aspect('equal') amp = np.abs([data.min(), data.max()]).max() tmp = ax.tricontourf(y/1000, x/1000, data, 30, cmap='RdBu_r', vmin=-amp, vmax=amp) fig.colorbar(tmp, ax=ax, pad=0.1, aspect=30, orientation='horizontal').set_label('nT') ax.set_xlabel('y (km)') ax.set_ylabel('x (km)')
# Make some synthetic magnetic data to test our Euler deconvolution. # The regional field inc, dec = -45, 0 # Make a model of two spheres magnetized by induction only model = [ mesher.Sphere(x=-1000, y=-1000, z=1500, radius=1000, props={'magnetization': utils.ang2vec(2, inc, dec)}), mesher.Sphere(x=1000, y=1500, z=1000, radius=1000, props={'magnetization': utils.ang2vec(1, inc, dec)}), ] # Generate some magnetic data from the model shape = (100, 100) area = [-5000, 5000, -5000, 5000] x, y, z = gridder.regular(area, shape, z=-150) data = sphere.tf(x, y, z, model, inc, dec) # We also need the derivatives of our data xderiv = transform.derivx(x, y, data, shape) yderiv = transform.derivy(x, y, data, shape) zderiv = transform.derivz(x, y, data, shape) # Now we can run our Euler deconv solver using expanding windows. We'll run 2 # solvers, each one expanding windows from points close to the anomalies. # We use a structural index of 3 to indicate that we think the sources are # spheres. # Make the solver and use fit() to obtain the estimate for the lower right # anomaly print("Euler solutions:")
""" from fatiando import mesher, gridder, utils from fatiando.gravmag import sphere from fatiando.vis import mpl # Set the inclination and declination of the regional field inc, dec = -30, 45 # Create a sphere model model = [ # One with induced magnetization mesher.Sphere(0, 2000, 600, 500, {'magnetization':5}), # and one with remanent mesher.Sphere(0, -2000, 600, 500, {'magnetization':utils.ang2vec(10, 70, -50)})] # induced + remanet # Create a regular grid at 100m height shape = (100, 100) area = (-5000, 5000, -5000, 5000) xp, yp, zp = gridder.regular(area, shape, z=-100) # Calculate the anomaly for a given regional field tf = sphere.tf(xp, yp, zp, model, inc, dec) # Plot mpl.figure() mpl.title("Total-field anomaly (nT)") mpl.axis('scaled') mpl.contourf(yp, xp, tf, shape, 15) mpl.colorbar() mpl.xlabel('East y (km)') mpl.ylabel('North x (km)') mpl.m2km() mpl.show()
from fatiando import mesher, gridder from fatiando.utils import ang2vec, vec2ang, contaminate from fatiando.gravmag import sphere from fatiando.vis import mpl from fatiando.gravmag.magdir import DipoleMagDir from fatiando.constants import CM # Make noise-corrupted synthetic data inc, dec = -10.0, -15.0 # inclination and declination of the Geomagnetic Field model = [mesher.Sphere(3000, 3000, 1000, 1000, {'magnetization': ang2vec(6.0, -20.0, -10.0)}), mesher.Sphere(7000, 7000, 1000, 1000, {'magnetization': ang2vec(10.0, 3.0, -67.0)})] area = (0, 10000, 0, 10000) x, y, z = gridder.scatter(area, 1000, z=-150, seed=0) tf = contaminate(sphere.tf(x, y, z, model, inc, dec), 5.0, seed=0) # Give the centers of the dipoles centers = [[3000, 3000, 1000], [7000, 7000, 1000]] # Estimate the magnetization vectors solver = DipoleMagDir(x, y, z, tf, inc, dec, centers).fit() # Print the estimated and true dipole monents, inclinations and declinations print 'Estimated magnetization (intensity, inclination, declination)' for e in solver.estimate_: print e # Plot the fit and the normalized histogram of the residuals mpl.figure(figsize=(14, 5)) mpl.subplot(1, 2, 1)
from fatiando.gravmag import sphere from fatiando.vis import mpl # Set the inclination and declination of the regional field inc, dec = -30, 45 # Create a sphere model model = [ # One with induced magnetization mesher.Sphere(0, 2000, 600, 500, {'magnetization': utils.ang2vec(5, inc, dec)}), # and one with remanent mesher.Sphere(0, -2000, 600, 500, {'magnetization': utils.ang2vec(10, 70, -50)}) ] # Create a regular grid at 100m height shape = (100, 100) area = (-5000, 5000, -5000, 5000) xp, yp, zp = gridder.regular(area, shape, z=-100) # Calculate the anomaly for a given regional field tf = sphere.tf(xp, yp, zp, model, inc, dec) # Plot mpl.figure() mpl.title("Total-field anomaly (nT)") mpl.axis('scaled') mpl.contourf(yp, xp, tf, shape, 15) mpl.colorbar() mpl.xlabel('East y (km)') mpl.ylabel('North x (km)') mpl.m2km() mpl.show()