EMSC Week 11 - A detailed look at the depth-age relationship for the seafloor.#
Extra - what happens if we try to fit the data ?
We have a theoretical relationship that we have been trying to see in the data
We can always try to see what happens if we fit the data to find \(d_0\) and \(\alpha\)
First a grid at fine resolution#
import stripy
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
even_mesh = stripy.spherical_meshes.icosahedral_mesh(include_face_points=True, tree=True, refinement_levels=6)
number_of_mesh_points = even_mesh.npoints
latitudes_in_radians = even_mesh.lats
latitudes_in_degrees = np.degrees(latitudes_in_radians)
longitudes_in_radians = even_mesh.lons
longitudes_in_degrees = np.degrees(longitudes_in_radians)%360.0 - 180.0
Find the age and depth values on these points#
As before, we interpolate each of our datasets to the same set of grid points. First we need to define the interpolation routine again.
def map_raster_to_mesh(mesh, latlongrid):
raster = latlongrid.T
latitudes_in_radians = mesh.lats
longitudes_in_radians = mesh.lons
latitudes_in_degrees = np.degrees(latitudes_in_radians)
longitudes_in_degrees = np.degrees(longitudes_in_radians)%360.0 - 180.0
dlons = np.mod(longitudes_in_degrees+180.0, 360.0)
dlats = np.mod(latitudes_in_degrees+90, 180.0)
ilons = raster.shape[0] * dlons / 360.0
ilats = raster.shape[1] * dlats / 180.0
icoords = np.array((ilons, ilats))
from scipy import ndimage
mvals = ndimage.map_coordinates(raster, icoords , order=3, mode='nearest').astype(float)
return mvals
Interpolate age data to fine, triangular grid.#
(You can plot the results as before to see that you have not made a mistake)
plt.figure(figsize=(6, 6))
ax = plt.subplot(111, projection=ccrs.Orthographic(central_longitude=0.1))
ax.add_feature(coastline, edgecolor="black", linewidth=0.5, zorder=3)
plt.scatter(longitudes_in_degrees, latitudes_in_degrees, c=meshages, cmap="RdYlBu",
vmin=0, vmax=250, s=5,
transform=ccrs.Geodetic())
import xarray
age_dataset = "data/age.3.6.nc"
age_data = xarray.open_dataset(age_dataset)
subs_data = age_data.sel(x=slice(-180,180, 1), y=slice(-90, 90, 1))
lons = subs_data.coords.get('x')
lats = subs_data.coords.get('y')
vals = subs_data['z']
x,y = np.meshgrid(lons.data, lats.data)
age = vals.data / 100.0
age[np.isnan(age)] = -1.0
meshages = map_raster_to_mesh(even_mesh, age)
(left, bottom, right, top) = (-180, -90, 180, 90)
map_extent = ( left, right, bottom, top)
etopo_dataset = "http://thredds.socib.es/thredds/dodsC/ancillary_data/bathymetry/ETOPO1_Bed_g_gmt4.nc"
etopo_data = xarray.open_dataset(etopo_dataset)
subs_data = etopo_data.sel(x=slice(left,right, 30), y=slice(bottom, top, 30))
lons = subs_data.coords.get('x')
lats = subs_data.coords.get('y')
vals = subs_data['z']
x,y = np.meshgrid(lons.data, lats.data)
height = vals.data
meshheights = map_raster_to_mesh(even_mesh, height)
Interpolate height data to fine, triangular grid.#
(You can plot the results as before to see that you have not made a mistake)
You also should make a decision about the resolution of the data you want to download.
plt.figure(figsize=(6, 6))
ax = plt.subplot(111, projection=ccrs.Orthographic(central_longitude=0.1))
ax.add_feature(coastline, edgecolor="black", linewidth=0.5, zorder=3)
plt.scatter(longitudes_in_degrees, latitudes_in_degrees, c=meshheights, cmap="terrain",
vmin=-5000, vmax=5000, s=2,
transform=ccrs.Geodetic())
plt.figure(figsize=(6, 6))
ax = plt.subplot(111)
ax.set_xlim(0,150)
ax.set_ylim(-7000,-2000)
plt.scatter( meshages[meshheights<-2000],
meshheights[meshheights<-2000],
alpha=0.2, marker="+")
Now use scipy.optimise
#
The scipy bundle of useful tools has some curve-fitting routines.
You can read the instructions for scipy.optimise.curve_fit()
at the scipy website
from scipy import optimize
import numpy as np
## First define the function that we are going to fit
def depth_age_fn(age, d0, alpha):
return d0 + alpha * np.sqrt(age)
## Now we need to check the data (interpolation can do weird things)
print(meshages.min(), meshages.max())
print(meshheights.min(), meshheights.max())
## Only fit data for valid ages
valid_age_locations = (meshages > 0)
meshages_1 = meshages[valid_age_locations]
meshheights_1 = meshheights[valid_age_locations]
## Now limit the data to the deep ocean
valid_depth_locations = (meshheights_1 < -2000)
meshages_2 = meshages_1[valid_depth_locations]
meshheights_2 = meshheights_1[valid_depth_locations]
## Something like this:
## popt, pcov = optimize.curve_fit(f, ages, heights )
## d0, alpha = popt
## fitted_heights = depth_age_fn(ages, d0, alpha)
Plot the results of the fitting exercise#
Is this what you would expect from looking at this by eye ?
Now add the curves from Stein & Stein (1992)
Note their values for \(d_0\) and \(\alpha\) !