Type: Package
Title: Calculate Tree Traits from Terrestrial Lidar
Version: 0.1.2
Description: Measuring tree architecture from terrestrial lidar data, including tree-level properties, crown characteristics, and structural attributes derived from quantitative structure models (QSMs).
License: GPL-3
Encoding: UTF-8
RoxygenNote: 7.3.3
Imports: data.table, lidR, dplyr, ggplot2, ggpubr, recexcavAAR, rlang, sf, spanner, terra, tibble, reticulate, CrownScorchTLS, FNN, alphashape3d, ggplotify, rgl, stats, stringr, readr
NeedsCompilation: no
Packaged: 2026-02-20 23:51:24 UTC; jeffery.cannon
Author: Jeffery B. Cannon [aut, cre]
Maintainer: Jeffery B. Cannon <jeffery.cannon@jonesctr.org>
Repository: CRAN
Date/Publication: 2026-02-25 19:00:02 UTC

Read a PyTLidar QSM file

Description

Reads a PyTLidar-generated cylinder file and converts it into a tidy data frame with start/end coordinates, radius, length, volume, and branching order.

Usage

.read_qsm_raw(cyl_file)

Arguments

cyl_file

Path to the PyTLidar cylinder output file (.txt).

Value

A data frame with columns startX, startY, startZ, endX, endY, endZ, cyl_ID, parent_ID, extension_ID, radius_cyl, length, volume, branching_order.


Add point-wise verticality from local PCA

Description

Computes a verticality metric (0-1) for each point in a LAS object based on the z-component of the dominant local PCA eigenvector.

Usage

add_verticality(las, k = 30, name = "verticality")

Arguments

las

A LAS object.

k

Number of nearest neighbors for local PCA.

name

Name of the attribute to store.

Value

The input 'LAS' object with a new numeric attribute containing verticality values (0–1).

Examples


las = lidR::readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las = add_verticality(las, k = 20)
head(las@data)


Diagnostic Plot of Basic Tree Measurements

Description

Generates a diagnostic 2D plot showing basic tree measurements such as tree height, crown base height (CBH), crown width, and diameter at breast height (DBH) over a subsampled LAS point cloud.

Usage

basics_diagnostic_plot(las, height, cbh, crown_width, dbh, res = 0.1)

Arguments

las

A 'LAS' object (from the 'lidR' package) containing the tree point cloud.

height

Numeric. Total tree height.

cbh

Numeric. Crown base height.

crown_width

Numeric. Crown width.

dbh

Numeric. Diameter at breast height.

res

Numeric. Resolution for point cloud thinning; default is 0.1 m.

Details

The function first thins the point cloud using 'lidR::decimate_points()' to improve plotting speed. Then it overlays key measurement lines and markers for height, crown width, DBH, and crown base height.

Value

A 'ggplot' object displaying thinned tree points and markers for key measurements.

Examples

library(lidR)
path = system.file('extdata', 'tree_0744.laz', package='tReeTraits')
las = clean_las(readLAS(path))
ht = get_height(las)
dbh = get_dbh(las)
wid = get_width(las)[1]
cbh = get_crown_base(las)
basics_diagnostic_plot(las, height = ht, cbh = cbh,
                     crown_width = wid, dbh = dbh)

Diagnostic Plot of Branch Diameter Distribution

Description

Generates a diagnostic plot showing the distribution of branch diameters in a QSM. This is a wrapper around 'branch_size_distribution()' which computes branch metrics.

Usage

branch_distribution_plot(qsm)

Arguments

qsm

A QSM object (e.g., data frame returned by 'run_treeqsm()') containing cylinder information.

Details

The function calls 'branch_size_distribution()' with 'plot = FALSE' to compute branch volumes at midpoints of diameter bins, then generates a bar plot showing total volume per diameter bin.

Value

A 'ggplot' object displaying branch diameter (x-axis) versus total branch volume (y-axis).

Examples

