Counts the voxels of neighboring trees that intersect a search cone or search cylinder around the target tree according to Seidel et al. (2015) and Metz et al. (2013).
Usage
compete_pc(
forest_source,
tree_source,
comp_method = c("cone", "cylinder", "both"),
center_position = c("crown_pos", "base_pos"),
tree_name = NULL,
cyl_r = 5,
h_cone = 0.6,
z_min = 100,
h_xy = 0.3,
acc_digits = 2,
res = 0.1,
print_progress = c("some", "full", "none"),
override_pos_check = FALSE,
...
)
Arguments
- forest_source
path to file of neighborhood point cloud or data.frame or LAS object (see lidR::LAS) with point cloud data which are passed on to
read_pc()
, or object of classforest_pc
as created withread_pc()
. The neighborhood can, but does not have to include the target tree itself, should not be height normalized, and can include ground points. Coordinates have to be in a Cartesian coordinate system in m. For paths to source files, the supported formats are are .las, .laz, .ply as well as all formats accepted bydata.table::fread()
(.csv, .txt, and others). If supplied as an object of classforest_pc
, arguments passed toread_inv()
are ignored.- tree_source
path to file of the point cloud of the segmented target, tree or data.frame or LAS object (see lidR::LAS) with point cloud data which are passed on to
read_pc()
, or object of classforest_pc
as created withread_pc()
. Coordinates have to be in the same coordinate system asforest_source
. For paths to source files, the supported formats are are .las, .laz, .ply and formats accepted bydata.table::fread()
. If supplied as an object of classforest_pc
, arguments passed toread_inv()
are ignored.- comp_method
character string of length 1 with competition method. Allowed values are "cone" for the cone method, "cylinder" for the cylinder method or "both" for both methods. Default is the cone method. See details for computation.
- center_position
character string of length 1 with the position used as the center of the search cone/cylinder. Allowed values are "crown_pos" for the central point of the crown projected area and "base_pos" for the stem base position as computed by
tree_pos()
. Default value is "crown_pos".- tree_name
(optional) ID for the tree. If no argument is put, defaults to the name of the argument provided as
tree_source
.- cyl_r
numeric of length one. Size of the cylinder radius in m. Default is 5 m. Only used when
comp_method = "cylinder"
.- h_cone
numeric of length one. Faction of the height of the tree where the tip of the search cone is located. For example, values of 0.5 or 0.6 specify that the cone opens in 50 or 60 % of the height of the target tree, respectively. Default is 0.6 (see Seidel et al., 2015). Only used when
comp_method = "cone"
.- z_min
integer of length 1 describing the minimum number of points needed in the lowermost 1 voxel depth Z layer to consider it part of the target tree. Default is 100. If changing the voxel resolution (
res
) from the default value of 0.1, different settings may be necessary. Used to calculate the stem base position of the target tree. For details seetree_pos()
.- h_xy
numeric of length 1 describing the height range in m over the stem base over which the x and y positions are used to calculate the x and y coordinates of the stem base of the target tree. Default is 0.3 m. Used to calculate the stem base position of the target tree. For details see
tree_pos()
.- acc_digits
integer of length 1 defining the accuracy of the point cloud measurements. The data will be aggregated to this number of digits to speed up calculations and avoid problems with joining tree and neighborhood data resulting from numeric accuracy. The resolution of the coordinates defined by
acc_digits
should alway be at least one order of magnitude higher than the resolutionres
used to compute the voxel counts in later steps. Defaults toacc_digits = 2
(round to 2 digits after the decimal point).- res
numeric of length 1 defining the resolution of a voxel as passed on to
VoxR::vox()
. Defaults to 0.1 (10 cm voxel size). Only change if there are good reasons to do so as this is the standard used in Seidel et al. (2015) and other papers and the results are strongly scale dependent!- print_progress
character of length 1. Allowed values are "full" (print all progress and full output), "some" (only print main details) and "none" (do not print any progress). Defaults to "some".
- override_pos_check
logical: should the function test if the target tree is actually situated within the neighborhood? Defaults to FALSE. Only change if you have very good reasons to do so, e.g., when computing the competition for a tree situated at the edge of a forest stand.
- ...
additional arguments passed on to
data.table::fread()
.
Value
object of type compete_pc
: modified data.frame
with tree ID,
tree height, the type of center position used for computation as well as
counts of the number of voxels of the neighborhood point cloud that reach
into the cone/cylinder spanned over/around the target tree.
Details
compete_pc()
computes competition indices based on voxel counts of
neighbor trees that intersect a search cone or search cylinder around
the target tree. In most cases, the function read_pc()
that is called
internally should be able to automatically identify the columns with the
coordinates of the point clouds when provided with non-standard file types.
If this is not the case, it is possible to provide arguments to pass on to
that function, to load the datasets separately with custom settings with
read_pc()
or loading them with external functions and pass them to
compete_pc()
as any kind of object inheriting from data.frame
(such as
base R data.frames, tibbles, data.tables etc).
Cone Method
Based on a search cone with an opening angle of 60 degrees,
by default opening from a basal point situated at 60 % of the
height of the target tree. The competition index is defined as the number
of voxels of neighboring trees (by default, with a 0.1 m res.) situated
within the cone spanned around the target tree (cf. Metz et al 2013;
Seidel et al., 2015).
The standard value of h_cone = 0.6
can be adjusted, for instance if no
neighbor trees at all intersect the cone of the target tree. However, be
careful with adjusting this parameter, as competition indices computed with
different h_cone
cannot easily be compared among each other.
Cylinder Method
Based on a search cylinder with a pre-defined radius cyl_r
around the
target tree (5 m by default). The competition index is defined as the
number of the voxels of neighboring trees (by default, with a 0.1 m res.)
situated within the cylinder around the target tree (cf. Seidel et al.,
2015). The index is sensitive to the choice of the cylinder radius, so be
careful when comparing competition indices computed with different values
of cyl_r
.
Both indices are highly sensitive to the voxel resolution, and it is not
recommended to change res
from its default value of 0.1 (i.e., 10 cm
voxel size) unless you have very good reasons to do so.
If calculating competition indices for single trees that each have an
accompanying point cloud of their immediate neighborhood, using the file
paths to these datasets as a tree_source
/ neighbor_source
will be
computationally efficient. However, when calculating indices for several
trees belonging to the same neighborhood, it may be faster to load the
neighborhood outside compete_pc()
a single time using read_pc()
and
then passing it to compete_pc()
as a forest_pc
object as this reduces
the computational overhead due to loading the point cloud into the memory.
In such cases, it may also make sense to load and process the forest point
cloud as an LAS object (see lidR::LAS) and process it outside of
TreeCompR
before analysis.
If the source files are very large, this may still lead to memory problems
especially on machines with low RAM capacity. In such cases, it may make
more sense to split up the data set into smaller chunks outside R that
each cover only a subset of the target trees to reduce the memory load.
Note: support of .las, .laz and .ply formats
The lidR
package has to be installed to be able to read in .las/.laz
files, which are internally processed by lidR::readTLSLAS()
.
Analogously, for point clouds in the .ply format, the Rvcg
package is
required as these are loaded with Rvcg::vcgPlyRead()
.
Literature
Metz, J., Seidel, D., Schall, P., Scheffer, D., Schulze, E.-D. & Ammer, C. (2013). Crown modeling by terrestrial laser scanning as an approach to assess the effect of aboveground intra- and interspecific competition on tree growth. Forest Ecology and Management,310:275-288. https://doi.org/10.1016/j.foreco.2013.08.014
Pretzsch, H., Biber, P. & Dursky, J. (2002). The single tree-based stand simulator SILVA: construction, application and evaluation. For. Ecol. Manage. 162, 3-21. https://doi.org/10.1016/S0378-1127(02)00047-6
Seidel, D., Hoffmann, N., Ehbrecht, M., Juchheim, J. & Ammer, C. (2015). How neighborhood affects tree diameter increment - New insights from terrestrial laser scanning and some methodical considerations. Forest Ecology and Management, 336: 119-128. http://dx.doi.org/10.1016/j.foreco.2014.10.020
See also
read_pc()
for details on reading point clouds, tree_pos()
for
computing tree position from point cloud objects. See pc approach
for details on how to pre-process the point clouds for this function.
Examples
if (FALSE) { # \dontrun{
# Due to the large required datasets it is not possible to provide running
# examples, but we hope that these example uses are helpful
# Quantifying crown competition for a single tree using the cone method
CI_cone <- compete_pc("path/to/forest_pc.las", "path/to/tree_pc.las",
"cone", h_cone = 0.5)
# Competition for a single tree using the cylinder method with 4 m radius
CI_cyl <- compete_pc("path/to/forest_pc.ply", "path/to/tree_pc.ply",
"cylinder", cyl_r = 4)
# Quantifying competition for a single tree using both methods
CI_cyl <- compete_pc("path/to/forest_pc.txt", "path/to/tree_pc.txt",
"cylinder", cyl_r = 4, h_cone = 0.6)
# Loading a large neighborhood outside compete_pc() to reuse the data for
# several target trees
# load neighborhood
neigh <- read_pc("path/to/forest_pc.las")
# get paths to trees
tree_paths <- list.files("folder_with_trees/")
# map over paths to get competition indices for all trees
library(tidyverse) # for purrr() and bind_rows()
CI_data <- map(
tree_paths,
~compete_pc(
forest_source = neigh,
tree_source = file.path("folder_with_trees", .x),
tree_name = .x,
comp_method = "cone"
)
) %>%
bind_rows()
} # }