Skip to content

Utilities

Gap infilling, pith-offset conversion, LiPD interchange, plotting, and CLI helpers.

fill_internal

Fill interior gaps (interior NaN) in a ring-width dataset.

Only interior NaN -- those between a series' first and last real ring -- are filled; leading and trailing NaN are left untouched. A real 0 (a locally absent ring) is data and is never treated as a gap. Series with one or no real value are returned unchanged.

Parameters:

Name Type Description Default
data pandas dataframe

ring widths (or indices), years as the index and series as columns.

required
fill (Mean, Spline, Linear, ARSTAN)

how to fill each interior gap (case-insensitive):

  • "Mean" : the series' mean (flat fill).
  • "Linear" : straight-line interpolation between the flanking values.
  • "Spline" : cubic-spline interpolation through the present values. A spline can overshoot below zero next to a small ring; such values are clipped to 0 (a ring width cannot be negative) and the series named in a warning, so the fill can be reviewed.
  • a number : that constant value.
  • "ARSTAN" : impute each missing ring from the common (mean) chronology signal, moment-matched to the series and modulated by its growth curve (see Notes and _fill_arstan).

"Mean", "Linear" and "Spline" port dplR's fill.internal.NA() and interpolate within each series only.

"Mean"
**kwargs

for fill="ARSTAN", forwarded to _fill_arstan (e.g. growth_nyrs, long_gap, flank).

{}

Returns:

Name Type Description
out pandas dataframe, same shape/index/columns as `data`, with interior

gaps filled. The input's attrs (metadata, precision, provenance) are kept: the result is still raw widths.

Notes

The simple methods know nothing about the other series -- they just bridge each hole -- so use them when you need an NaN-free series for a downstream step, not as if the filled values were measured. "ARSTAN" instead borrows the shared year-to-year signal from all series.

References

.. [1] https://opendendro.github.io/dplPy/reference/utilities/#fill_internal

edit_rwl

Insert, delete, or change one ring in a single series.

Returns a new object; the input is never modified in place (unlike the old Fortran programs, where the edit mutated the record). Assign the result to keep it. The fix that pairs with the crossdating checks: xdate, series_corr, and check find a misdated ring (a NEGATIVE lag there means a MISSING ring, so action="insert"), and edit_rwl corrects it.

Parameters:

Name Type Description Default
data DataFrame or Series

a ring-width collection (then series names the column to edit) or a single year-indexed series. Leading/trailing NaN rows of a Series are kept.

required
series str or None

the series (column) to edit; required when data is a DataFrame.

None
year int

the calendar year to act on (a whole number; NaN or 2003.7 is an error). For action="insert" it may also be the year just before the series (prepend).

None
action (insert, delete, change)

"insert" adds a ring (a missed ring), "delete" removes one (a false or double-counted ring), "change" replaces a measured value without changing the series length or dating. Case-insensitive.

"insert"
value float or None

the ring width, a finite non-negative number. Required for "change"; for "insert" it defaults to the series mean; ignored for "delete".

None
fix_last bool

insert/delete only. True keeps the most recent year dated and lets the one-ring change roll off the inner (oldest) end; False keeps the inner end dated and changes the recent end. Matches dplR's fix.last.

True
fix_length bool or None

