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
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 seismograms = zcomp
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()
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[0].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()
""" 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")
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']) ax.set_ylim(0, 70)
# fetch sample SEGY data, near-offset marmousi data url = "http://dl.dropboxusercontent.com/" \ "s/i287ci4ww3w7gdt/marmousi_nearoffset.segy" urllib.urlretrieve(url, 'marmousi_nearoffset.segy') # We'll use the ObsPy library to load the SEGY data" segyfile = segy.readSEGY('marmousi_nearoffset.segy') # turn ObsPy Stream in a matrix of traces # first dimension time, second dimension traces ntraces = len(segyfile.traces) nsamples = len(segyfile.traces[0].data) mtraces = np.zeros((nsamples, ntraces)) i = 0 for tr in segyfile.traces: mtraces[:, i] = tr.data[:] i += 1 # make plots mpl.figure() mpl.subplot(2, 1, 1) mpl.ylabel('time (seconds)') mpl.title("Seismic wiggle plot", fontsize=13, family='sans-serif', weight='bold') # plot using wiggle mpl.seismic_wiggle(mtraces, scale=10**-4) mpl.subplot(2, 1, 2) mpl.ylabel('time (seconds)') mpl.title("Seismic image plot", fontsize=13, family='sans-serif', weight='bold') # plot using image mpl.seismic_image(mtraces, aspect='auto') mpl.show()
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() # Fit using many different solvers levmarq = [e for e in solver.levmarq(initial=initial[0], iterate=True)] steepest = [e for e in solver.steepest(initial=initial[0], iterate=True)] newton = [e for e in solver.newton(initial=initial[0], iterate=True)] ACO_R = [e for e in solver.acor(bounds=area, maxit=100, iterate=True)] # Make a map of the objective function shape = (100, 100) xs, ys = gridder.regular(area, shape) obj = [solver.value(numpy.array([x, y])) for x, y in zip(xs, ys)] mpl.figure() mpl.title('Epicenter + %d recording stations' % (len(recs))) mpl.axis('scaled') mpl.contourf(xs, ys, obj, shape, 60) mpl.points(recs, '^r') mpl.points(initial, '*w') mpl.points(levmarq, '.-k', label="Levemeber-Marquardt") mpl.points(newton, '.-r', label="Newton") mpl.points(steepest, '.-m', label="Steepest descent") mpl.points(ACO_R, '.-c', label="Ant Colony") mpl.points(src, '*y') mpl.set_area(area) mpl.legend(loc='lower right', shadow=True, numpoints=1, prop={'size': 12}) mpl.xlabel("X") mpl.ylabel("Y") mpl.show()
zp = numpy.arange(0, 100, 1) temp, error = utils.contaminate(climsig.abrupt(amp, age, zp), 0.02, percent=True, return_stddev=True) # Preparing for the inversion assuming that the change was LINEAR p, residuals = climsig.ilinear(temp, zp) est_amp, est_age = p mpl.figure(figsize=(12,5)) mpl.subplot(1, 2, 1) mpl.title("Climate signal\n(true is abrupt but inverted using linear)") 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']) ax.set_ylim(0, 150)
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
duration = 250 maxit = int(duration / dt) stations = [[100000, 0], [700000, 0]] snapshots = int(1.0 / dt) simulation = wavefd.elastic_sh(mu, density, area, dt, maxit, sources, stations, snapshots, padding=70, taper=0.005) # This part makes an animation using matplotlibs animation API background = svel * 5 * 10 ** -7 fig = mpl.figure(figsize=(10, 8)) mpl.subplots_adjust(right=0.98, left=0.11, hspace=0.3, top=0.93) mpl.subplot(3, 1, 1) mpl.title("Seismogram 1") seismogram1, = mpl.plot([], [], "-k") mpl.xlim(0, duration) mpl.ylim(-0.1, 0.1) mpl.ylabel("Amplitude") 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])
""" 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()
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()
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()
twtvmodel = np.zeros((len(twt), dnx)) # velocity model in time and discretized for i in xrange(0, nx, disc): # set the time re-sample velocity model twtvmodel[:, int(i/disc)] = np.interp(twt, twti[:, i], vmodel[:, i]) zimp = np.ones(twtvmodel.shape)*1000.*twtvmodel # create impedance z = rho*v rc = (zimp[1:]-zimp[:-1])/(zimp[1:]+zimp[:-1]) # calculate reflection coefs fig = mpl.figure(figsize=(11, 7)) # plottings mpl.subplots_adjust(right=0.98, left=0.11, hspace=0.4, top=0.93, bottom=0.13) mpl.subplot2grid((3, 4), (0, 0), colspan=4) # plot rc model mpl.title("Zero-offset section reflection coefficients", fontsize=13, family='sans-serif', weight='bold') rcs = utils.matrix2stream(rc.transpose(), header={'delta': dt}) mpl.seismic_wiggle(rcs, normalize=True, scale=1.5, ranges=[0, nx]) # rc model wavelet = signal.ricker(255, 1/(2*f*dt)) # create wavelet samples = signal.filtfilt(wavelet, np.ones(len(wavelet)), rc, axis=0, padlen=len(twt)-2) # convolve rc*wavelet mpl.ylabel('twt (s)') mpl.subplot2grid((3, 4), (1, 0), colspan=4) # plot zero-offset traces traces = utils.matrix2stream(samples.transpose(), header={'delta': dt}) mpl.seismic_image(traces, cmap=mpl.pyplot.cm.jet, aspect='auto', ranges=[0, nx]) mpl.seismic_wiggle(traces, ranges=[0, nx], normalize=True) mpl.ylabel('twt (s)') mpl.title("Zero-offset section amplitude", fontsize=13, family='sans-serif', weight='bold') ax = mpl.subplot2grid((3, 4), (2, 0), colspan=4) # plot vmodel mpl.imshow(vmodel, extent=[0, nx, nz*ds, 0], cmap=mpl.pyplot.cm.bwr, aspect='auto', origin='upper') ax.autoscale(False) mpl.ylabel('depth (m)') stations = [[i, 0] for i in xrange(0, nx, disc)] mpl.points(stations, '^k', size=7) # zero-offset station points mpl.text(250, 120, '2900 m/s') # model velocities
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()
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()
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 mpl.figure(figsize=(12, 5)) mpl.subplot(1, 2, 1)
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
fig = mpl.figure(figsize=(11, 7)) # plottings mpl.subplots_adjust(right=0.98, left=0.11, hspace=0.4, top=0.93, bottom=0.13) mpl.subplot2grid((3, 4), (0, 0), colspan=4) # plot rc model mpl.title("Zero-offset section reflection coefficients", fontsize=13, family='sans-serif', weight='bold') rcs = utils.matrix2stream(rc.transpose(), header={'delta': dt}) mpl.seismic_wiggle(rcs, normalize=True, scale=1.5, ranges=[0, nx]) # rc model wavelet = signal.ricker(255, 1 / (2 * f * dt)) # create wavelet samples = signal.filtfilt(wavelet, np.ones(len(wavelet)), rc, axis=0, padlen=len(twt) - 2) # convolve rc*wavelet mpl.ylabel('twt (s)') mpl.subplot2grid((3, 4), (1, 0), colspan=4) # plot zero-offset traces traces = utils.matrix2stream(samples.transpose(), header={'delta': dt}) mpl.seismic_image(traces, cmap=mpl.pyplot.cm.jet, aspect='auto', ranges=[0, nx]) mpl.seismic_wiggle(traces, ranges=[0, nx], normalize=True) mpl.ylabel('twt (s)') mpl.title("Zero-offset section amplitude", fontsize=13, family='sans-serif', weight='bold') ax = mpl.subplot2grid((3, 4), (2, 0), colspan=4) # plot vmodel mpl.imshow(vmodel, extent=[0, nx, nz * ds, 0],
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()
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") levels = mpl.contourf(yp, xp, gz, shape, 12)
print "dt for simulation is ", dt print "max iteration for simulation is ", maxit print "duration for simulation is ", duration # TODO implement 2D esg version with abs condition simulation = wavefd.scalar3_esg(pvel, 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[0][::-1], extent=area[:4], alpha=0.25) wavefield = mpl.imshow(np.zeros(shape[1:]), extent=area[:4], vmin=-10**-7, vmax=10**-7, alpha=0.75, cmap=mpl.cm.gray_r) mpl.points([ stations[i][:2] for i in range(len(stations))], '.k') mpl.ylim(area[2:4][::-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): # t, pressure, seismograms t, u, zcomp = simulation.next() mpl.title('time: %0.3f s' % (times[t])) # wavefield.set_array((p + s)[::-1]) wavefield.set_data(u[0][::-1]) global seismograms seismograms = zcomp return wavefield, seismograms
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() # Fit using many different solvers levmarq = [e for e in solver.levmarq(initial=initial[0], iterate=True)] steepest = [e for e in solver.steepest(initial=initial[0], iterate=True)] newton = [e for e in solver.newton(initial=initial[0], iterate=True)] ACO_R = [e for e in solver.acor(bounds=area, maxit=100, iterate=True)] # Make a map of the objective function shape = (100, 100) xs, ys = gridder.regular(area, shape) obj = [solver.value(numpy.array([x, y])) for x, y in zip(xs, ys)] mpl.figure() mpl.title('Epicenter + %d recording stations' % (len(recs))) mpl.axis('scaled') mpl.contourf(xs, ys, obj, shape, 60) mpl.points(recs, '^r') mpl.points(initial, '*w') mpl.points(levmarq, '.-k', label="Levemeber-Marquardt") mpl.points(newton, '.-r', label="Newton") mpl.points(steepest, '.-m', label="Steepest descent") mpl.points(ACO_R, '.-c', label="Ant Colony") mpl.points(src, '*y') mpl.set_area(area) mpl.legend(loc='lower right', shadow=True, numpoints=1, prop={'size':12}) mpl.xlabel("X") mpl.ylabel("Y") mpl.show()
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) # Put the estimated density values in the mesh
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']) # Plot the adjustment and the result
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 mpl.figure(figsize=(12, 5))
stations, snapshots, padding=70, taper=0.005, xz2ps=True) # This part makes an animation using matplotlibs animation API background = 10**-5 * ((density - density.min()) / density.max()) fig = mpl.figure(figsize=(10, 8)) mpl.subplots_adjust(right=0.98, left=0.11, hspace=0.3, top=0.93) mpl.subplot(3, 1, 1) mpl.title('x seismogram') xseismogram, = mpl.plot([], [], '-k') mpl.xlim(0, duration) mpl.ylim(-0.05, 0.05) mpl.ylabel('Amplitude') mpl.subplot(3, 1, 2) mpl.title('z seismogram') zseismogram, = mpl.plot([], [], '-k') mpl.xlim(0, duration) mpl.ylim(-0.05, 0.05) 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.00001, vmax=0.00001) mpl.points(stations, '^b', size=8) mpl.text(500000, 20000, 'Crust')
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) mpl.show()
""" 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()
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 seeds = gm.harvester.sow([
""" 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()
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) mpl.xlabel("z", fontsize=14)
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) ]
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()
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',