Run a modified version of the Bchronology algorithm from the R package "Bchron" (Haslett and Parnell, 2008)
Source:R/modBchron.R
modBchron.RdRun a modified version of the Bchronology algorithm from the R package "Bchron" (Haslett and Parnell, 2008)
Usage
modBchron(
ages,
ageSds,
positions,
positionThicknesses = rep(0, length(positions)),
ids,
distTypes = rep("G", length(ages)),
MC = 10000,
burn = 2000,
probability = 0.95,
adapt = TRUE,
mhSD = rep(0.001, length(unique(ids))),
psiSD = 0.001,
muSD = 0.001,
mu0 = NULL,
psi0 = NULL,
thetas0 = NULL,
mu_fixed = NULL,
psi_fixed = NULL,
predictPositions = seq(min(positions), max(positions), length = 500),
truncateUp = 0,
extrapUp = 100,
truncateDown = 1e+10,
extrapDown = 100
)Arguments
- ages
Ages of the dated samples (numeric vector, one value per date, in one time unit such as kyr or Ma that is used for all age arguments). Required (no default).
- ageSds
One-sigma uncertainties of
ages(numeric vector, > 0, same unit, length and order asages); fordistTypes = "U"it is the half-width of the uniform distribution. Required (no default).- positions
Stratigraphic positions of the dated samples as distance above the base of the section, e.g. in metres (numeric vector, same length and order as
ages; unordered positions are sorted with a warning). Required (no default).- positionThicknesses
Stratigraphic uncertainty of each date, given as half thickness in the unit of
positions(numeric vector, >= 0, same length and order asages).Default=rep(0, length(positions))(no positional uncertainty).- ids
Sample names of the dates (character or numeric vector, same length and order as
ages); all dates with the same id are combined into a single age PDF of one dated horizon. Required (no default).- distTypes
Distribution used for each date (character vector, same length and order as
ages):"G"Gaussian (meanages, standard deviationageSds) or"U"uniform (agesplus or minusageSds).Default=rep('G', length(ages)).- MC
Number of MCMC iterations (integer, >
burn).Default=10000.- burn
Number of initial MCMC iterations discarded as burn-in when the intervals are computed (integer, >= 1 and <
MC).Default=2000.- probability
Probability of the returned highest density interval and of the outlier check of the dates (numeric, between 0 and 1; 0.95 is 95 percent).
Default=0.95.- adapt
Tune the proposal standard deviations of the model parameters during the run with the adaptive proposal algorithm of Haario et al. (1998) (logical, TRUE or FALSE).
Default=TRUE.- mhSD
Metropolis-Hastings proposal standard deviations of the ages of the dated horizons, in the age unit (numeric vector of length
length(unique(ids)), > 0); the starting values whenadapt = TRUE, used as they are otherwise.Default=rep(0.001, length(unique(ids))).- psiSD
Metropolis-Hastings proposal standard deviation of the Compound Poisson-Gamma scale parameter psi (numeric, > 0); the starting value when
adapt = TRUE.Default=0.001.- muSD
Metropolis-Hastings proposal standard deviation of the Compound Poisson-Gamma mean parameter mu (numeric, > 0); the starting value when
adapt = TRUE.Default=0.001.- mu0
Warm-start centre of the initial Compound Poisson-Gamma mean parameter mu (numeric, > 0, or
NULL). IfNULL, mu is initialised the original way, from the raw date/position spacing. If given, the chain starts atabs(rnorm(1, mean = mu0, sd = muSD)), so that a chain can be restarted near a previously known good region of parameter space (e.g. in a rejection-sampling/restart scheme) instead of re-exploring from scratch. It does not change the Metropolis-Hastings acceptance ratio, only where the chain begins.Default=NULL.- psi0
Warm-start centre of the initial Compound Poisson-Gamma scale parameter psi (numeric, > 0, or
NULL), analogous tomu0. IfNULL, psi is initialised the original way (abs(rnorm(1, 1, sd = psiSD))).Default=NULL.- thetas0
Warm-start vector of starting ages of the dated horizons (numeric vector, one value per unique id, in the same order as
unique(ids)). If NULL (default) each is initialised from its own likelihood peak, as before. This matters most in a batch-RESTART scheme: the adaptive proposal SDs start at theirmhSDdefault of 0.001 and grow by only about a factor of 10 per 200-iteration adaptation window, so they need roughly 1000 iterations to reach the right scale (measured on a 7500 +/- 15 date: mhSD goes 0.001 -> 0.012 at iter 200 -> 0.157 at iter 400 -> ~34 at iter 1000). A chain restarted COLD inside a short batch never gets there: its dated horizons stay pinned within a fraction of a kyr of their starting values, so the run silently reports near-ZERO age uncertainty at the dated horizons. Passingthetas0together with the previous run's adaptedmhSD/psiSD/muSDlets a restarted chain resume properly mixed instead of paying that burn-in again. Values are still clipped into [truncateUp, truncateDown].Default=NULL.- mu_fixed, psi_fixed
Hold the Compound Poisson-Gamma mean (
mu_fixed) or scale (psi_fixed) parameter at the given value and skip its Metropolis-Hastings updates (numeric, > 0, orNULL).NULLestimates the parameter in the MCMC as before.Default=NULLfor both.WHY THIS EXISTS. mu and psi are estimated from the gaps BETWEEN dated horizons, so n dates give only n-1 numbers to estimate both. With a handful of dates psi is effectively UNIDENTIFIED: on a 3-date section its posterior spanned a factor of 489 (95% range 28.9 to 14100). That matters enormously, because psi controls the Poisson event rate of the age-depth bridge, lambda = mu^(2-p)/(psi*(2-p)). At the posterior median psi of ~3450 that works out at about ONE event across a whole 3750-kyr interval – the age path between two dates is then essentially a single random gamma jump, and the interior uncertainty balloons to several hundred kyr regardless of how precise the dates are. Left "free", psi is not being estimated so much as allowed to wander somewhere unhelpful.
WHAT PINNING IT BUYS (measured, floating-time model, 3 dates at +/-30 kyr, 3 replicates each): psi free : interior SD 458 kyr, RMSE of the median vs the true curve 15.8 kyr psi = 100 : interior SD 245 kyr, RMSE 20.3 kyr psi = 10 : interior SD 82 kyr, RMSE 15.4 kyr psi = 1 : interior SD 35 kyr, RMSE 15.4 kyr So a 13-fold tightening with NO loss of accuracy – the free-psi width was not information, it was an unidentified nuisance parameter wandering.
THE PRICE, AND IT IS REAL. psi encodes how much you trust the timescale you are fitting against. Pinning it small asserts that the cyclostratigraphic axis is right. Repeating the test with a deliberately WRONG axis (cycle misidentified as 25 kyr instead of 21, plus a spurious trend): psi free : interior SD 451 kyr, RMSE 94 kyr, 95% coverage 1.00 psi = 1 : interior SD 35 kyr, RMSE 94 kyr, 95% coverage 0.49 Both are equally WRONG, but the wide free-psi band still contained the truth while the pinned one did not – at half of all depths the true age fell outside the model's own 95% interval. The sprawling free-psi uncertainty was acting as an accidental safety net.
SO: pin psi only alongside the independent astronomical controls in spectral_filter.R (the spectral peak test and the cycle-count test). Those are what establish that the axis is right, and once psi is pinned they are no longer a refinement – they are the thing standing between you and a confidently wrong answer. Report a sensitivity range over psi rather than a single value.
- predictPositions
Stratigraphic positions at which the age model is evaluated, in the unit of
positions(numeric vector); positions above the top or below the base date are extrapolated.Default=seq(min(positions), max(positions), length = 500)(500 evenly spaced points from the bottom to the top dated horizon).- truncateUp
Youngest permitted age, used as truncation for extrapolating above the top of the section (numeric, in the age unit).
Default=0. IMPORTANT: this is a HARD lower bound on the age of the TOPMOST DATED HORIZON as well, not just on extrapolated points above it – it is used directly as thelowlimit of that horizon's Metropolis-Hastings proposal. So if your top date's own likelihood sits close to this bound (the common case being a "present day" date of 0 +/- sd with the default truncateUp = 0), roughly the lower half of that date's likelihood is excluded by the bound, and its posterior comes out correspondingly narrower and skewed. For a date of 0 +/- 15 with truncateUp = 0 the posterior is a half-normal: sd ~9.0 instead of 15, and a 95% width of ~33 kyr instead of ~59 kyr – verified against both the model output and the closed-form half-normal. That is the model correctly doing what you told it, NOT uncertainty being lost; the age-depth model's uncertainty at a dated horizon equals that date's POSTERIOR, which for any date far from a bound comes back essentially equal to the input (e.g. 7500 +/- 15 at the base returns a 95% width of ~58.6 kyr against the input's 58.8 kyr). If you did not intend the bound to bite, set truncateUp below the youngest age you want to permit (e.g. -1000) and the full date uncertainty is recovered. The same reasoning applies totruncateDownand the bottommost date.- extrapUp
Number of Compound Poisson-Gamma events simulated for every extrapolated age path above the top dated horizon (integer, > 1); it must be large enough for the path to reach the highest
predictPositions.Default=100.- truncateDown
Oldest permitted age, used as truncation for extrapolating below the bottom of the section (numeric, in the age unit). See the note on
truncateUp: it is likewise a hard upper bound on the age of the bottommost dated horizon, not only on extrapolated points.Default=1e10(in effect no bound).- extrapDown
Number of Compound Poisson-Gamma events simulated for every extrapolated age path below the bottom dated horizon (integer, > 1), as
extrapUp.Default=100.
Value
HDI = specified probability highest density interval for the model run
model = Raw model predictions for each MCMC iteration
thetas = The posterior values for each dated horizon from each MCMC run. burn is not removed.
predictPositions = Stratigraphic positions where the model was evaluated. Same as predictPositions
mu, psi = The posterior values for the Compound Poisson-Gamma mean and scale parameters. burn is not removed.
ageGrid = Grid that age PDFs were evaluated over. Useful for plotting
likelihoods = Age PDFs for each set of dated samples. Useful for plotting
nAges = Number of ages that were combined into each sample. Useful for plotting
masterPositions = Stratigraphic positions for each set of combined ages. Useful for plotting
ids = Vector of unique sample names. Useful for plotting