Input & output¶
Reading ring-width and chronology files, inspecting metadata, and writing data back out. See the Reading & writing data guide for worked examples.
readers¶
Imports a common ring width data file
Extended Summary
This function reads data from common ring width data files (.csv, .rwl) and stores them in pandas dataframes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename |
str
|
a data file (.CSV, .RWL or .RAW). May be a local path or an http(s) URL (e.g. a file served from the NOAA/ITRDB archive) -- both are read the same way. |
required |
header |
bool or None
|
Whether a 3-line site-metadata header sits at the top of the file.
|
None
|
skip_lines |
int
|
indicates how many of the first few lines of the file to skip when reading it. |
0
|
format |
(None, tucson, csv)
|
Force the file format regardless of suffix. |
None
|
strict |
bool
|
|
True
|
join |
bool
|
|
True
|
Returns:
| Name | Type | Description |
|---|---|---|
data |
pandas dataframe
|
|
Examples:
>>> import dplpy as dpl
>>> data = dpl.readers("../tests/data/csv/file.csv")
>>> data = dpl.readers("../tests/data/rwl/file.rwl") # header auto-detected
>>> data = dpl.readers("../tests/data/rwl/file.rwl", header=True)
>>> data = dpl.readers("https://www.ncei.noaa.gov/pub/data/paleo/treering/"
... "measurements/northamerica/usa/ak132x.rwl") # read from a URL
References
.. [1] https:/opendendro.org/dplpy-man/#readers
readers_url¶
Read a Tucson (.rwl) file directly from a URL.
Deprecated: readers() now accepts an http(s) URL directly, so
dpl.readers(url) does the same thing. This thin wrapper is kept for
backward compatibility and simply forwards to readers.
metadata¶
Extract site/sample metadata from a Tucson (.rwl) file's header.
Returns a dict with best-effort fields (site_id, site_name, species_code, species_name, country_region, elevation_m, latitude, longitude, first_year, last_year, investigators) plus n_header_lines and the raw header lines. Unreadable fields are None. Reads only the header, so it is cheap and independent of loading the data; accepts a local path or an http(s) URL. This is a prototype -- see df.attrs['dplpy_metadata'] for the same result captured at read time.
read_crn¶
Read a Tucson (.crn) chronology file into a DataFrame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename |
str
|
Path (or http/https URL) to a .crn chronology file. Standard single chronologies and combined multi-block files (stacked ARSTAN types, or many sites concatenated) are both handled. |
required |
strict |
bool
|
|
True
|
split_by_site |
bool
|
If True, return a dict mapping each site ID to its own DataFrame (each
framed as a single-site file: value columns named by chronology type
plus a shared |
False
|
Returns:
| Type | Description |
|---|---|
pandas.DataFrame or dict of pandas.DataFrame
|
By default one DataFrame indexed by year: one value column per
chronology (named by chronology type for a single-site file, e.g.
'std'/'res'/'ars'; by site, or 'site.type', for a multi-site file),
index values divided by 1000 and 9990 mapped to NaN, with sample depths
as 'samp_depth' (shared when several chronologies carry identical depth)
or ' |
Examples:
>>> dpl.read_crn("ga004.crn")
>>> dpl.read_crn("celaque_prelim_v01.rwl_crns.txt")
>>> by_site = dpl.read_crn("ALL.CRNS", split_by_site=True) # {site: DataFrame}
References
.. [1] https:/opendendro.org/dplpy-man/#read_crn
read_ids¶
Derive tree and core IDs from series names (site-tree-core convention).
Extended Summary
Tree-ring series are conventionally named with a site code, a tree number, and a core designator (the "STC" convention). This function splits each series name into a tree identifier (site + tree number, so that different trees -- and different sites -- never collide) and a core designator, and returns the mapping used by dpl.rwi_stats() and dpl.sss() to know which cores belong to the same tree.
Two parsing modes are available:
Pattern default (stc=None). Each name is split on its letter/digit boundaries: leading letters are the site, the first run of digits is the tree number, and any trailing characters are the core. This handles names with a LETTER core and a variable-length site automatically, e.g. both "ABC001A" (site ABC, tree 001, core A -> tree "ABC001") and "ABCD01" (site ABCD, tree 01, no core -> tree "ABCD01").
IMPORTANT: this pattern cannot see a DIGIT core. A name like "CAM031" (site CAM, tree 03, core 1) still matches -- the whole digit run "031" is read as the tree number and the core comes out empty -- so it parses WITHOUT any warning but leaves "CAM031" and "CAM032" as two separate trees instead of grouping them under "CAM03". For digit cores (and for site codes that contain digits) you MUST supply an explicit stc mask. The only names that trigger the "could not parse" warning are those that do not match the pattern at all (no leading letters, embedded separators, etc.).
STC mask (stc=(site_len, tree_len[, core_len])). Splits each name by fixed character positions: the tree identifier is the first site_len+tree_len characters, and the core is the remainder (or exactly core_len characters if a third element is given). Use this whenever the pattern default cannot resolve the structure -- e.g. digit cores like "CAM031" with stc=(3, 2, 1), or site codes that contain digits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data |
pandas dataframe or iterable of str
|
a dataframe whose column names are the series names (such as from dpl.readers()), or any iterable of series-name strings. |
required |
stc |
tuple of int, or None
|
None to use the pattern default; otherwise a (site_len, tree_len) or (site_len, tree_len, core_len) character mask. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
ids |
pandas dataframe indexed by series name, with columns 'tree' and
|
'core'. Pass this directly as the |
Examples:
>>> import dplpy as dpl
>>> data = dpl.readers("../tests/data/csv/file.csv")
>>> ids = dpl.read_ids(data) # letter-core names
>>> ids = dpl.read_ids(data, stc=(3, 2, 1)) # digit-core names (e.g. CAM031)
>>> dpl.rwi_stats(dpl.detrend(data, plot=False), ids=ids)
References
.. [1] https://rdrr.io/cran/dplR/man/read.ids.html
combine_rwl¶
Combine ring-width datasets on the union of their years (dplR combine.rwl).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x |
pandas.DataFrame or list/tuple of DataFrames
|
Either the first dataset (with |
required |
y |
DataFrame
|
The second dataset, when |
None
|
warn_duplicates |
bool
|
Emit a warning if the combined frame ends up with duplicate series names (the columns are still kept, matching dplR -- this only flags them). |
True
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
All series side by side, indexed by a contiguous year range spanning the earliest to the latest year of the inputs (years with no data are NaN). |
Notes
Series columns are concatenated as-is: like dplR, duplicate series IDs are neither merged nor renamed. Deduplicate or rename beforehand if that matters for your workflow.
writers¶
Output dplpy datasets to .csv, .rwl and .crn files.
Extended Summary
Given a pandas dataframe, this function writes its contents to a .csv, .rwl
or .crn file as indicated by the format parameter. The file will be created
in the same directory unless a different path is included in label.
For 'csv' and 'rwl', data is a ring-width dataframe (years x series). For
'crn', data is a chronology (the output of dpl.chron() -- a dataframe with
an index column such as 'std'/'res' and a 'samp_depth' column), and a
header of site metadata is REQUIRED to populate the Tucson .crn header.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data |
pandas dataframe
|
ring widths (csv/rwl) or a chronology from dpl.chron() (crn). |
required |
label |
str
|
name (can include file path) to give the file; no extension. |
required |
format |
str
|
'csv', 'rwl', 'crn', or 'txt'. |
required |
header |
dict, required for format='crn'
|
site metadata with the keys: 'site_id', 'site_name', 'species_code', 'state_country', 'species', 'elevation', 'latitude', 'longitude', 'investigators'; optionally 'completion_date'. First/last year are taken from the chronology. |
None
|
chronology_type |
str
|
for format='crn', the ITRDB chronology type written in header record 2: 'standard' (blank code), 'arstan' ('A'), or 'residual' ('R'). |
'standard'
|
column |
str
|
for format='crn', which chronology column to write (e.g. 'std', 'res'). |
'std'
|
prec |
float
|
for format='rwl', the measurement precision in mm: 0.001 (values written
x1000, end-of-series marker -9999) or 0.01 (values x100, end marker 999).
The precision->marker mapping follows dplR's write.tucson. Note two
deliberate divergences from dplR: dplPy defaults to prec=0.001 (dplR
defaults to 0.01), and interior gaps are encoded via the |
0.001
|
gaps |
(int, split)
|
for format='rwl', how to encode a true interior gap (a NaN inside a series -- missing measurement, as distinct from a real 0, which is a ring that was locally absent that year and is always written as 0): a negative integer (a dplPy convention, default -99; also e.g. -9) writes that sentinel in the gap within a continuous block -- it must be negative so it is not read as a ring width, and must not be a stop marker; dplPy's reader turns any such negative back into NaN on read. "split" instead closes the block with the end marker and reopens a new block at the next present year (no sentinel in the file; gap still reads back as NaN). |
int
|
sep |
for format='txt', the column delimiter (default tab), printf float format
(default '%.4f', None for full precision), and missing-value text
(default 'NA'). For 'txt', |
'\t'
|
|
float_format |
for format='txt', the column delimiter (default tab), printf float format
(default '%.4f', None for full precision), and missing-value text
(default 'NA'). For 'txt', |
'\t'
|
|
na_rep |
for format='txt', the column delimiter (default tab), printf float format
(default '%.4f', None for full precision), and missing-value text
(default 'NA'). For 'txt', |
'\t'
|
Returns:
| Type | Description |
|---|---|
None
|
|
summary¶
Summarizes a chronology
Extended Summary
This function summarizes a given dataframe of tree widths/rings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inp |
str or pandas dataframe
|
a data file (.CSV or .RWL) or a pandas dataframe imported from dpl.readers(). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
data |
pandas dataframe
|
|
Examples:
References
.. [1] https:/opendendro.org/dplpy-man/#summary
report¶
Generates a report
Extended Summary
Generates a text report about the input dataset that includes: Number of dated series Number of measurements Avg series length (years) Range (total years) Span (start-end year) Mean (Standard Deviation) series intercorrelation Mean (Standard Deviation) AR1 Years with absent rings listed by series
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inp |
str or pandas dataframe
|
a data file (.CSV or .RWL) or a pandas dataframe imported from dpl.readers(). |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Examples:
References
.. [1] https:/opendendro.org/dplpy-man/#report
SiteMetadata¶
Site/sample metadata shared by dplPy's file exporters.
Field names mirror dpl.metadata() / df.attrs['dplpy_metadata']. Use
:meth:from_rwl to auto-fill from a frame read by dpl.readers(),
:meth:from_metadata from a metadata dict, or construct one directly and set
fields by hand. :meth:to_crn_header renders the dict the Tucson .crn
writer expects (which uses a few different key names).
from_metadata
classmethod
¶
Build from a metadata dict (dpl.metadata() output or the same
shape). Unknown keys (e.g. n_header_lines) are ignored.
from_rwl
classmethod
¶
Build from a frame read by dpl.readers() (uses
df.attrs['dplpy_metadata']), or from a metadata dict directly.
coerce
classmethod
¶
Return obj if it is already a SiteMetadata, or build one from a
metadata dict. Used by writers so they accept either form.
to_crn_header ¶
Render the header dict the Tucson .crn writer expects. The writer
uses a few different key names (state_country/species/
elevation); this maps them. Fields that are None are omitted, so the
writer's own "missing required key" check reports what still needs
filling rather than writing the literal 'None'.