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
# 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) mpl.title("Total Field Anomaly (nT)", fontsize=14) mpl.axis('scaled') nlevels = mpl.contour(y, x, tf, (50, 50), 15, interp=True, color='r', label='Observed', linewidth=2.0) mpl.contour(y, x, solver.predicted(), (50, 50), nlevels, interp=True, color='b', label='Predicted', style='dashed', linewidth=2.0) mpl.legend(loc='upper left', shadow=True, prop={'size': 13}) mpl.xlabel('East y (m)', fontsize=14) mpl.ylabel('North x (m)', fontsize=14) mpl.subplot(1, 2, 2) residuals_mean = numpy.mean(solver.residuals()) residuals_std = numpy.std(solver.residuals()) # Each residual is subtracted from the mean and the resulting # difference is divided by the standard deviation s = (solver.residuals() - residuals_mean) / residuals_std mpl.hist(s, bins=21, range=None, normed=True, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None) mpl.xlim(-4, 4) mpl.title("mean = %.3f std = %.3f" % (residuals_mean, residuals_std), fontsize=14) mpl.ylabel("P(z)", fontsize=14)
gxy = utils.contaminate(gm.prism.gxy(xp, yp, zp, model), noise) gxz = utils.contaminate(gm.prism.gxz(xp, yp, zp, model), noise) gyy = utils.contaminate(gm.prism.gyy(xp, yp, zp, model), noise) gyz = utils.contaminate(gm.prism.gyz(xp, yp, zp, model), noise) gzz = utils.contaminate(gm.prism.gzz(xp, yp, zp, model), noise) tensor = [gxx, gxy, gxz, gyy, gyz, gzz] titles = ['gxx', 'gxy', 'gxz', 'gyy', 'gyz', 'gzz'] # plot the data mpl.figure() for i in xrange(len(tensor)): mpl.subplot(2, 3, i + 1) mpl.title(titles[i]) mpl.axis('scaled') levels = mpl.contourf(yp, xp, tensor[i], shape, 30) mpl.colorbar() mpl.xlabel('y (km)') mpl.ylabel('x (km)') mpl.m2km() mpl.show() # Inversion setup # Create a mesh mesh = PrismMesh(bounds, (30, 30, 30)) # Wrap the data so that harvester can use it data = [gm.harvester.Gxx(xp, yp, zp, gxx), gm.harvester.Gxy(xp, yp, zp, gxy), gm.harvester.Gxz(xp, yp, zp, gxz), gm.harvester.Gyy(xp, yp, zp, gyy), gm.harvester.Gyz(xp, yp, zp, gyz), gm.harvester.Gzz(xp, yp, zp, gzz)] # Make the seeds
# Should be close to the data error if the inversion was able to fit the data residuals = tomo.residuals() print "Assumed error: %g" % (error) print "Standard deviation of residuals: %g" % (np.std(residuals)) mpl.figure(figsize=(14, 5)) mpl.subplot(1, 2, 1) mpl.axis('scaled') mpl.title('Vp model') mpl.squaremesh(model, prop='vp', cmap=mpl.cm.seismic) cb = mpl.colorbar() cb.set_label('Velocity') mpl.points(src_loc, '*y', label="Sources") mpl.points(rec_loc, '^r', label="Receivers") mpl.legend(loc='lower left', shadow=True, numpoints=1, prop={'size': 10}) mpl.m2km() mpl.subplot(1, 2, 2) mpl.axis('scaled') mpl.title('Tomography result') mpl.squaremesh(mesh, prop='vp', vmin=4000, vmax=10000, cmap=mpl.cm.seismic) cb = mpl.colorbar() cb.set_label('Velocity') mpl.m2km() mpl.figure() mpl.grid() mpl.title('Residuals (data with %.4f s error)' % (error)) mpl.hist(residuals, color='gray', bins=10) mpl.xlabel("seconds") mpl.show()
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) # Plot the results myv.figure() myv.prisms(model, 'density', style='wireframe', linewidth=2) myv.prisms(mesh, 'density', edges=False) axes = myv.axes(myv.outline()) myv.wall_bottom(axes.axes.bounds) myv.wall_north(axes.axes.bounds) myv.show()
# 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(gm.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 data = [gm.harvester.Gz(xp, yp, zp, gz)] # Make the seed seeds = gm.harvester.sow([[500, 500, 450, {'density':1000}]], mesh) # Run the inversioin estimate, predicted = gm.harvester.harvest(data, seeds, mesh, compactness=0.5, threshold=0.0005)
temp, error = utils.contaminate(climsig.abrupt(amp, age, zp), 0.02, percent=True, return_stddev=True) # Preparing for the inversion p, residuals = climsig.iabrupt(temp, zp) est_amp, est_age = p mpl.figure(figsize=(12, 5)) mpl.subplot(1, 2, 1) mpl.title("Climate signal (abrupt)") mpl.plot(temp, zp, 'ok', label='Observed') mpl.plot(temp - residuals, zp, '--r', linewidth=3, label='Predicted') mpl.legend(loc='lower right', numpoints=1) mpl.xlabel("Temperature (C)") mpl.ylabel("Z") mpl.ylim(100, 0) ax = mpl.subplot(1, 2, 2) ax2 = mpl.twinx() mpl.title("Age and amplitude") width = 0.3 ax.bar([1 - width], [age], width, color='b', label="True") ax.bar([1], [est_age], width, color='r', label="Estimate") ax2.bar([2 - width], [amp], width, color='b') ax2.bar([2], [est_amp], width, color='r') ax.legend(loc='upper center', numpoints=1) ax.set_ylabel("Age (years)") ax2.set_ylabel("Amplitude (C)") ax.set_xticks([1, 2]) ax.set_xticklabels(['Age', 'Amplitude'])
mpl.ylim(-10**(-3), 10**(-3)) mpl.subplot(2, 2, 4) mpl.title('z component') zseismogram, = mpl.plot([], [], '-k') mpl.xlim(0, duration) mpl.ylim(-10**(-3), 10**(-3)) mpl.subplot(1, 2, 1) # Start with everything zero and grab the plot so that it can be updated later wavefield = mpl.imshow(np.zeros(shape), extent=area, vmin=-10**-6, vmax=10**-6, cmap=mpl.cm.gray_r) mpl.points(stations, '^k') mpl.ylim(area[2:][::-1]) mpl.xlabel('x (km)') mpl.ylabel('z (km)') mpl.m2km() times = np.linspace(0, maxit * dt, maxit) # This function updates the plot every few timesteps def animate(i): # Simulation will yield panels corresponding to P and S waves because # xz2ps=True t, p, s, xcomp, zcomp = simulation.next() mpl.title('time: %0.1f s' % (times[t])) wavefield.set_array((p + s)[::-1]) xseismogram.set_data(times[:t + 1], xcomp[0][:t + 1]) zseismogram.set_data(times[:t + 1], zcomp[0][:t + 1]) return wavefield, xseismogram, zseismogram
titles = ('gxy', 'gzz') mpl.figure() mpl.suptitle("True: color | Inversion: contour") for i in xrange(len(tensor)): mpl.subplot(2, 2, i + 1) mpl.title(titles[i]) mpl.axis('scaled') levels = mpl.contourf(y*0.001, x*0.001, tensor[i], shape, 12) mpl.colorbar() mpl.contour(y*0.001, x*0.001, predicted[i], shape, levels, color='k') for i in xrange(len(tensor)): mpl.subplot(2, 2, i + 3) residuals = tensor[i] - predicted[i] mpl.title('residuals stddev = %.2f' % (residuals.std())) mpl.hist(residuals, bins=10) mpl.xlabel('Residual (Eotvos)') mpl.show() myv.figure() myv.prisms(model, 'density', style='wireframe') myv.prisms([mesh[s.i] for s in seeds], 'density') myv.axes(myv.outline(bounds), ranges=[i*0.001 for i in bounds], fmt='%.1f', nlabels=6) myv.wall_bottom(bounds) myv.wall_north(bounds) myv.figure() myv.prisms(model, 'density', style='wireframe') myv.prisms(density_model, 'density') myv.axes(myv.outline(bounds), ranges=[i*0.001 for i in bounds], fmt='%.1f', nlabels=6) myv.wall_bottom(bounds) myv.wall_north(bounds)
maxit = int(duration / simulation.dt) maxt = duration # This part makes an animation using matplotlibs animation API background = (velocity - 6000) * 10**-3 fig = mpl.figure(figsize=(8, 6)) mpl.subplots_adjust(right=0.98, left=0.11, hspace=0.5, top=0.93) mpl.subplot2grid((4, 3), (0, 0), colspan=3, rowspan=3) wavefield = mpl.imshow(np.zeros_like(velocity), extent=area, cmap=mpl.cm.gray_r, vmin=-0.05, vmax=0.05) mpl.points([75 * ds, 125 * ds], '^b', size=8) # seismometer position mpl.ylim(area[2:][::-1]) mpl.xlabel('x (km)') mpl.ylabel('z (km)') mpl.m2km() mpl.subplot2grid((4, 3), (3, 0), colspan=3) seismogram1, = mpl.plot([], [], '-k') mpl.xlim(0, duration) mpl.ylim(-0.05, 0.05) mpl.ylabel('Amplitude') mpl.xlabel('Time (s)') times = np.linspace(0, maxt, maxit) # This function updates the plot every few timesteps simulation.run(maxit) seismogram = simulation[:, 125, 75] # (time, z and x) shape
padding=50, taper=0.01) # This part makes an animation using matplotlibs animation API fig = mpl.figure(figsize=(12, 5)) # Start with everything zero and grab the plot so that it can be updated later mpl.imshow(pvel[::-1], extent=area, alpha=0.25) wavefield = mpl.imshow(np.zeros(shape), extent=area, vmin=-10**-7, vmax=10**-7, alpha=0.75, cmap=mpl.cm.gray_r) mpl.points(stations, '.k') mpl.ylim(area[2:][::-1]) mpl.xlabel('x (km)') mpl.ylabel('z (km)') mpl.m2km() times = np.linspace(0, maxit * dt, maxit) # the only way for getting the feedback response of the seimograms global seismograms # This function updates the plot every few timesteps def animate(i): # Simulation will yield panels corresponding to P and S waves because # xz2ps=True t, ux, uz, xcomp, zcomp = simulation.next() mpl.title('time: %0.3f s' % (times[t])) # wavefield.set_array((p + s)[::-1]) wavefield.set_data(uz[::-1])
mpl.subplot(3, 1, 2) mpl.title("Seismogram 2") seismogram2, = mpl.plot([], [], "-k") mpl.xlim(0, duration) mpl.ylim(-0.1, 0.1) mpl.ylabel("Amplitude") ax = mpl.subplot(3, 1, 3) mpl.title("time: 0.0 s") wavefield = mpl.imshow(background, extent=area, cmap=mpl.cm.gray_r, vmin=-0.005, vmax=0.005) mpl.points(stations, "^b", size=8) mpl.text(750000, 20000, "Crust") mpl.text(740000, 100000, "Mantle") fig.text(0.82, 0.33, "Seismometer 2") fig.text(0.16, 0.33, "Seismometer 1") mpl.ylim(area[2:][::-1]) mpl.xlabel("x (km)") mpl.ylabel("z (km)") mpl.m2km() times = np.linspace(0, dt * maxit, maxit) # This function updates the plot every few timesteps def animate(i): t, u, seismogram = simulation.next() mpl.title("time: %0.1f s" % (times[t])) wavefield.set_array((background + u)[::-1]) seismogram1.set_data(times[: t + 1], seismogram[0][: t + 1]) seismogram2.set_data(times[: t + 1], seismogram[1][: t + 1]) return wavefield, seismogram1, seismogram2
""" Gridding: Load a Surfer ASCII grid file """ from fatiando import datasets, gridder from fatiando.vis import mpl # Fetching Bouguer anomaly model data (Surfer ASCII grid file)" # Will download the archive and save it with the default name archive = datasets.fetch_bouguer_alps_egm() # Load the GRD file and convert in three numpy-arrays (x, y, bouguer) x, y, bouguer, shape = gridder.load_surfer(archive, fmt="ascii") mpl.figure() mpl.axis("scaled") mpl.title("Data loaded from a Surfer ASCII grid file") mpl.contourf(y, x, bouguer, shape, 15, cmap=mpl.cm.RdBu_r) cb = mpl.colorbar() cb.set_label("mGal") mpl.xlabel("y points to East (km)") mpl.ylabel("x points to North (km)") mpl.m2km() mpl.show()
# 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(gm.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 data = [gm.harvester.Gz(xp, yp, zp, gz)] # Make the seed seeds = gm.harvester.sow([[500, 500, 450, {'density': 1000}]], mesh) # Run the inversioin estimate, predicted = gm.harvester.harvest(data, seeds, mesh,
mpl.points(src, '*y') initial = mpl.pick_points(area, mpl.gca(), marker='*', color='b') if len(initial) > 1: print "Don't be greedy! Pick only one point" sys.exit() estimate = solver.config('levmarq', initial=initial[0]).fit().estimate_ mpl.figure(figsize=(10, 4)) mpl.subplot(1, 2, 1) mpl.title('Epicenter + %d recording stations' % (len(recs))) mpl.axis('scaled') mpl.points(src, '*y', label="True") mpl.points(recs, '^r', label="Stations") mpl.points(initial, '*b', label="Initial") mpl.points([estimate], '*g', label="Estimate") mpl.set_area(area) mpl.legend(loc='lower right', shadow=True, numpoints=1, prop={'size': 12}) mpl.xlabel("X") mpl.ylabel("Y") ax = mpl.subplot(1, 2, 2) mpl.title('Travel-time residuals + error bars') s = numpy.arange(len(traveltime)) + 1 width = 0.3 mpl.bar(s - width, traveltime, width, color='g', label="Observed", yerr=error) mpl.bar(s, solver.predicted(), width, color='r', label="Predicted") ax.set_xticks(s) mpl.legend(loc='upper right', shadow=True, prop={'size': 12}) mpl.xlabel("Station number") mpl.ylabel("Travel-time residual") mpl.show()
initial = mpl.pick_points(area, mpl.gca(), marker='*', color='b') if len(initial) > 1: print "Don't be greedy! Pick only one point" sys.exit() estimate = solver.config('levmarq', initial=initial[0]).fit().estimate_ mpl.figure(figsize=(10,4)) mpl.subplot(1, 2, 1) mpl.title('Epicenter + %d recording stations' % (len(recs))) mpl.axis('scaled') mpl.points(src, '*y', label="True") mpl.points(recs, '^r', label="Stations") mpl.points(initial, '*b', label="Initial") mpl.points([estimate], '*g', label="Estimate") mpl.set_area(area) mpl.legend(loc='lower right', shadow=True, numpoints=1, prop={'size':12}) mpl.xlabel("X") mpl.ylabel("Y") ax = mpl.subplot(1, 2, 2) mpl.title('Travel-time residuals + error bars') s = numpy.arange(len(traveltime)) + 1 width = 0.3 mpl.bar(s - width, traveltime, width, color='g', label="Observed", yerr=error) mpl.bar(s, solver.predicted(), width, color='r', label="Predicted") ax.set_xticks(s) mpl.legend(loc='upper right', shadow=True, prop={'size':12}) mpl.xlabel("Station number") mpl.ylabel("Travel-time residual") mpl.show()
utils.contaminate(gravmag.prism.gxx(x, y, z, model), noise), utils.contaminate(gravmag.prism.gxy(x, y, z, model), noise), utils.contaminate(gravmag.prism.gxz(x, y, z, model), noise), utils.contaminate(gravmag.prism.gyy(x, y, z, model), noise), utils.contaminate(gravmag.prism.gyz(x, y, z, model), noise), utils.contaminate(gravmag.prism.gzz(x, y, z, model), noise) ] with open('data.txt', 'w') as f: f.write(logger.header(comment='#')) f.write("# Noise corrupted gz and tensor components:\n") f.write("# noise = %g Eotvos\n" % (noise)) f.write("# noise = %g mGal\n" % (noisegz)) f.write("# coordinates are in meters\n") f.write("# gz in mGal and tensor in Eotvos\n") f.write("# x y z height gz gxx gxy gxz gyy gyz gzz\n") numpy.savetxt(f, numpy.transpose(data)) # Show it mpl.figure(figsize=(10, 9)) names = "z height gz gxx gxy gxz gyy gyz gzz".split() for i, comp in enumerate(data[2:]): mpl.subplot(3, 3, i + 1) mpl.axis('scaled') mpl.title(names[i]) levels = mpl.contourf(y * 0.001, x * 0.001, comp, shape, 8) mpl.contour(y * 0.001, x * 0.001, comp, shape, levels) if i == 3: mpl.ylabel('North = x (km)') if i == 7: mpl.xlabel('East = y (km)') mpl.show()
xp, yp, zp = gridder.regular(area, shape, z=-1) noise = 0.1 # 0.1 mGal noise gz = utils.contaminate(polyprism.gz(xp, yp, zp, model), noise) # Create a mesh mesh = PrismMesh(bounds, (25, 50, 50)) # Wrap the data so that harvester can read it data = [harvester.Gz(xp, yp, zp, gz)] # Plot the data and pick the location of the seeds mpl.figure() mpl.suptitle("Pick the seeds (polygon is the true source)") mpl.axis("scaled") levels = mpl.contourf(yp, xp, gz, shape, 12) mpl.colorbar() mpl.polygon(model[0], xy2ne=True) mpl.xlabel("Horizontal coordinate y (km)") mpl.ylabel("Horizontal coordinate x (km)") seedx, seedy = mpl.pick_points(area, mpl.gca(), xy2ne=True).T # Set the right density and depth locations = [[x, y, 1500, {"density": 1000}] for x, y in zip(seedx, seedy)] mpl.show() # Make the seed and set the compactness regularizing parameter mu seeds = harvester.sow(locations, mesh) # Run the inversion estimate, predicted = harvester.harvest(data, seeds, mesh, compactness=0.05, threshold=0.0005) # Put the estimated density values in the mesh mesh.addprop("density", estimate["density"]) # Plot the adjustment and the result mpl.figure() mpl.title("True: color | Predicted: contour") mpl.axis("scaled")
log.info("Generating synthetic data") verts = [(10000, 1.), (90000, 1.), (90000, 7000), (10000, 3330)] model = mesher.Polygon(verts, {'density':-100}) xp = numpy.arange(0., 100000., 1000.) zp = numpy.zeros_like(xp) gz = utils.contaminate(gravmag.talwani.gz(xp, zp, [model]), 0.5) log.info("Preparing for the inversion") solver = inversion.gradient.levmarq(initial=(9000, 500)) estimate, residuals = gravmag.basin2d.trapezoidal(xp, zp, gz, verts[0:2], -100, solver) mpl.figure() mpl.subplot(2, 1, 1) mpl.title("Gravity anomaly") mpl.plot(xp, gz, 'ok', label='Observed') mpl.plot(xp, gz - residuals, '-r', linewidth=2, label='Predicted') mpl.legend(loc='lower left', numpoints=1) mpl.ylabel("mGal") mpl.xlim(0, 100000) mpl.subplot(2, 1, 2) mpl.polygon(estimate, 'o-r', linewidth=2, fill='r', alpha=0.3, label='Estimated') mpl.polygon(model, '--k', linewidth=2, label='True') mpl.legend(loc='lower left', numpoints=1) mpl.xlabel("X") mpl.ylabel("Z") mpl.set_area((0, 100000, 10000, -500)) mpl.show()
stations = [[50000, 0]] # x, z coordinate of the seismometer snapshot = int(0.5 / dt) # Plot a snapshot of the simulation every 0.5 seconds simulation = wavefd.elastic_sh(mu, density, area, dt, maxit, sources, stations, snapshot, padding=50, taper=0.01) # This part makes an animation using matplotlibs animation API fig = mpl.figure(figsize=(14, 5)) ax = mpl.subplot(1, 2, 2) mpl.title('Wavefield') # Start with everything zero and grab the plot so that it can be updated later wavefield_plt = mpl.imshow(np.zeros(shape), extent=area, vmin=-10 ** (-5), vmax=10 ** (-5), cmap=mpl.cm.gray_r) mpl.points(stations, '^b') mpl.xlim(area[:2]) mpl.ylim(area[2:][::-1]) mpl.xlabel('x (km)') mpl.ylabel('z (km)') mpl.subplot(1, 2, 1) seismogram_plt, = mpl.plot([], [], '-k') mpl.xlim(0, duration) mpl.ylim(-10 ** (-4), 10 ** (-4)) mpl.xlabel('time (s)') mpl.ylabel('Amplitude') times = np.linspace(0, duration, maxit) # Update the plot everytime the simulation yields def animate(i): """ Grab the iteration number, displacment panel and seismograms """
""" GravMag: 2D forward modeling with polygons """ import numpy from fatiando import utils, mesher from fatiando.gravmag import talwani from fatiando.vis import mpl # Notice that the last two number are switched. # This way, the z axis in the plots points down. area = (-5000, 5000, 5000, 0) axes = mpl.figure().gca() mpl.xlabel("X") mpl.ylabel("Z") mpl.axis('scaled') polygons = [mesher.Polygon(mpl.draw_polygon(area, axes), {'density': 500})] xp = numpy.arange(-4500, 4500, 100) zp = numpy.zeros_like(xp) gz = talwani.gz(xp, zp, polygons) mpl.figure() mpl.axis('scaled') mpl.subplot(2, 1, 1) mpl.title(r"Gravity anomaly produced by the model") mpl.plot(xp, gz, '-k', linewidth=2) mpl.ylabel("mGal") mpl.xlim(-5000, 5000) mpl.subplot(2, 1, 2) mpl.polygon(polygons[0], 'o-k', linewidth=2, fill='k', alpha=0.5) mpl.xlabel("X")
xp, yp, zp = gridder.regular(area, shape, z=-1) noise = 0.1 # 0.1 mGal noise gz = utils.contaminate(gm.polyprism.gz(xp, yp, zp, model), noise) # Create a mesh mesh = PrismMesh(bounds, (25, 50, 50)) # Wrap the data so that harvester can read it data = [gm.harvester.Gz(xp, yp, zp, gz)] # Plot the data and pick the location of the seeds mpl.figure() mpl.suptitle("Pick the seeds (polygon is the true source)") mpl.axis('scaled') levels = mpl.contourf(yp, xp, gz, shape, 12) mpl.colorbar() mpl.polygon(model[0], xy2ne=True) mpl.xlabel('Horizontal coordinate y (km)') mpl.ylabel('Horizontal coordinate x (km)') seedx, seedy = mpl.pick_points(area, mpl.gca(), xy2ne=True).T # Set the right density and depth locations = [[x, y, 1500, {'density': 1000}] for x, y in zip(seedx, seedy)] mpl.show() # Make the seed and set the compactness regularizing parameter mu seeds = gm.harvester.sow(locations, mesh) # Run the inversion estimate, predicted = gm.harvester.harvest(data, seeds, mesh, compactness=0.05, threshold=0.0005) # Put the estimated density values in the mesh mesh.addprop('density', estimate['density'])
""" Seismic: Invert vertical seismic profile (VSP) traveltimes for the velocity of a layered model. """ import numpy from fatiando import utils from fatiando.seismic.profile import layered_straight_ray, LayeredStraight from fatiando.inversion.regularization import Damping from fatiando.vis import mpl # The limits in velocity and depths, respectively area = (0, 10000, 0, 100) vmin, vmax, zmin, zmax = area # Use the interactive functions of mpl to draw a layered model figure = mpl.figure() mpl.xlabel("Velocity (m/s)") mpl.ylabel("Depth (m)") thickness, velocity = mpl.draw_layers(area, figure.gca()) # Make some synthetic noise-corrupted travel-time data zp = numpy.arange(zmin + 0.5, zmax, 0.5) tts, error = utils.contaminate(layered_straight_ray(thickness, velocity, zp), 0.02, percent=True, return_stddev=True) # Make the solver and run the inversion using damping regularization # (assumes known thicknesses of the layers) solver = (LayeredStraight(tts, zp, thickness) + 0.1 * Damping(len(thickness))).fit() velocity_ = solver.estimate_ # Plot the results
0.02, percent=True, return_stddev=True) # Assume that the thicknesses are unknown. In this case, use a mesh of many # thin layers and invert for each slowness thick = 10. mesh = [thick]*int(sum(thickness)/thick) solver = (LayeredStraight(tts, zp, mesh) + 5*Smoothness1D(len(mesh))).fit() velocity_ = solver.estimate_ mpl.figure(figsize=(12,5)) mpl.subplot(1, 2, 1) mpl.grid() mpl.title("Vertical seismic profile") mpl.plot(tts, zp, 'ok', label='Observed') mpl.plot(solver.predicted(), zp, '-r', linewidth=3, label='Predicted') mpl.legend(loc='upper right', numpoints=1) mpl.xlabel("Travel-time (s)") mpl.ylabel("Z (m)") mpl.ylim(sum(mesh), 0) mpl.subplot(1, 2, 2) mpl.grid() mpl.title("True velocity + smooth estimate") mpl.layers(mesh, velocity_, '.-k', linewidth=2, label='Estimated') mpl.layers(thickness, velocity, '--b', linewidth=2, label='True') mpl.ylim(sum(mesh), 0) mpl.xlim(0, 10000) mpl.legend(loc='upper right', numpoints=1) mpl.xlabel("Velocity (m/s)") mpl.ylabel("Z (m)") mpl.show()
duration = 2.5 maxit = int(duration/dt) stations = [[75*ds, 125*ds]] # x, z coordinate of the seismometer snapshots = 3 # every 3 iterations plots one simulation = wavefd.scalar(velocity, area, dt, maxit, sources, stations, snapshots) # This part makes an animation using matplotlibs animation API background = (velocity-4000)*10**-1 fig = mpl.figure(figsize=(8, 6)) mpl.subplots_adjust(right=0.98, left=0.11, hspace=0.5, top=0.93) mpl.subplot2grid((4, 3), (0,0), colspan=3,rowspan=3) wavefield = mpl.imshow(np.zeros_like(velocity), extent=area, cmap=mpl.cm.gray_r, vmin=-1000, vmax=1000) mpl.points(stations, '^b', size=8) mpl.ylim(area[2:][::-1]) mpl.xlabel('x (km)') mpl.ylabel('z (km)') mpl.m2km() mpl.subplot2grid((4,3), (3,0), colspan=3) seismogram1, = mpl.plot([],[],'-k') mpl.xlim(0, duration) mpl.ylim(-200, 200) mpl.ylabel('Amplitude') times = np.linspace(0, dt*maxit, maxit) # This function updates the plot every few timesteps def animate(i): t, u, seismogram = simulation.next() seismogram1.set_data(times[:t+1], seismogram[0][:t+1]) wavefield.set_array(background[::-1]+u[::-1]) return wavefield, seismogram1 anim = animation.FuncAnimation(fig, animate, frames=maxit/snapshots, interval=1)
""" Gridding: Load a Surfer ASCII grid file """ from fatiando import datasets, gridder from fatiando.vis import mpl # Fetching Bouguer anomaly model data (Surfer ASCII grid file)" # Will download the archive and save it with the default name archive = datasets.fetch_bouguer_alps_egm() # Load the GRD file and convert in three numpy-arrays (y, x, bouguer) y, x, bouguer, shape = gridder.load_surfer(archive, fmt='ascii') mpl.figure() mpl.axis('scaled') mpl.title("Data loaded from a Surfer ASCII grid file") mpl.contourf(y, x, bouguer, shape, 15) cb = mpl.colorbar() cb.set_label('mGal') mpl.xlabel('y points to East (km)') mpl.ylabel('x points to North (km)') mpl.m2km() mpl.show()
stations = [[2200+i*dx, 0] for i in range(220)] # x, z coordinate of the seismometers snapshot = int(0.004/dt) # Plot a snapshot of the simulation every 4 miliseconds print "dt for simulation is ", dt print "max iteration for simulation is ", maxit print "duration for simulation is ", duration simulation = wavefd.elastic_psv(lamb, mu, density, area, dt, maxit, sources, stations, snapshot, padding=50, taper=0.01) # This part makes an animation using matplotlibs animation API fig = mpl.figure(figsize=(12, 5)) # Start with everything zero and grab the plot so that it can be updated later mpl.imshow(pvel[::-1], extent=area, alpha=0.25) wavefield = mpl.imshow(np.zeros(shape), extent=area, vmin=-10**-7, vmax=10**-7, alpha=0.75, cmap=mpl.cm.gray_r) mpl.points(stations, '.k') mpl.ylim(area[2:][::-1]) mpl.xlabel('x (km)') mpl.ylabel('z (km)') mpl.m2km() times = np.linspace(0, maxit*dt, maxit) # the only way for getting the feedback response of the seimograms global seismograms # This function updates the plot every few timesteps def animate(i): # Simulation will yield panels corresponding to P and S waves because # xz2ps=True t, ux, uz, xcomp, zcomp = simulation.next() mpl.title('time: %0.3f s' % (times[t])) # wavefield.set_array((p + s)[::-1]) wavefield.set_data(uz[::-1]) global seismograms
""" Gridding: Load a Surfer ASCII grid file """ from fatiando import datasets, gridder from fatiando.vis import mpl # Fetching Bouguer anomaly model data (Surfer ASCII grid file)" # Will download the archive and save it with the default name archive = datasets.fetch_bouguer_alps_egm() # Load the GRD file and convert in three numpy-arrays (x, y, bouguer) x, y, bouguer, shape = gridder.load_surfer(archive, fmt='ascii') mpl.figure() mpl.axis('scaled') mpl.title("Data loaded from a Surfer ASCII grid file") mpl.contourf(y, x, bouguer, shape, 15, cmap=mpl.cm.RdBu_r) cb = mpl.colorbar() cb.set_label('mGal') mpl.xlabel('y points to East (km)') mpl.ylabel('x points to North (km)') mpl.m2km() mpl.show()
from fatiando import utils from fatiando.geothermal.climsig import linear, SingleChange from fatiando.vis import mpl # Generating synthetic data amp = 5.43 age = 78.2 # along a well at these depths zp = numpy.arange(0, 100, 1) temp, error = utils.contaminate(linear(amp, age, zp), 0.02, percent=True, return_stddev=True) # Preparing for the inversion data = SingleChange(temp, zp, mode='linear').config('levmarq', initial=[1, 1]) amp_, age_ = data.fit().estimate_ print "Linear change in temperature" print " true: amp=%.3f age=%.3f" % (amp, age) print " estimated: amp=%.3f age=%.3f" % (amp_, age_) mpl.figure(figsize=(4, 5)) mpl.title("Residual well temperature") mpl.plot(temp, zp, 'ok', label='Observed') mpl.plot(data.predicted(), zp, '--r', linewidth=3, label='Predicted') mpl.legend(loc='lower right', numpoints=1) mpl.xlabel("Temperature (C)") mpl.ylabel("Z (m)") mpl.ylim(100, 0) mpl.show()
gxy = utils.contaminate(gm.prism.gxy(xp, yp, zp, model), noise) gxz = utils.contaminate(gm.prism.gxz(xp, yp, zp, model), noise) gyy = utils.contaminate(gm.prism.gyy(xp, yp, zp, model), noise) gyz = utils.contaminate(gm.prism.gyz(xp, yp, zp, model), noise) gzz = utils.contaminate(gm.prism.gzz(xp, yp, zp, model), noise) tensor = [gxx, gxy, gxz, gyy, gyz, gzz] titles = ['gxx', 'gxy', 'gxz', 'gyy', 'gyz', 'gzz'] # plot the data mpl.figure() for i in xrange(len(tensor)): mpl.subplot(2, 3, i + 1) mpl.title(titles[i]) mpl.axis('scaled') levels = mpl.contourf(yp, xp, tensor[i], shape, 30) mpl.colorbar() mpl.xlabel('y (km)') mpl.ylabel('x (km)') mpl.m2km() mpl.show() # Inversion setup # Create a mesh mesh = PrismMesh(bounds, (30, 30, 30)) # Wrap the data so that harvester can use it data = [ gm.harvester.Gxx(xp, yp, zp, gxx), gm.harvester.Gxy(xp, yp, zp, gxy), gm.harvester.Gxz(xp, yp, zp, gxz), gm.harvester.Gyy(xp, yp, zp, gyy), gm.harvester.Gyz(xp, yp, zp, gyz), gm.harvester.Gzz(xp, yp, zp, gzz)
mesher.Prism(-4000, -3000, -4000, -3000, 0, 2000, {'magnetization': 2}), # a scalar magnetization means only induced mesher.Prism(-1000, 1000, -1000, 1000, 0, 2000, {'magnetization': 1}), # This prism will have magnetization in a different direction mesher.Prism(2000, 4000, 3000, 4000, 0, 2000, {'magnetization': utils.ang2vec(3, -10, 45)})] # induced + remanent # Create a regular grid at 100m height shape = (200, 200) area = bounds[:4] xp, yp, zp = gridder.regular(area, shape, z=-500) # Calculate the anomaly for a given regional field tf = prism.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() # Show the prisms myv.figure() myv.prisms(model, 'magnetization') myv.axes(myv.outline(bounds), ranges=[i * 0.001 for i in bounds]) myv.wall_north(bounds) myv.wall_bottom(bounds) myv.show()
xp, yp, zp = gridder.regular(area, shape, z=-1) noise = 0.1 # 0.1 mGal noise gz = utils.contaminate(polyprism.gz(xp, yp, zp, model), noise) # Create a mesh mesh = PrismMesh(bounds, (25, 50, 50)) # Wrap the data so that harvester can read it data = [harvester.Gz(xp, yp, zp, gz)] # Plot the data and pick the location of the seeds mpl.figure() mpl.suptitle("Pick the seeds (polygon is the true source)") mpl.axis('scaled') levels = mpl.contourf(yp, xp, gz, shape, 12) mpl.colorbar() mpl.polygon(model[0], xy2ne=True) mpl.xlabel('Horizontal coordinate y (km)') mpl.ylabel('Horizontal coordinate x (km)') seedx, seedy = mpl.pick_points(area, mpl.gca(), xy2ne=True).T # Set the right density and depth locations = [[x, y, 1500, {'density': 1000}] for x, y in zip(seedx, seedy)] mpl.show() # Make the seed and set the compactness regularizing parameter mu seeds = harvester.sow(locations, mesh) # Run the inversion estimate, predicted = harvester.harvest(data, seeds, mesh, compactness=0.05, threshold=0.0005) # Put the estimated density values in the mesh mesh.addprop('density', estimate['density']) # Plot the adjustment and the result mpl.figure() mpl.title("True: color | Predicted: contour")
# Calculate and print the standard deviation of the residuals # Should be close to the data error if the inversion was able to fit the data residuals = tomo.residuals() print "Assumed error: %g" % (error) print "Standard deviation of residuals: %g" % (np.std(residuals)) mpl.figure(figsize=(14, 5)) mpl.subplot(1, 2, 1) mpl.axis('scaled') mpl.title('Vp model') mpl.squaremesh(model, prop='vp', cmap=mpl.cm.seismic) cb = mpl.colorbar() cb.set_label('Velocity') mpl.points(src_loc, '*y', label="Sources") mpl.points(rec_loc, '^r', label="Receivers") mpl.legend(loc='lower left', shadow=True, numpoints=1, prop={'size': 10}) mpl.m2km() mpl.subplot(1, 2, 2) mpl.axis('scaled') mpl.title('Tomography result') mpl.squaremesh(mesh, prop='vp', vmin=4000, vmax=10000, cmap=mpl.cm.seismic) cb = mpl.colorbar() cb.set_label('Velocity') mpl.m2km() mpl.figure() mpl.grid() mpl.title('Residuals (data with %.4f s error)' % (error)) mpl.hist(residuals, color='gray', bins=10) mpl.xlabel("seconds") mpl.show()
15, interp=True, color='r', label='Observed', linewidth=2.0) mpl.contour(y, x, solver.predicted(), (50, 50), nlevels, interp=True, color='b', label='Predicted', style='dashed', linewidth=2.0) mpl.legend(loc='upper left', shadow=True, prop={'size': 13}) mpl.xlabel('East y (m)', fontsize=14) mpl.ylabel('North x (m)', fontsize=14) mpl.subplot(1, 2, 2) residuals_mean = numpy.mean(solver.residuals()) residuals_std = numpy.std(solver.residuals()) # Each residual is subtracted from the mean and the resulting # difference is divided by the standard deviation s = (solver.residuals() - residuals_mean) / residuals_std mpl.hist(s, bins=21, range=None, normed=True, weights=None, cumulative=False, bottom=None, histtype='bar',