qsm_file = system.file('extdata',"tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
branch_distribution_plot(qsm)

Get Branch size distribution from a QSM

Description

This function outputs the volume (in mL) distribution of branches across different branch diameter classes (in cm). Outputs a table that can be used in other functions to find branch_skewness or branch_volume_weighted_stats()

Usage

branch_size_distribution(qsm, breaks = NULL, plot = TRUE)

Arguments

qsm

– a QSM loaded using '[load_qsm()]'.

breaks

numeric – a vector of diameter classes (in cm) by which to summarize branch volume. If 'NULL' the branch of branch sizes will be distributed across 1 cm bins.

plot

boolean – indicates whether the branch diameter distribution should be plotted as a histogram.

Value

A tibble summarizing branch volume by diameter class with columns:

diameter_cm

Factor indicating the diameter class (cm).

midpoint

Numeric midpoint (cm) of each diameter class.

volume_mL

Total branch volume (mL) within the class.

Returns 'NA' if fewer than two branch cylinders are present.

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
branch_distribution = branch_size_distribution(qsm, plot=TRUE)
print(branch_distribution)

#volume-weighted mean
branch_volume_weighted_stats(qsm, FUN = function(x) mean(x))

#volume-weighted median
branch_volume_weighted_stats(qsm, FUN = function(x) median(x))

# volume-weighted skewness
branch_volume_weighted_stats(qsm, FUN = function(x) 3*(mean(x) - median(x)) / sd(x))

Calculate volume weighted branch statistics

Description

This function calculates statistics on branch diameters weighted by the volume of branches of that size based on outputs from 'branch_size_distribution()'. The user defined function 'FUN' can take any form of f(x) where x is a vector of diameters of length 1 for every mL of volume of that branch size class. See Details for recommended values for 'FUN'. #Details Values of central tendency are recommended, but not variance since the weighted means are simulated.

Usage

branch_volume_weighted_stats(qsm, breaks = NULL, FUN = function(x) mean(x))

Arguments

qsm

a QSM loaded using '[load_qsm()]'.

breaks

numeric – a vector of diameter classes (in cm) by which to summarize branch volume. If 'NULL' the branch of branch sizes will be distributed across 1 cm bins.

FUN

function – central tendency function to be weighted based on branch volume.

Details

Recommended values of 'FUN' are:

Mean FUN = function(x) mean(x)

Median FUN = function(x) median(x)

Skewness FUN = function(x) 3*(mean(x) - median(x)) / sd(x)

Value

A numeric value representing the volume-weighted statistic calculated by 'FUN' across branch diameter classes.

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
branch_distribution = branch_size_distribution(qsm, plot=TRUE)
print(branch_distribution)

#volume-weighted mean
branch_volume_weighted_stats(qsm, FUN = function(x) mean(x))

#volume-weighted median
branch_volume_weighted_stats(qsm, FUN = function(x) median(x))

# volume-weighted skewness
branch_volume_weighted_stats(qsm, FUN = function(x) 3*(mean(x) - median(x)) / sd(x))

Load, Recenter, and Remove low vegetation from 'LAS' object representing segmented tree

Description

Function to normalize, remove noise, remove vegetation, and recenter 'LAS' representing segmented tree. Vegetation cleaning is accomplished by identifying stem points (CrownScrochTLS::StemPoints) and removing all but the Stem below the 'z.threshold'.

Usage

clean_las(las, bole_height = 1, quantile = 0.001)

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree

bole_height

numeric, height threshold below which all stem points can be considered vegetation.

quantile

See 'normalize_las'. Z quantile at which grown level is specified since ground points may not be identifiable with common algorithms if ground points are removed during segmentation#'

Value

A cleaned 'LAS' object with vegetation and noise removed, normalized and recentered.

Examples

library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las_cleaned = clean_las(las)

plot(las)
plot(las_cleaned)


Returns the convex hull representing vertical crown area

Description

This function generates an 'sf' object representing th vertical crown area of a 'LAS' object based using the convex hull of a 2D vertical projection.

Usage

convex_hull_2D(las, angle = 0)

Arguments

las

'LAS' object from 'lidR' package representing the CROWN of a tree. Crowns must be segmented using [segment_crown()].

angle

numeric - in degrees, rotation angle about Z axis.

Value

An 'sf' polygon representing the vertical convex hull of the crown projection.

Examples

las = lidR::readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las = clean_las(las)
cbh = get_crown_base(las, threshold=0.25, sustain=2)
las = segment_crown(las, cbh)
get_crown_volume_voxel(las)
get_crown_volume_alpha(las)
sf::st_area(convex_hull_2D(las)) #profile area, convex hull
sf::st_area(voxel_hull_2D(las)) #profile area, voxel hull
get_lacunarity(las)

Extract patch diameter parameters from a QSM filename

Description

Internal helper function to parse patch diameters (D, DI, DA) from a PyTLidar-generated QSM filename. Falls back to default values if not present.

Usage

extract_patch_params(
  filepath,
  default_patch1,
  default_patch2min,
  default_patch2max
)

Arguments

filepath

Character. Full path to the QSM file.

default_patch1

Numeric. Default value for D (patch_diam1).

default_patch2min

Numeric. Default value for DI (patch_diam2min).

default_patch2max

Numeric. Default value for DA (patch_diam2max).

Value

A named list with elements 'patch_diam1', 'patch_diam2min', and 'patch_diam2max'.


Fit taper equation to QSM

Description

This function fits a taper equation to trunk sections of a QSM using Kozak the Model (2002, 2007).

Usage

fit_taper_Kozak(
  qsm,
  dbh,
  terminus_diam_cm = 4,
  segment_size = 0.25,
  plot = TRUE
)

Arguments

qsm

a QSM loaded using '[load_qsm()]'.

dbh

numeric – required to fit Kozak model, not calculated from QSM, so as not to conflict with other more accurate means of measurement e.g., ‘get_DBH’

terminus_diam_cm

numeric – the trunk diameter at which is no longer considered trunk

segment_size

numeric – the length of segments that QSM cylinders are grouped into

plot

boolean – indicates whether model output should be plotted. Plots are found in the output list as object$plot, regardless of this setting.

Details

$ d(h)/D = a0 (h/H) + a1 (h/H) + a2 (h/H)^2 + a3 (h/H)^3 $

The function groups QSM cylinders into segments of 'segment_size' up to 'terminus_diam' which is the maximum diameter at which the taper equation ends.

Value

A list with components:

data

Tibble of trunk segment heights and observed diameters used in model fitting.

plot

A 'ggplot2' object showing observed diameters and fitted taper curve.

results

Data frame containing fitted Kozak parameters ('a0'–'a3'), coefficient of determination ('r2'), and root mean squared error ('rmse').

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
fit_taper_Kozak(qsm, dbh = 13.8)

Generate a diagnostic plot to assess basic metrics and QSM output

Description

Generate a diagnostic plot to assess basic metrics and QSM output

Usage

full_diagnostic_plot(las, qsm, height, cbh, crown_width, dbh, res = 0.1)

Arguments

las

'LAS' object from 'lidR' package representing the CROWN of a tree. Crowns can be segmented using [segment_crown()]

qsm

a QSM loaded using '[load_qsm()]'.

height

numeric - tree height, or generated from 'get_height()'

cbh

numeric - crown base heigth, or generated from 'get_crown_base()'.

crown_width

numeric - crown width height, or generated from 'get_width()'

dbh

numeric - in cm, tree diameter at breast height, or generated from 'get_dbh()'

res

numeric - resolution of voxelization to speed up plotting

Value

A multi-panel 'ggplot' object (class 'ggarrange') summarizing tree structural metrics and QSM diagnostics, suitable for printing or saving with 'ggplot2'.

Examples

library(lidR)
las_file = system.file("extdata", "tree_0744.laz", package="tReeTraits")
las = lidR::readLAS(las_file, filter = '-thin_with_voxel 0.1')
las = clean_las(las, bole_height=3)
height = get_height(las)
crown_width = get_width(las)
dbh = get_dbh(las, select_n=30)
cbh = get_crown_base(las, threshold=0.25, sustain=2)
las = segment_crown(las, cbh)
qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
full_diagnostic_plot(las=las, qsm=qsm, height=height, cbh=cbh, crown_width=crown_width, dbh=dbh)

Generate area estimates of tree profile in segments

Description

This function calculates the area of the tree profile by breaking it into segments of height 'segment_height' and estimating the width of each segement. Area profiles are useful for caluclating total area, but also used to detect crown base height.

Usage

get_area_profile(las, segment_height = 0.25, quantile = c(0.001), angle = 0)

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree, with the crown labeled.

segment_height

numeric - height of each segment in which to calculate area

quantile

numeric - quantile at which width is measured Values in the interval approaching 0 (e.g., 0.001) are recommended to trim random noise

angle

numeric - angle at which to rotate the point cloud prior to estimating area. Useful in a loop if quantifying mulitple angles

Value

A tibble with columns 'bottom', 'top', 'width', 'area', and 'angle' describing the vertical area profile.


Get center of mass from tree bole segments QSM (X, Y, Z)

Description

This function calculates the center of mass/volume from a QSM by estimating the centroid of cylinder locations, each weighted by their volume. Only trunk sections are included (e.g., 'branching_order == 0'). For center of mass, assumes constant density within segments.

Usage

get_center_of_mass(qsm)

Arguments

qsm

qsm object loaded from '[load_qsm]'.

Value

A tibble with one row and three numeric columns:

X

Volume-weighted X coordinate of the trunk center of mass (m).

Y

Volume-weighted Y coordinate of the trunk center of mass (m).

Z

Volume-weighted Z coordinate of the trunk center of mass (m).

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
print(get_center_of_mass(qsm))

Horizontal offset of center of mass from QSM

Description

This function extracts the horizontal distance between the base of a tree and the center of a tree from a QSM. The function takes the coordinate of the lowest QSM segment, and the center of mass, and finds the horizontal distance between them.

Usage

get_com_offset(qsm)

Arguments

qsm

a QSM loaded using '[load_qsm()]'.

Value

A single numeric value giving the horizontal distance (m) between the base of the tree and the volume-weighted center of mass.

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
print(get_center_of_mass(qsm))
print(get_com_offset(qsm))

Estimate Crown base height of 'LAS' representing segmented tree.

Description

This function estimates the crown base height by analyzing the vertical profile of the tree using [get_area_profile()] which breaks the profile into segments of height 'segment_height'. The function estimates segments exceed a threshold specified by 'threshold' which must be exceeded 'sustain' times.

Usage

get_crown_base(
  las,
  threshold = 0.5,
  sustain = 2,
  segment_height = 0.25,
  quantile = 0.01
)

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree

threshold

numeric - threshold width at which crown becomes apparent. Recommend a width ~2X greater than anticipated DBH.

sustain

numeric - number of segments in a row that treshold must be exceeded before identifying start of crown. This is to exclude small segments of crown isolated from larger continuous crown.

segment_height

numeric - height of each segment in which to calculate area

quantile

numeric - quantile at which width is measured Values in the interval approaching 0 (e.g., 0.001) are recommended to trim random noise

Value

A named numeric vector with element 'crown_base_height' (m).

Examples

# example code
library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package = "tReeTraits"))
las = clean_las(las)

