Estimating whole-tree sap flow in buttressed and irregular trunks
Data files
Jul 21, 2026 version files 1.84 MB
-
pisonia-modeled-trunk-data-2026-05-16.csv
15.26 KB
-
r-steiner-r-in-computation.R
7.79 KB
-
README.md
11.63 KB
-
sapflow-estimates.R
10.81 KB
-
smoothed_polygons_aligned_clean.gpkg
1.13 MB
-
swd.csv
681 B
-
trunk-data-generator.R
10.18 KB
-
trunk-erosion.R
8.16 KB
-
trunks.gpkg
638.98 KB
Abstract
When upscaling sap flux densities to estimate the water consumption of an entire tree, standard practice assumes the trunk’s cross section is perfectly circular. This assumption will overestimate the area and underestimate the perimeter of a real trunk’s cross section as measured with a taut diameter tape. But how might irregular trunk shapes bias sap flow estimates?
The data and scripts in this repository were used by Burnett et al. (submitted) to investigate this question, and to evaluate new theoretical and semi-empirical methods for correcting sap flow estimates for non-circular tree trunks. The repository includes the 33 digitized trunk cross sections of Pisonia grandis, geometric properties derived from these cross sections, sapwood depth and sap flux density data collected in-situ, and scripts that estimate spatially explicit reference sap flow (SFref), traditional circular trunk assumption sap flow (SFcirc), sap flow theoretically corrected for non-convex trunks using Steiner's formula (SFsteiner), and sap flow corrected using empirical models of trunk geometry (SFcorr).
Also included is an R package that allows users to generate SFcirc, SFsteiner, and SFcorr from their own trunk measurement datasets (inputs: radial sap flux density profiles, DBH, perimeter, and, optionally, sapwood depth and deepest concavity depth).
This set of scripts and inputs generates the SF estimates reported by Burnett et al. (2026) for 33 Pisonia grandis trunks on Tetiaroa Atoll.
Script inputs can be modified for use with digitized cross-sections for new trees, and with new radial sap flux distributions. See the article for a description of how to digitize trunk cross-sections.
Input files
- smoothed_polygons_aligned_clean.gpkg
- This geopackage includes vector (polygon) representations of the 33 digitized Pisonia trunks.
- Each polygon is associated with a unique "tree_ID"
- UTM zone 1 (EPSG 32601)
- swd.csv
- This file includes tree_ID values and a sapwood depth value in cm associated with each individual.
Scripts
Scripts should be run in the following order, with input/output filepaths modified to reflect the user's filesystem.
- trunk-data-generator.R
- Generates an array of geometric properties for each trunk polygon and saves them to "trunks.gpkg" (this filename can be modified).
- trunk-erosion.R
- This script requires radial profiles of sap flux density be described by a beta distribution defined by parameters u (mean) and K (concentration). u and K are set by the user (default values are those fit for Pisonia in the article).
- Creates a new geopackage file for each original polygon within a new "/eroded" directory (this directory can be modified).
- Each new geopackage file contains the nested annuli of thickness dx (0.5 mm by default) from each polygon and calculates the sap flow (volume/time) contributed by each annulus, according to the beta sap flux distribution entered by the user.
- Mode can be changed from default "sapwood" to "full_radius" if the beta sapflux distribution reflects the entire range of depths from cambium to Rcirc rather than the range of depths from cambium to sapwood depth.
- This script uses packages
foreachanddoParallelto speed up processing. - Sap flux densities are modeled using unscaled beta distributions (i.e. the area under the distribution adds up to 1). Configurable parameter A is a scalar that can be used to introduce real units into the calculation; as a simple example, if the sap flux density is known at a certain depth (Jtrue), the beta distribution sap flux density value at that depth can be upscaled using A if A=Jtrue/Jbeta. SF values will then be estimated in the units of Jtrue. The script is written such that the same A must be applied to all trees.
- r-steiner-r-in-computation.R
- This script spatially estimates rsteiner and rin from the eroded geopackages, then writes them to "trunks.gpkg". These are the relative radii at which annular areas depart from those predicted by Steiner's formulae and at which annular areas drop to zero, respectively (see Burnett et al. (2026)).
- sapflow-estimates.R
- Uses the three sap flow models proposed by Burnett et al. (2026) (SFcirc, SFsteiner, and SFcorr) to estimate sap flow for all the polygons in trunks.gpkg
- By default, SFcorr is estimated not with the rsteiner and rin values measured by the previous script, but instead with modeled values from Equations 10-13 in Burnett et al. (2026). These equations estimate rsteiner and rin from measured perimeter, convex hull perimeter, and deepest concavity depth using empirical relationships derived from Pisonia grandis. Measured values of rsteiner and rin can be used instead by changing
use_regression_for_rto FALSE; regression coefficients can also be modified in the "toggle & coefficients" section. The script uses Eqs. 10-13 by default because in the article we were examining the overall uncertainty in SFcorr if the models are used for rsteiner and rin, as they would be in a new tree. Eqs. 10-13 were fit using the data output from the previous script. - Mode can be changed from default "sapwood" to "full_radius" if the beta sapflux distribution reflects the entire range of depths from cambium to Rcirc rather than the range of depths from cambium to sapwood depth. Stay consistent with the mode used in trunk-erosion.R.
- Scaling parameter A should be the same in this script as in Script #2.
Outputs
- /eroded/ID_eroded_v1.gpkg
-
The "eroded" directory will include a geopackage file for every unique polygon present in the original input. Each of these geopackages will include many layers, each reflecting one eroded annulus used to calculate SFref.
-
Each geopackage will include trunk-level data fields (which are the same for every layer):
- tree_id - a unique identifier for each trunk
- perimeter_cm - true trunk cross-sectional perimeter in cm
- hull_perimeter_cm - convex hull perimeter in cm (equivalent to DBH*pi)
- convexity - the perimeter convexity of the trunk, as defined as the hull perimeter divided by the perimeter. Perfectly convex shapes have a convexity of 1; shapes with increasingly substantial concavities will be closer to 0.
- area_cm2 - trunk cross-sectional area in cm2
- hull_area_cm2 - area of the convex hull in cm2
- area_ratio - the ratio of a trunk's area to its convex hull area
- DBH_cm - Diameter at breast height (DBH) in cm, as estimated as the convex hull perimeter divided by pi.
- perimeter_to_area - the ratio of a trunk's perimeter to its area
- deepest_concave_depth_cm - hmax, or the depth of the deepest concavity on the trunk's cross section as measured along the inward normal from the convex hull.
- concave_depth_over_dbh - hrel, or the diameter-relativized deepest concavity depth, defined as hmax over DBH. This dimensionless metric of deepest concavity depth can be used to compare trunks of many sizes.
- sapwood_depth_cm - depth of the sapwood:heartwood transition, as provided by the user in swd.csv.
- r_sapwood - depth of the sapwood:heartwood transition, relativized as a proportion of Rcirc.
-
Each geopackage will also include annulus-level data fields (which are different for every layer):
14. layer - counter for annuli starting at 1 for the outermost annulus.
15. layer.distance.from.edge - distance between each annulus' outer boundary and the trunk's original outer boundary, in mm.
16. layer.area.cm2 - area of annulus in cm2
17. layer.area.mm2 - area of annulus in mm2
18. layer.perimeter.cm - outer perimeter of annulus in cm
19. swd.cm - depth of the sapwood:heartwood transition (redundant with sapwood_depth_cm)
20. relative.sfd - sap flux density at the middle-depth of each annulus; units dependent on user-supplied sap flux distributions.
21. layer.relative.sapflow - the volumetric sap flow contributed by each layer; units dependent on user-supplied sap flux distributions.
22. relative.depth.to.swd - how close an annulus is to the sapwood:heartwood transition, proportionally.
-
- trunks.gpkg
- Each layer represents one trunk polygon with the following data fields:
- tree_id - a unique identifier for each trunk
- perimeter_cm - true trunk cross-sectional perimeter in cm
- hull_perimeter_cm - convex hull perimeter in cm (equivalent to DBH*pi)
- convexity - the perimeter convexity of the trunk, as defined as the hull perimeter divided by the perimeter. Perfectly convex shapes have a convexity of 1; shapes with increasingly substantial concavities will be closer to 0.
- area_cm2 - trunk cross-sectional area in cm2
- hull_area_cm2 - area of the convex hull in cm2
- area_ratio - the ratio of a trunk's area to its convex hull area
- DBH_cm - Diameter at breast height (DBH) in cm, as estimated as the convex hull perimeter divided by pi.
- perimeter_to_area - the ratio of a trunk's perimeter to its area
- deepest_concave_depth_cm - hmax, or the depth of the deepest concavity on the trunk's cross section as measured along the inward normal from the convex hull.
- concave_depth_over_dbh - hrel, or the diameter-relativized deepest concavity depth, defined as hmax over DBH. This dimensionless metric of deepest concavity depth can be used to compare trunks of many sizes.
- sapwood_depth_cm - depth of the sapwood:heartwood transition, as provided by the user in swd.csv.
- r_sapwood - depth of the sapwood:heartwood transition, relativized as a proportion of Rcirc.
- r_steiner - relative depth of first significant topological change, rsteiner, (see notes under section Scripts), as estimated by Script #3 (see notes under section Scripts).
- swd_minus_r_steiner - relativized sapwood depth minus the relativized Steiner radius (rsteiner); useful for examining whether sap flow occurs deeper than rsteiner.
- incircle_R_cm - radius of largest possible inscribed circle in cm.
- R_cm - Rcirc in cm.
- r_in - relativized radius of the largest possible inscribed circle, rin, as estimated by Script #3 (see notes under section Scripts).
- sapflow_ref - SFref as estimated from eroded annuli in Script #4. Units dependent on user-provided sap flux density distribution.
- r_in_pred - rin predicted by Eq. 13 in the article (see notes under section Scripts).
- r_steiner_pred - rsteiner predicted by Eq. 11 in the article (see notes under section Scripts).
- sapflow_circ - SFcirc as modeled in Script #4.
- sapflow_steiner - *SF~steiner ~*as modeled in Script #4.
- sapflow_corr - SFcorr as modeled in Script #4.
- SF_circ_bias - Bias of SFcirc relative to SFref, as defined by (SFcirc - SFref) / SFref.
- SF_steiner_bias - Bias of SFsteiner relative to SFref, as defined by (SFsteiner - SFref) / SFref.
- SF_corr_bias - Bias of SFcorr relative to SFref, as defined by (SFcorr - SFref) / SFref.
- Note that the SF units are determined by the A scalars in Scripts #2 and #4. If the default A=1 is used, the SF units are aribitrary because sap flux density is unitless (as described by the beta distribution). If the beta distribution of sap flux density is scaled such that its units are cm3 cm-2 hr-1, for instance, then the final SF units are cm3hr-1.
- Each layer represents one trunk polygon with the following data fields:
Other files
-
pisonia-modeled-trunk-data-2026-05-16.csv
- This spreadsheet includes all the primary and modeled data from the 33 digitized Pisonia trunks.
- Should mimic the final data included in trunks.gpkg after running the above scripts on the Pisonia data.
R package
An R package, sapscaleR v0.1.0, is also included in the Dryad repository (hosted at Zenodo) in its initial release version (https://doi.org/10.5281/zenodo.21420061). Information on using the package can be found in the included vignette. For the most recent versions, users are directed to https://github.com/m1burnett/sapscaleR.
Contact
Please contact lead author Michael W. Burnett at mburnett@ucsb.edu or senior author Leander D.L. Anderegg at landeregg@ucsb.edu.