insert/delete on a Series only. True (the default for a Series, as dplR's fix.length) keeps the series' original length by dropping (insert) or NA-padding (delete) one ring at the end opposite fix_last; a warning names the measured ring an insert drops. For a DataFrame it is not applied, following dplR's rwl method: no measurement is ever discarded, the collection simply gains a year (insert) or the series loses one (delete), and all-NaN rows a delete leaves at either end are trimmed. Passing fix_length=True with a DataFrame is an error, as in dplR.

None

Returns:

Type Description
DataFrame or Series

a copy with the one edit applied, same type as data. For a DataFrame the edited column is realigned onto the (possibly one-year-extended) year index and the other series are untouched. The input's attrs are kept (the result is still raw widths).

Examples:

>>> import dplpy as dpl
>>> rwl = dpl.readers("co021.rwl")
>>> fixed = dpl.edit_rwl(rwl, series="641114", year=1900, action="insert")
>>> fixed = dpl.edit_rwl(rwl, series="641114", year=1905, action="delete")
>>> fixed = dpl.edit_rwl(rwl, series="641114", year=1912, action="change", value=0.44)
References

.. [1] https://rdrr.io/cran/dplR/man/insert.ring.html .. [2] https://opendendro.github.io/dplPy/reference/utilities/#edit_rwl

po_to_wc

Convert pith offset to (partial) wood completeness (dplR's po.to.wc()).

The number of missing heartwood rings equals the pith offset (dplPy's pith offset is itself the count of rings between pith and first measured ring; 0 = pith present).

Parameters:

Name Type Description Default
po DataFrame

pith-offset table with a series column (series IDs) and a pith_offset column (integer rings between the pith and the first measured ring; 0 = pith present).

required

Returns:

Type Description
DataFrame

one column, n_missing_heartwood (integer), indexed by series.

References

.. [1] https://rdrr.io/cran/dplR/man/po.to.wc.html

wc_to_po

Convert wood completeness to pith offset (dplR's wc.to.po()).

The pith offset is the number of missing heartwood rings plus the number of unmeasured inner rings (0 = pith present), for every series whose pith presence is known (complete/incomplete) or whose missing-heartwood count is given; other series get a missing pith offset.

Parameters:

Name Type Description Default
wc DataFrame

wood-completeness table indexed by series, with any of the optional columns pith_presence ("complete"/"incomplete"), n_missing_heartwood (int) and n_unmeasured_inner (int).

required

Returns:

Type Description
DataFrame

a pith-offset table with series and pith_offset columns (nullable integer; 0 = pith present), suitable as input to RCS.

References

.. [1] https://rdrr.io/cran/dplR/man/wc.to.po.html

yrs_to_pith

Estimate years (rings) to pith from an estimated distance to pith.

Ports modendro's yrs_to_pith() (C. Maher). The number of unmeasured rings between the pith and the innermost measured ring is estimated as the distance to pith divided by a mean innermost ring width, rounded to a whole number of rings. The distance to pith is whatever you measured (e.g. in CooRecorder, as returned by dpl.read_pos().attributes); only the table format matters.

Parameters:

Name Type Description Default
rwl DataFrame

ring widths, years as the index and series IDs as columns.

required
d2pith DataFrame

one row per series, with a series column and a distance-to-pith column named d2pith or distance_to_pith (same units as the ring widths, typically mm).

required
method (dist, rings)

"rings" divides the distance by the mean of the innermost n_rings ring widths. "dist" divides by the mean of as many innermost rings as fit within the distance (at least n_rings), which tracks a changing growth rate near the pith better.

"dist"
n_rings int

number of innermost rings to average ("rings"), or the floor on the number averaged ("dist").

10

Returns:

Type Description
DataFrame

columns series, d2pith, mean_rw, and pith_offset (the estimated whole-ring offset, 0 = pith present), ready to pass to dpl.rcs/dpl.po_to_wc as a pith-offset table.

to_lipd

Write dplPy chronologies to a LiPD .lpd file.

Parameters:

Name Type Description Default
chron DataFrame

Chronology output from dpl.chron() or dpl.chron_ars() -- year indexed, with one or more chronology columns and, if present, 'samp_depth' (written as the count / sampleCount companion).

required
filename str

Output path. .lpd is appended if missing.

required
rwl DataFrame

Raw ring widths the chronology was built from. Written as a further measurement table, and -- if metadata is None -- used to auto-fill site metadata from its dplpy_metadata attrs.

None
metadata SiteMetadata or dict

Site metadata for the geo block; defaults to what rwl carries.

None
dsname str

LiPD dataset name; defaults to the filename stem (a purely-numeric name is avoided -- pylipd cannot resolve one).

None
column str

The primary chronology column (written with isPrimary=True).

'std'
chronologies None | 'all' | list of str

Which chronology columns to write. None writes just column; 'all' writes every non samp_depth column (e.g. std/res/ars from chron_ars); a list writes those columns. The primary is written first.

None
stats DataFrame

Per-year running statistics (e.g. dpl.chron_stabilized(..., running_rbar =True)); a running-rbar column is written as RBAR on the primary chronology table and EPS is derived from it and sample depth (or taken from an EPS column if present).

None
publication dict

Citation for the record: any of authors/author (str or list), doi, title, journal, year, url, citation.

None
provenance str

Free-text description of how the chronology was built (detrending, AR, robust mean, ...). Stored on each chronology variable's description/notes and PaST long name.

None
archive_type str

LiPD archiveType. Defaults to 'Wood'.

None

Returns:

Type Description
str

The path written.

Notes

Requires the optional pylipd dependency: pip install "dplpy[lipd]".

from_lipd

Read a LiPD .lpd file into dplPy-native objects.

Returns a dict with:

  • 'rwl' : the raw ring widths as a year-indexed DataFrame (series as columns), ready for dpl.detrend / dpl.chron, or None.
  • 'chronology' : the primary (headline) chronology as a year-indexed DataFrame (trsgi plus any count/RBAR/EPS), or None.
  • 'chronologies' : a dict of all chronologies found (keyed by a label such as 'standard'/'residual'/'arstan'), from measurement tables and/or model summaries.
  • 'metadata' : a dpl.metadata()-shape dict from the geo block.
  • 'dsname' : the LiPD dataset name.

Requires the optional pylipd dependency: pip install "dplpy[lipd]".

lipd_metadata

Read just the site metadata from a LiPD .lpd file, as a dpl.metadata()-shape dict. Requires the optional pylipd dependency.

plot

Plot a ring-width dataset as a line, spaghetti, or segment plot.

Parameters:

Name Type Description Default
inp str | DataFrame

a file path to a .csv or .rwl file, or a dataframe from dpl.readers().

required
type str

'seg' (coverage segments, one bar per series), 'spag' (spaghetti: each series offset vertically, black by default -- pass color= a colormap name to shade by first year), or 'line' (all series overplotted against year).

'seg'
ax matplotlib Axes

draw into this Axes instead of creating a new figure. When omitted, a figure is created and auto-sized to the data.

None
show bool

call plt.show() after drawing. Set False to keep the figure for saving or further editing (the returned figure is still fully drawn). Under a non-interactive backend (scripts, tests, CI) plt.show() is a no-op, so the figure is closed after showing to avoid accumulating open figures; the returned (fig, ax) can still be saved.

True
**kwargs

passed through to the underlying plotter (e.g. zfac and color for the spaghetti plot -- color takes a colormap name like 'viridis'/'turbo' or a single colour like 'black').

{}

Returns:

Type Description
(fig, ax) : tuple of matplotlib Figure and Axes

the figure and axes drawn on, so callers can save or restyle them. (Earlier versions returned None; the figure is now returned for reuse.)

Examples:

>>> dpl.plot(data)
>>> dpl.plot(data, type="spag")
>>> fig, ax = dpl.plot(data, type="seg", show=False); fig.savefig("seg.png")
References

.. [1] https://opendendro.github.io/dplPy/reference/utilities/#plot

help

Print help for dplPy in the console.

With no argument, print an overview of every public function (grouped by task, each with the first line of its docstring). With a function name -- dpl.help("readers") -- or the function itself -- dpl.help(dpl.readers) -- print that function's live signature and full docstring. The listing is generated from the installed package, so it always matches the real API.

Parameters:

Name Type Description Default
name str or callable

A public dplPy function name ("readers", "dpl.readers") or the function object. Omit for the overview.

None

Examples:

>>> dpl.help()
>>> dpl.help("xdate")

readme

Open the online dplPy manual (https://opendendro.github.io/dplPy/) in a web browser. Prints the URL as well, for machines without a display.