# Estimate crown base height
cbh = get_crown_base(las)
print(cbh)

Calculate crown leverage from point cloud

Description

This function calculates the lever arm of canopies. The function #' is a simple wrapper for 'get_area_profile()'. It calculates the crown area in segments defined by 'segement_height', multiplies the area of each of those segments by their height, and then returns the sum of all segments. This is proportaionl to drag calculations on the tree assuming windspeed is invariant with height.

Usage

get_crown_lever_arm(las, segment_height = 0.25, quantile = c(0.001), angle = 0)

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree, with the crown labeled. See 'segment_crown()'

segment_height

numeric - height of each segment in which to calculate area

quantile

numeric - quantile at which width is measured Values in the interval approaching 0 (e.g., 0.001) are recommended to trim random noise

angle

numeric - angle at which to rotate the point cloud prior

to estimating area. Useful in a loop if quantifying mulitple angles

Value

A numeric value representing the crown lever arm.

Examples

library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las = clean_las(las)
las = segment_crown(las)
print(get_crown_lever_arm(las))

Estimate crown volume by alpha shape volume

Description

This function volume of a 'LAS' object by thinning to a resolution specified by 'resolution', and estimating volume by fitting a alpha shape volume. Crowns must be segmented using [segment_crown()].

Usage

get_crown_volume_alpha(las, resolution = 0.1, alpha = 0.5)

