Crossdating¶
Statistical crossdating against a master chronology, COFECHA-style batch reporting, floating-series dating, and relative dating of undated collections. See the Crossdating & COFECHA and Dating a floating series guides.
xdate¶
Crossdate a set of ring-width series against a leave-one-out master.
Each series is normalized, optionally AR-prewhitened, and correlated against
a biweight master built from all the other series, over segments of
window_length years overlapping by half. Mirrors dplR's corr.rwl.seg.
Flagged segments are labelled A or B (mutually exclusive):
- B -- the segment correlates better at a non-dated lag (best lag != 0): a
possible dating shift. (dplR flags on significance only; dplPy adds this
COFECHA-style lag flag, also used by
preset="COFECHA".) - A -- lag 0 is the best match but the correlation is not significant
(one-tailed p >=
p_val): weak but correctly placed.
Lag sign: the dated segment stays fixed and the master slides past it, so a
negative lag means a missing ring in the series (as in COFECHA). The same
convention holds in series_corr and check.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
detrended RWI (e.g. from |
required |
prewhiten
|
bool
|
AR-prewhiten each series ( |
True
|
corr
|
(spearman, pearson, kendall)
|
correlation method (case-insensitive). |
"spearman"
|
window_length
|
int
|
segment length in years ( |
50
|
bin_floor
|
int
|
the first segment is floored to a multiple of this. |
100
|
p_val
|
float
|
significance level for the A flag. |
0.05
|
biweight
|
bool
|
build the master with a Tukey biweight robust mean (else arithmetic). |
True
|
lag
|
int
|
maximum ± lag examined for the B flag. |
10
|
show_flags
|
bool
|
print the summary box, the flag summary and lag tables. |
True
|
plot
|
bool
|
draw the segment-correlation plot. |
False
|
preset
|
str or None
|
|
None
|
seg_lag
|
int or None
|
segment step in years (overlap). None uses |
None
|
ar_max
|
int or None
|
AR-order ceiling for prewhitening (ARSTAN/COFECHA's 10). |
10
|
first_aic_min
|
bool
|
pick the AR order at the first local AIC minimum (the ARSTAN/COFECHA rule,
dplPy's package default) rather than the global minimum. |
True
|
absent
|
DataFrame or None
|
COFECHA preset only -- marks locally absent rings to omit from a series'
correlations. A boolean (years x series) frame, or a raw ring-width frame whose
zeros mark them (e.g. |
None
|
spline_period
|
int
|
COFECHA preset only -- spline wavelength (years) for the internal detrend and
variance stabilization ( |
32
|
Returns:
| Type | Description |
|---|---|
dict
|
with keys:
With
|
Examples:
>>> rwi = dpl.detrend(ca533, fit="spline", plot=False)
>>> res = dpl.xdate(rwi)
>>> res = dpl.xdate(rwl, preset="COFECHA") # pass the RAW frame
>>> res["n_problems"]
References
.. [1] https://opendendro.github.io/dplPy/reference/crossdating/#xdate
xdate_report¶
Generate a COFECHA-style crossdating QA report for one or more .rwl files.
For each file: read (salvage mode), detrend, cross-date with dpl.xdate,
collate per-series statistics, and print the report and/or save it as
<name>.txt in out_dir (see output). Built for batch QA of ITRDB
submissions. Pass preset="COFECHA" to emulate the COFECHA program instead
(Burg prewhitening, spline variance stabilization, an arithmetic z-scored
master, Pearson correlation, COFECHA segment anchoring and critical value, and
"omit absent rings" fed from the raw frame); pass a RAW frame in that case.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
files
|
str, pandas.DataFrame, or list
|
A .rwl path, an already-loaded ring-width DataFrame (e.g. from dpl.readers()), or a list mixing either. A DataFrame is reported directly (the read step is skipped). For the COFECHA preset, pass a RAW frame (zeros marking absent rings). |
required |
out_dir
|
str
|
Directory for the |
"."
|
fit
|
str
|
detrending curve passed to |
"Spline"
|
corr
|
passed through to |
'spearman'
|
|
window_length
|
passed through to |
'spearman'
|
|
bin_floor
|
passed through to |
'spearman'
|
|
p_val
|
passed through to |
'spearman'
|
|
output
|
(both, screen, file)
|
where the full report goes: |
"both"
|
verbose
|
bool
|
print a one-line per-file progress note and a final tally. |
True
|
preset
|
str or None
|
set to |
None
|
spline_period
|
int
|
spline stiffness (years) for the |
32
|
name
|
str or None
|
Report label for a DataFrame input -- the report title, |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
|
References
.. [1] https://opendendro.github.io/dplPy/reference/crossdating/#xdate_report
xdate_plot¶
dplR-style crossdating overview for a set of series (see corr.rwl.seg).
A thin wrapper: crossdates data with xdate() (same parameters;
slide_period= is a deprecated alias of window_length) and draws the
green/blue/red segment plot -- green = series extent, blue = a segment that
correlates significantly with the master, red = a flagged segment
(p >= p_val). Returns the matplotlib Axes.
Note: this plot shows only the significance screen (dplR's corr.rwl.seg,
i.e. the A flag) -- red marks a segment whose dated (lag-0) correlation is
not significant. It does NOT show the B flag (a segment that correlates
better at a non-dated lag -- a possible dating shift), which dplR's plot has no
concept of. A B-flagged segment that still dates significantly is drawn blue
here, so it looks fine on the plot even though xdate() reports it as a
problem. Always read the text xdate() flag report alongside this plot to
catch B (lag) flags.
References
.. [1] https://opendendro.github.io/dplPy/reference/crossdating/#xdate_plot
xdate_floater¶
Estimate the calendar dating of a floating (undated) ring-width series.
Slide the floating series against a dated master and score each offset by correlation, reporting the best-fit placement with crossdating statistics (t-value, effective df, Bonferroni-corrected p, isolation factor).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame or Series
|
The dated reference (year-indexed). A DataFrame is a collection of
ring-width series, averaged into the master; a Series (or one-column
DataFrame) is used directly as the master -- e.g. |
required |
series
|
sequence or Series / DataFrame
|
The floating (undated) ring-width series -- ring values oldest to youngest; any calendar index is ignored. An interior NaN is an unmeasured ring and keeps its position (it is not compressed out). |
required |
series_name
|
str or None
|
Label for the floating series. None takes it from the series itself (a named Series or one-column DataFrame header), falling back to "Unknown". |
None
|
min_overlap
|
int
|
Minimum overlapping (pairwise-complete) rings required to score an offset. |
50
|
transform
|
(pw, fd, none)
|
High-pass transform applied (after mean-normalization) before correlating,
case-insensitive: |
"pw"
|
prewhiten
|
bool
|
Deprecated alias: |
None
|
biweight
|
bool
|
Build the master with a Tukey biweight robust mean (else arithmetic mean). |
True
|
corr
|
(spearman, pearson, kendall)
|
Correlation used to score each offset (one-sided). |
"spearman"
|
ar_max
|
int or None
|
AR order ceiling for |
10
|
first_aic_min
|
bool
|
Select the AR order at the FIRST local AIC minimum (COFECHA/ARSTAN rule)
rather than the global AIC minimum (dplR's |
True
|
plot
|
bool
|
Plot the sliding t-value against the series' end year, marking the best fit. |
False
|
return_rwl
|
bool
|
Also return the floating series placed at its best-fit years ( |
False
|
segmented
|
bool
|
Also date each overlapping segment of the floater independently against the
master and check that they agree (COFECHA UDATE-style). Adds
|
False
|
segment_topk
|
int
|
With |
5
|
verbose
|
bool
|
Print a short summary of the best-fit dating. |
True
|
Returns:
| Type | Description |
|---|---|
dict
|
|
Notes
Ports dplR's xdate.floater and adds crossdating statistics (t-value,
autocorrelation-adjusted effective degrees of freedom, a Bonferroni-corrected
p-value, and an isolation factor; Baillie & Pilcher 1973, Wigley et al. 1987,
Wilson 2026). The correlation scoring reuses dplPy's crossdating internals, so
results are consistent with dpl.xdate.
References
.. [1] https://opendendro.github.io/dplPy/reference/crossdating/#xdate_floater
xdate_undated¶
Crossdate a set of undated ("floating") ring-width series against one another and assemble a single relatively-dated floating chronology (COFECHA UFLOAT-style).
Use this when no dated reference exists but the samples overlap in time -- e.g. a
stand of sub-fossil or river-drowned trees. The series are positioned relative to
each other and the earliest inferred ring is set to anchor_year (default 1).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
pandas.DataFrame, dict, or list
|
The undated collection. A DataFrame is read as one column per series (its
index only orders the rings, oldest first); a dict maps names to ring-width
arrays; a bare list is auto-named |
required |
transform
|
(pw, fd, none)
|
High-pass transform applied before matching (case-insensitive): |
"pw"
|
corr
|
(spearman, pearson, kendall)
|
Correlation used to score every offset. |
"spearman"
|
min_overlap
|
int
|
Minimum overlapping rings required to score a match. |
50
|
crit_t
|
float
|
A series joins the master only if its best t against the running mean reaches this. |
4.0
|
anchor_year
|
int
|
Relative calendar year assigned to the earliest ring of the assembled chronology. |
1
|
min_isolation
|
float
|
A placement whose leave-one-out isolation (the t gap to the next-best, well-separated position) falls below this is flagged for review. |
1.0
|
ar_max
|
int or None
|
AR order ceiling for |
10
|
first_aic_min
|
bool
|
Select the AR order at the FIRST local AIC minimum (COFECHA/ARSTAN rule)
rather than the global AIC minimum (dplR's |
True
|
plot
|
bool
|
Draw a placement chart (each series on the relative axis, coloured by isolation) with the mean floating chronology beneath it. |
False
|
verbose
|
bool
|
Print a short summary. |
True
|
Returns:
| Type | Description |
|---|---|
dict with:
|
|
References
.. [1] https://opendendro.github.io/dplPy/reference/crossdating/#xdate_undated
series_corr¶
Crossdate one series against the master built from all the others.
Produces (and, by default, plots) a moving correlation of the series against
the leave-one-out master, the per-segment correlations, and a per-segment
lag table (COFECHA-style) showing how the correlation changes when the
master is shifted ± lag years past the dated segment -- an off-zero
peak suggests a dating error in that segment.
Lag convention (lag_table and, by default, ccf): the dated segment
stays fixed and the MASTER slides, so a negative lag means a missing ring
in the series, as in COFECHA, dpl.xdate and dpl.check. The
lag_table is xdate._lag_table(), the same scan behind xdate's B flags.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
ring-width series (typically detrended RWI). |
required |
series_name
|
str
|
the series to examine. |
required |
prewhiten
|
as in |
True
|
|
corr
|
as in |
True
|
|
window_length
|
as in |
True
|
|
bin_floor
|
as in |
True
|
|
p_val
|
as in |
True
|
|
biweight
|
as in |
True
|
|
lag
|
as in |
True
|
|
ar_max
|
as in |
True
|
|
first_aic_min
|
as in |
True
|
|
plot
|
bool
|
master switch for drawing any figure. |
True
|
series_x
|
bool
|
lag convention for the dplR-style |
False
|
which
|
(both, moving, ccf)
|
when |
'both'
|
Returns:
| Type | Description |
|---|---|
dict with keys ``moving_corr`` (Series), ``seg_corr`` (Series over bins),
|
|
``overall`` (DataFrame, one row for the series, columns ``rho`` and
|
|
``p_val`` -- the same shape as ``xdate()["overall"]``), ``lag_table``
|
|
(correlations at shifted master windows, lags x bins, using ``corr``),
|
|
``ccf`` (dplR-style Pearson cross-correlation per segment, lags x bins),
|
|
``ccf_bins``, ``bins`` and ``rwi`` (the transformed series used).
|
|
References
.. [1] https://opendendro.github.io/dplPy/reference/crossdating/#series_corr
interseries_corr¶
Mean interseries correlation (COFECHA's headline statistic).
For each series, correlate it against a master chronology built from every other
series (leave-one-out), then average. This is dplR's interseries.cor(), and
is distinct from rbar (rwi_stats), which averages the pairwise correlations
between individual series.
Expects raw ring widths, not indices: each series is normalized by its own mean
and, by default, prewhitened before the correlations are computed (the same
transform as dpl.xdate, so the per-series values equal
xdate()["overall"]["rho"]).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
raw ring widths (as from |
required |
prewhiten
|
boolean
|
prewhiten each series with an autoregressive model before correlating
( |
True
|
biweight
|
boolean
|
build each leave-one-out master with a Tukey biweight robust mean rather than the arithmetic mean. |
True
|
corr
|
(spearman, pearson, kendall)
|
correlation type (case-insensitive). |
"spearman"
|
ar_max
|
int or None
|
AR-order ceiling for prewhitening; |
10
|
first_aic_min
|
bool
|
AR order at the first local AIC minimum (ARSTAN rule) rather than the global
minimum; |
True
|
Returns:
| Type | Description |
|---|---|
dict
|
|
Examples:
>>> import dplpy as dpl
>>> res = dpl.interseries_corr(dpl.readers("series.rwl"))
>>> res["mean"], res["table"]
References
.. [1] https://rdrr.io/cran/dplR/man/interseries.cor.html .. [2] https://opendendro.github.io/dplPy/reference/crossdating/#interseries_corr