Estimating Age-Depth Models from Sedimentation Rates

Niklas Hohmann

Nonparametric Estimation of age-depth models from sedimentation rates

This vignette gives an example on how to estimate age-depth models (ADMs) from sedimentation rates using the function sedrate_to_multiadm. The function takes the following inputs:

Coding Tie Points

Times and heights of tie points are coded via the functions t_tp (timing) and h_tp (height) that take no inputs. They serve as wrappers around user-defined procedures that reflect uncertainties around tie points. Every time t_tp and h_tp are evaluated, they return possible values for the tie points. Writing these functions requires some effort, but it allows the user to hand over arbitrarily complex uncertainties of the tie points to the sedrate_to_multiadm function.

The function for the heights of the tie points must return a named vector with entries h1 and h2, corresponding to the heights of the first (lower) and second (upper) tie point. h1 must be smaller than h2.

For this example, I assume the stratigraphic positions of the tie points is known without uncertainty, and are at 10 and 85 m stratigraphic height.

h_min = 10 # height of tie point 1
h_max = 85 # height of tie point 2

h_tp is then implemented as follows:

h_tp = function(){
  return(c("h1" = h_min, 
           "h2" = h_max))
}

When evaluated, this function returns the stratigraphic positions of the tie points:

#Evaluate stratigraphic positions of tie points
h_tp()
#> h1 h2 
#> 10 85

The function for the timing of the tie points must return a named vector with names “t1” (timing of first tie point) and “t2” (timing of second tie point). “t1” must be smaller than “t2”.

For this example, I assume the first timing of the first tie point follows a normal distribution with mean 0 and standard deviation 0.5. The timing of the second tie point is bimodal and given as an equal mixture of two normal distributions with means 5 and 7 and standard deviations of 0.1 and 0.3. This is implemented as follows in t_tp:

t_tp = function(){
  # first tie point
  t1 = rnorm(n = 1, mean = 0, sd = 0.5)
  
  # second tie point
  d1 = rbinom(n = 1, size = 2, prob = 0.5) # fair coin flip for mixture
  if (d1 == 0){
    t2 = rnorm(n = 1, mean = 5, sd = 0.1)
  } else {
    t2 = rnorm(n = 1, mean = 7, sd = 0.3)
  }
  return(c("t1" = t1, "t2" = t2))
}

Using Myr as time unit, the distribution of times for the tie points is as follows:

no_of_samples = 10000
# Evaluate timing of tie points
hist(x = sapply(seq_len(no_of_samples), function(x) t_tp()["t1"]),
     freq = FALSE,
     xlab = "Time [Myr]",
     main = "Timing of first tie point")
hist(x = sapply(seq_len(no_of_samples), function(x) t_tp()["t2"]),
     freq = FALSE,
     xlab = "Time [Myr]",
     main = "Timing of second tie point")

Coding Sedimentation Rates

Sedimentation rates are specified via a function sed_rate_gen that takes no inputs. It serves as wrapper for user-defined procedures that specify uncertainties in sedimentation rates. sed_rate_gen is a “function factory”: every time it is evaluated, it returns another function that is one potential sedimentation rate scenario. Writing this function factory requires some effort, but it allows the user to specify how uncertainties of sedimentation rates are expressed in the section, and implement arbitrarily complex distributions.

I use a simple sedimentation rate model, where only upper and lower bounds on sedimentation rates in the section are known. Between these limits, I assume a uniform distribution.

# limits on sed. rates
lower_limit = c(0.1,2,0.1,10)
upper_limit = c(0.2,3,2,12)

# strat intervals where sed rates are defined
s = c(h_min - 1, 30,75, 80, h_max + 1)

Based on these parameters, the sedimentation rate function factory is defined as follows:

# define function factory
sed_rate_fun = function(){
  # draw sed rates from uniform distribution
  aa_1 = c(runif(1,lower_limit[1],upper_limit[1]),
         runif(1, lower_limit[2],upper_limit[2]),
         runif(1,lower_limit[3],upper_limit[3]),
         runif(1, lower_limit[4], upper_limit[4]))
  aa = c(aa_1, aa_1[4])
  # define sed rate "realization" based on samples from uniform distribution
 sed_rate_fun = approxfun(x = s,
                          y = aa,
                          method = "constant")
 # return the function
 return(sed_rate_fun)
}

To visualize, here are three sedimentation rates generated by the “sedimentation rate function factory” sed_rate_fun:

plot(NULL,
     xlim = c(h_min, h_max),
     ylim = c(0, max(upper_limit)),
     xlab = "Stratigraphic Height [m]",
     ylab = "Sedimentation Rate")

no_of_sedrates = 3 # no. of sed rates displayed
h = seq(h_min,h_max, by = 0.1) # strat. positions where sed rates are plotted

for (i in seq_len(no_of_sedrates)){
  # generate sed rate from the factory
  sed_rate_sample = sed_rate_fun()
  
  # plot sed rate in the section
  lines(h, sed_rate_sample(h))
}

All sedimentation rates generated by sed_rate_fun will be different, because they are determined by random numbers.

Estimating the Age-Depth Models

The function sedrate_to_multiadm estimates the age-depth model from the inputs. Here, I determine the age-depth models every meter, and generate 10 ADMs

h = seq(h_min,h_max, by = 1) # strat. positions where ADMs are estimated
no_of_rep = 10 # no. of ADMs estimated
my_adm = sedrate_to_multiadm(h_tp = h_tp(),
                             t_tp = t_tp(),
                             sed_rate_gen = sed_rate_fun,
                             h = h,
                             no_of_rep = no_of_rep)

It generates a portfolio of age-depth models combined into the variable madm (multi-adm). madm is an object of class multiadm.

These are 10 age-depth models generated by the sedrate_to_adm function, which are all equally likely candidates for the age-depth relationship in the section. Running summary statistics on large number of age-depth models (increasing the no_of_rep input variable) gives an assessment of the uncertainties of the age-depth relationship. This can be used to generate the classic envelopes of uncertainty (95 % CI).

Further information

For information on estimating age-depth models from tracer contents of rocks and sediments, see

vignette("adm_from_trace_cont")