Arguments

las

'LAS' object from 'lidR' package representing a tree. Crowns must be segmented using [segment_crown()].

resolution

numeric - resolution of initial voxelization to increase speed

alpha

numeric - alpha for the computation of the 3D alpha-shape of the point cloud. See [alphashape3d::ashape3d].

Value

A named numeric vector with element 'crown_volume_alpha' (m^3).

Examples

las = lidR::readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
cbh = get_crown_base(las, threshold=0.25, sustain=2)
las = segment_crown(las, cbh)
get_crown_volume_voxel(las)
get_crown_volume_alpha(las)
sf::st_area(convex_hull_2D(las)) #profile area, convex hull
sf::st_area(voxel_hull_2D(las)) #profile area, voxel hull
get_lacunarity(las)

Estimate crown volume by voxelization

Description

This function volume of a 'LAS' object by thinning to a resolution specified by 'resolution', and estimating volume using the equation

Volume_{crown} = N_{occupied voxel} * Volume_{voxel}

Usage

get_crown_volume_voxel(las, resolution = 0.1)

Arguments

las

'LAS' object from 'lidR' package representing a tree. Crowns must be segmented using [segment_crown()].

resolution

numeric - resolution of voxelization

Value

A named numeric vector with element 'crown_volume_vox' (m^3).

Examples

las = lidR::readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las = clean_las(las)
cbh = get_crown_base(las, threshold=0.25, sustain=2)
las = segment_crown(las, cbh)
get_crown_volume_voxel(las)
get_crown_volume_alpha(las)
sf::st_area(convex_hull_2D(las)) #profile area, convex hull
sf::st_area(voxel_hull_2D(las)) #profile area, voxel hull
get_lacunarity(las)

Extract diameter at breast height from 'LAS' object representing segmented tree.

Description

Function to extract diameter at breast height (1.37 m) from LAS object. Function filters LAS keeping only points with Intensity greater than specified threshold. Function calculates verticality eigenvalue and filters based on verticality threshold. Last, diameter is calculated using a RANSAC cylinder fitting algorithm.

Usage

get_dbh(
  las,
  intensity_threshold = 41000,
  select_n = 10,
  verticality_threshold = 0.9
)

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree

intensity_threshold

numeric - filter value for Intensity to help remove vegetation

select_n

numeric - number of points selected on every RANSAC iteration.

verticality_threshold

numeric - filter value for Verticality threshold to remove horizontal branches.

Value

A named numeric vector with element 'dbh' (m).

Examples

