Skip to contents

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 class forest_pc as created with read_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 by data.table::fread() (.csv, .txt, and others). If supplied as an object of class forest_pc, arguments passed to read_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 class forest_pc as created with read_pc(). Coordinates have to be in the same coordinate system as forest_source. For paths to source files, the supported formats are are .las, .laz, .ply and formats accepted by data.table::fread(). If supplied as an object of class forest_pc, arguments passed to read_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 see tree_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 resolution res used to compute the voxel counts in later steps. Defaults to acc_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()
} # }