library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las = clean_las(las)
print(get_dbh(las))

Extract height from 'LAS' object representing segmented tree.

Description

Function to extract height from LAS object. Function calculates difference between two specified quantiles from the 'Z' attribute.

Usage

get_height(las, quantiles = c(0, 1))

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree

quantiles

Z quantiles at which ground level and highest point are measured. Values in the interval (0,1) are recommended to trim random noise.

Value

A named numeric vector with element 'height' (m).

Examples

library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las = clean_las(las)
print(get_height(las))

Calculate crown lacunarity from a tree crown

Description

This function calculates the lacunarity or "porosity" of a tree crown by defined as 1 - the ratio of a voxelized crown hull and a convex hull. See 'voxel_hull_2D()' and 'convex_hull_2D()'

Usage

get_lacunarity(las, res = 0.1, angle = 0)

Arguments

las

'LAS' object from 'lidR' package representing the CROWN of a tree. Crowns must be segmented using [segment_crown()].

res

numeric - resolution of voxelization

angle

numeric - in degrees, rotation angle about Z axis.

Value

A numeric value representing crown lacunarity (unitless).

Examples

las = lidR::readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
cbh = get_crown_base(las, threshold=0.25, sustain=2)
las = segment_crown(las, cbh)
get_crown_volume_voxel(las)
get_crown_volume_alpha(las)
sf::st_area(convex_hull_2D(las)) #profile area, convex hull
sf::st_area(voxel_hull_2D(las)) #profile area, voxel hull
get_lacunarity(las)

Extract primary branches from a QSM

Description

Extract primary branches from a QSM by filtering out the the trunk, and identifying all cylinders where 'branching_order == 1' and are attached to the trunk. Returns a tibble containing the basal diameter and height of attachment points.

Usage

get_primary_branches(qsm)

Arguments

qsm

a QSM loaded using '[load_qsm()]'.

Value

A tibble with one row per primary branch containing:

section

Character string ("branches").

diam_cm

Basal diameter of the branch (cm).

ht_m

Height of branch attachment (m).

volume

Placeholder column (currently 'NA').

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
primary_branches = get_primary_branches(qsm)
#number of primary branches
nrow(primary_branches)

Calculate tree sweep from straight line from QMS

Description

This function calculates tree sweep from a QSM. Starting with an idealized vector of a straight tree (straight line from top to bottom QSM segment) the function caclucates devations of points along the trunk from the idealized vector. It resturns sweep from each QSM segment so that summary statistics can be computed by the user. See also 'get_stem_deflection()'

Usage

get_stem_sweep(qsm, terminus_diam_cm = 4, plot = TRUE)

Arguments

qsm

QSM loaded using '[load_qsm()]'.

terminus_diam_cm

numeric – the trunk diameter at which is no longer considered trunk

plot

boolean – indicates whether graph of sweep should be plotted.

Value

A data frame with columns:

Height

Height (m) of each trunk segment midpoint.

sweep

Perpendicular deviation (m) from the idealized straight stem line.

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
print(get_center_of_mass(qsm))
print(get_com_offset(qsm))

Get tree tilt from QSM

Description

This function calculates tilt of a tree from a QSM. The function identifies the upper and lower extreme segments of the QMS (trunk sections only) and computes a vector between them, and returns the devation of that angle from directly vertical.

Usage

get_stem_tilt(qsm, terminus_diam_cm = 4)

Arguments

qsm

a QSM loaded using '[load_qsm()]'.

terminus_diam_cm

numeric - trunk diameter at which it is treated as a branch.

Value

A single numeric value giving stem tilt in degrees from vertical.

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
get_stem_tilt(qsm)

Extract width from 'LAS' object representing segmented tree.

Description

Function to extract width from LAS object. Function calculates difference between two specified quantiles from the 'X' and 'Y' attributes and returns both widths and their average.

Usage

get_width(las, quantiles = c(0.001, 0.999))

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree

quantiles

Z quantiles at which widths are measured are measured. Values in the interval (0,1) are recommended to trim random noise.

Value

A named numeric vector with elements 'mean_width', 'x_width', and 'y_width' (m).

Examples

library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las = clean_las(las)
print(get_width(las))

Diagnostic Plot of Crown Convex Hulls

Description

Generates a 2D diagnostic plot to visualize the convex hulls and voxelized hulls of tree crowns in a LAS point cloud. Useful for checking results of crown segmentation.

Usage

hull_diagnostic_plot(las, res = 0.1)

Arguments

las

A 'LAS' object from the 'lidR' package. Must contain a column named 'Crown'.

res

Numeric. Resolution for voxelization in 'voxel_hull_2D()'. Default is 0.1.

Details

The function first filters points marked as crown ('Crown == 1') and then computes both the 2D convex hull and a voxelized 2D hull. The resulting plot overlays the voxel hull in color and the convex hull as a dashed outline.

Value

A 'ggplot' object displaying convex hulls (dashed) and voxel hulls (filled).

Examples

library(lidR)
file = system.file('extdata', file='tree_0744.laz', package='tReeTraits')
las <- readLAS(file)
las <- segment_crown(las)  # adds `Crown` column
hull_diagnostic_plot(las)

Get internode distances between primary branches from a QSM

Description

This function estimates the internode distance between primary branches from a QSM. It filters out all primary branches 'branching_order == 1' calculates their attachment points (Z) to the trunk, and then returns the distances betweent the branches

Usage

internode_distances(qsm, min_diam = 2)

Arguments

qsm

a QSM loaded using '[load_qsm()]'.

min_diam

numeric - minimum diameter (in cm) to include branch

Value

A numeric vector of internode distances (m) between consecutive primary branches that meet the diameter threshold. Returns 'NA' if fewer than two qualifying primary branches are present.

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
inodes = internode_distances(qsm)
print(inodes)
median(inodes)

Load and Validate a QSM File

Description

Reads a Quantitative Structure Model (QSM) file from disk and checks that it includes all required columns. If any expected columns are missing, the function stops with an informative error message.

Usage

load_qsm(path)

Arguments

path

Character string giving the path to a QSM text file.

Value

A tibble containing the QSM data.

A tibble containing the QSM data with validated required columns: 'startX', 'startY', 'startZ', 'endX', 'endY', 'endZ', 'cyl_ID', 'parent_ID', 'extension_ID', 'radius_cyl', 'length', 'volume', and 'branching_order'. An error is thrown if any required columns are missing.

Examples

qsm_path = system.file('extdata', 'tree_0744_qsm.txt', package='tReeTraits')
qsm <- load_qsm(qsm_path)
plot_qsm2d(qsm, scale=50)

Normalize 'LAS' object representing segmented tree.

Description

Function to normalize LAS object. Function calculates ground level based on the parameter specified by 'quantile', subtracts it from all 'Z'.

Usage

normalize_las(las, quantile = c(0.001))

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree

quantile

Z quantile at which grown level is specified since ground points may not be identifiable with common algorithms if ground points are removed during segmentation

Value

A 'LAS' object with Z values normalized to ground level.

Examples

library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
# view histogram of Z values ranging from  -18 to -7 m
hist(las$Z)
las = normalize_las(las)
# view histogram of Z values now ranging from  0 to 11 m
hist(las$Z)

Plot QSM in base R

Description

Simple function to create a diagnostic plot to view QSMs colored by branching order.

Usage

plot_qsm2d(qsm, scale = 150, rotation = TRUE)

Arguments

qsm

a QSM loaded using '[load_qsm()]'.

scale

a factor by which to multiply the 'radius_cyl' column to give line segments the appearance of volume

rotation

boolean - indicates whether the plot should display the tree from 2 angles TRUE, or just one FALSE.

Value

'NULL', invisibly. Produces a base R plot as a side effect.

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
plot_qsm2d(qsm)

Plot QSM Cylinders in 3D

Description

Renders a 3D visualization of tree cylinders (from a Quantitative Structure Model, QSM) using actual geometric radii. Each cylinder is drawn between its start and end coordinates with the radius provided in the QSM data.

Usage

plot_qsm3d(qsm, bg = "white", color = "black", alpha = 0.7)

Arguments

qsm

A data frame or tibble containing QSM cylinder data with columns: startX, startY, startZ, endX, endY, endZ, and radius_cyl.

bg

Background color for the 3D plot. Defaults to "white".

color

Cylinder color. Defaults to "black".

alpha

Transparency level for cylinders, between 0 (fully transparent) and 1 (fully opaque). Defaults to 0.7.

Details

This function uses rgl to draw 3D cylinders representing each segment of a tree model. It is intended for visualizing QSM output such as that produced by PyTLidar or other tree reconstruction algorithms.

For large models, rendering may be slow because each cylinder is drawn as a separate mesh. Consider downsampling or filtering before plotting.

Value

Opens an interactive 3D rgl window with rendered cylinders. Returns NULL invisibly.

A 'ggplot' object combining multiple diagnostic panels.

Examples

# Load QSM output (example path)
qsm_file = system.file('extdata',"tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
# Plot with real radii

plot_qsm3d(qsm, color = "forestgreen", alpha = 0.6)


Make 3-panel plot of tree point cloud to check for errors

Description

Plots 2 profiles X, Y, and and overhead Z view of a point cloud to allow users to identify stray points, or errors in segmentations.

Usage

plot_tree(las, res = 0.05, plot = TRUE)

Arguments

las

'LAS' object from 'lidR' package representing the CROWN of a tree. Crowns can be segmented using [segment_crown()].

res

numeric - resolution of voxelization to speed up plotting

plot

boolean - indicates whether to print the output plot, in both cases a ggplot object is returned in the output.

Value

A 'ggplot' object containing the arranged diagnostic panels.

Examples

# example code
library(lidR)
file = system.file("extdata", "tree_0744.laz", package="tReeTraits")
las = readLAS(file, filter = '-thin_with_voxel 0.1')
las = clean_las(las)
plot_tree(las)

Volume distribution from QSM

Description

This function estimates tree volume and its vertical distribution from a QSM. The function separates the QSM into (1) trunk sections (2) terminus (top of trunk < 4 cm dbh), and (3) primary branches. The function divides trunk into segments defined by 'segment_size', calculates QSM volume, For tree portions identified as branches the function only returns the diameter. Both of these can be used in mass-volume equations as needed.

Usage

qsm_volume_distribution(qsm, terminus_diam_cm = 4, segment_size = 0.5)

Arguments

qsm

a QSM loaded using '[load_qsm()]'.

terminus_diam_cm

numeric - trunk diameter at which it is treated as a branch.

segment_size

numeric length of trunk segments in which to summarize volume.

Value

A tibble describing vertical volume distribution with columns:

section

Tree component ("trunk", "terminus", or "branches").

diam_cm

Diameter (cm) of the segment or branch.

ht_m

Height (m) of the segment midpoint or branch attachment.

volume

Total volume (m^3) of the segment (trunk and terminus only; 'NA' for branches).

Examples

qsm_file = system.file("extdata", "tree_0744_qsm.txt", package='tReeTraits')
qsm = load_qsm(qsm_file)
volume = qsm_volume_distribution(qsm)
print(volume)
plot(volume~ht_m, data=volume, type='l', xlab='height (m)', ylab='Volume (m3)')

Recenter 'LAS' object representing segmented tree based on the bole location

Description

Function calculates the tree location using points below specified 'height' and recenters on 'X=0 Y=0'

Usage

recenter_las(las, height = 1)

Arguments

las

'LAS' object from 'lidR' package representing

height

consider only points where Z < height, if specified. Useful for considering only the tree bole, for centering. individually segmented tree. Set 'height = NULL' to recenter using all points.

Value

A 'LAS' object with X and Y coordinates recentered to (0, 0).

Examples

library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
# view histogram of original X/Y values
par(mfrow=c(1,2))
hist(las$X)
hist(las$Y)
las = recenter_las(las)
# view histogram of X/Y values centered on 0,0
hist(las$X)

hist(las$Y)

Rotate 'LAS' object about the 'Z' axis

Description

Rotate 'LAS' object about the 'Z' axis for specified angle.

Usage

rotate_las_z(las, angle)

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree

angle

numeric - in degrees, rotation angle about Z axis.

Value

A 'LAS' object rotated about the Z axis.

Examples

library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las_rotated = rotate_las_z(las, 90)

plot(las)
plot(las_rotated)


Run TreeQSM on a LAS/LAZ file using PyTLidar

Description

Processes a point cloud, filters and normalizes it, then runs the PyTLidar TreeQSM model to reconstruct cylinders representing the tree structure.

Usage

run_treeqsm(
  file,
  output_dir = NULL,
  intensity_threshold = 40000,
  resolution = 0.02,
  patch_diam1 = c(0.05, 0.1),
  patch_diam2min = c(0.04, 0.05),
  patch_diam2max = c(0.12, 0.14),
  optimizing_metrics = c("TrunkMean", "Branch1Mean"),
  verbose = TRUE
)

Arguments

file

Path to the input LAS or LAZ file.

output_dir

Directory to save output files; temporary if NULL.

intensity_threshold

Minimum point intensity to retain.

resolution

Thinning voxel size (m).

patch_diam1

Numeric vector of patch diameter 1 parameters.

patch_diam2min

Numeric vector of minimum patch diameter 2.

patch_diam2max

Numeric vector of maximum patch diameter 2.

optimizing_metrics

Character vector of metric names to average and minimize when selecting the best QSM fit. See Details

verbose

Logical; whether to print details during processing.

Details

The optimizing_metrics argument controls which point-to-cylinder distance summaries are used to evaluate TreeQSM fits. These metrics quantify how closely reconstructed cylinders match the underlying point cloud and are computed for different structural components of the tree.

Available metrics include:

When multiple metrics are supplied, their row-wise mean is computed and minimized to select the best-fitting QSM, allowing users to balance fit quality across different tree components.

Value

A list with elements:

A list with elements:

qsm_pars

Data frame of patch parameters and fit metrics.

qsm

Data frame of cylinder-level QSM output.

Examples

## Not run: 
file <- system.file("extdata", "tree_0744.laz", package="tReeTraits")
run_treeqsm(file)

## End(Not run)

Segment tree crown of 'LAS' representing segmented tree.

Description

This function labels all points with $Z > 'crown_base_height'$ and returns a labled LAS. If 'crown_base_height' is not specified, it is estimated with [get_crown_base()] using default parameters.

Usage

segment_crown(las, crown_base_height = NULL)

Arguments

las

'LAS' object from 'lidR' package representing individually segmented tree

crown_base_height

numeric - height of crown base for segmentation. 'NULL', it is estimated with [get_crown_base()] using default parameters.

Value

The input 'LAS' object with a new attribute 'Crown' (1 = crown, 0 = non-crown).

Examples

library(lidR)
las = readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las = clean_las(las)
las = segment_crown(las)

#Plot with color based on crown
plot(las, color='Crown')


Setup PyTLidar Python environment

Description

Ensures Python 3.11 is available via conda, creates 'r-reticulate-pytlidar' environment if needed, activates it, and installs required Python modules for PyTLidar.

Usage

setup_pytlidar()

Details

This function **must be called manually** before using any Python-dependent functions.

Value

'TRUE' if the environment is successfully activated and all required Python modules are available, 'FALSE' if installation of Miniconda was required and R should be restarted.

Examples

## Not run: 
setup_pytlidar()

## End(Not run)

Diagnostic Plot of Tree Taper

Description

Generates a diagnostic plot showing the fitted taper of a tree using the Kozak model. This is a simple wrapper around 'fit_taper_Kozak()' to extract its plot output.

Usage

taper_diagnostic_plot(qsm, dbh)

Arguments

qsm

A QSM object (e.g., data frame returned by 'run_treeqsm()') containing cylinder information.

dbh

Numeric. Diameter at breast height of the tree, used as input to the taper function.

Details

The function calls 'fit_taper_Kozak()' with 'plot = FALSE' and returns the plot component. This allows quick visualization of the taper without modifying the underlying QSM.

Value

A 'ggplot' object showing the fitted taper along the tree stem.

Examples

path = system.file('extdata', 'tree_0744_qsm.txt', package='tReeTraits')
qsm = load_qsm(path)
taper_diagnostic_plot(qsm, dbh = 0.25)

Returns an 'sf'representing the vertical crown area from voxelization

Description

This function generates an 'sf' object representing th vertical crown area of a 'LAS' object by voxelizing a 2D vertical projection.

Usage

voxel_hull_2D(las, resolution = 0.1, angle = 0)

Arguments

las

'LAS' object from 'lidR' package representing the CROWN of a tree. Crowns must be segmented using [segment_crown()].

resolution

numeric - resolution of voxelization

angle

numeric - in degrees, rotation angle about Z axis.

Value

An 'sf' polygon representing the voxel-based vertical crown hull.

Examples

las = lidR::readLAS(system.file("extdata", "tree_0744.laz", package="tReeTraits"))
las = clean_las(las)
cbh = get_crown_base(las, threshold=0.25, sustain=2)
las = segment_crown(las, cbh)
get_crown_volume_voxel(las)
get_crown_volume_alpha(las)
sf::st_area(convex_hull_2D(las)) #profile area, convex hull
sf::st_area(voxel_hull_2D(las)) #profile area, voxel hull
get_lacunarity(las)

Save QSM results and patch parameters

Description

Writes QSM cylinder data and parameter summaries to tab-delimited text files.

Usage

write_qsm(qsm, name, output_dir = getwd())

Arguments

qsm

Output from run_treeqsm(); a list with qsm and qsm_pars.

name

Base name to use for output files.

output_dir

Directory where files are written (defaults to current working directory).

Value

Invisibly returns a list with file paths:

Examples

## Not run: 
# Run and Load a qsm from a laz file.
# ---- Step 1. Define input file  ----
# Input file
file <- system.file("extdata", "tree_0744.laz", package = "tReeTraits")
tree_id <- tools::file_path_sans_ext(basename(file))

# ---- Step 2. Run TreeQSM ----
# Multiple parameter combinations can be supplied; TreeQSM optimizes across them
qsm_result <- run_treeqsm(
  file = file,
  intensity_threshold = 40000,
  resolution = 0.02,
  patch_diam1 = c(0.05, 0.1),
  patch_diam2min = c(0.04, 0.05),
  patch_diam2max = c(0.12, 0.14),
  verbose = TRUE
)

# ---- Step 3. Save results ----
write_qsm(
  qsm_result,
  name = tree_id,
  output_dir = tempdir()
)

# ---- Step 4. Reload QSM ----
qsm_path <- file.path(tempdir(), paste0(tree_id, "_qsm.txt"))
qsm <- load_qsm(qsm_path)

# ---- Step 5. Visualize ----
plot_qsm2d(qsm, scale = 50)
plot_qsm3d(qsm)
## End(Not run)

mirror server hosted at Truenetwork, Russian Federation.