“The science of today is the technology of tomorrow.” Edward Teller

The gapfraction package for R was designed for modeling understory light in forests with light-detection-and-ranging (LiDAR) data. In addition to metrics of canopy gap fraction (\(P_o\)), angular canopy closure (ACC), and vertical canopy cover (VCC), the package implements a new canopy height model (CHM) algorithm, popular individual tree crown (ITC) detection algorithms, and a number of other algorithms that produce useful features for statistical modeling, including the distance of trees from plot center.

While the package was originally intended for processing airborne laser scanning (ALS) data, most of its functions may work for terrestrial laser scanning (TLS) data. The package was produced for one chapter of Adam Erickson’s doctoral thesis at University of British Columbia1. The gapfraction package is designed to be used with LAS or LAZ format point cloud data pre-processed with LAStools2, USDA Fusion3, or the new lidR package from Jean-Romain Roussel4. The package also accepts LAS objects imported from rLiDAR by Carlos Silva5.

The main input to functions are height-normalized point clouds in LAS or LAZ format, typically LiDAR plots corresponding to field plots of similar size. The functions are designed to accept file paths or data.frame/data.table objects imported with the lidR or rLiDAR packages. Functions automatically detect whether a path or object is input for the las parameter. If using objects created from LAS/LAZ files, the column order and naming conventions must follow those of lidR and rLiDAR, which together provide a standardized object API for LiDAR data in R, based on the ASPRS LAS specification 1.4. It is highly recommended to use either lidR in R or LAStools in CLI. For more information on these, view the pre-processing page on this site.

Getting started


Microsoft R Open is recommended for its MKL-optimized algebra libraries. To install the gapfraction package, you may need to have a working development environment, as the package depends on the lidR package. Required software for a working development environment is listed below.

  • Windows: Rtools.exe
  • Mac: Xcode
  • Linux: R development branch (e.g., r-devel or r-base-dev)

Next, install gapfraction from the R command line:

devtools::install_github("adam-erickson/gapfraction", dependencies=TRUE)

If you're starting with a fresh install of R, you may need to first install the R6 and curl packages manually from CRAN or MRAN.

Example data

After loading the gapfraction package with library(gapfraction), the example data can be loaded by calling data(las). The included data consists of an example 100-meter circular radius LiDAR plot with synthetic \(X,Y,Z\) coordinates in UTM 11N and height in meters, along with 8-bit unsigned interger values for intensity and return number. Based on previous research, I recommend using plots minimally of this size for comparison to ground data (e.g., hemispherical photography) to capture edge effects.

Let’s get started!

X Y Z Intensity ReturnNumber
272568.2 3882445 10.55 2 1
272568.6 3882446 9.24 4 1
272568.7 3882446 11.76 22 1
272568.7 3882446 0.00 14 2
272568.0 3882448 6.16 13 1
272568.3 3882448 11.18 32 1
272568.1 3882448 10.30 26 1
272568.7 3882450 0.00 3 2
272568.7 3882449 0.47 15 2
272568.2 3882450 14.37 27 1

Once the data is loaded, you can proceed to call functions from the gapfraction package.

Example usage

Computing hemispherical Voronoi gap fraction

P.hv(las=las, model="equidist", thresh.val=1.25, thresh.var="height", reprojection=NA,
     pol.deg=5, azi.deg=45, col="height", plots=T, plots.each=F, plots.save=F)
## [1] 0.4943591

Comparison of canopy height model (CHM) algorithms

## class       : RasterLayer 
## dimensions  : 100, 100, 10000  (nrow, ncol, ncell)
## resolution  : 0.98802, 0.987822  (x, y)
## extent      : 272568.5, 272667.4, 3882398, 3882496  (xmin, xmax, ymin, ymax)
## coord. ref. : NA 
## data source : in memory
## names       : layer 
## values      : 0, 21.83  (min, max)
## class       : RasterLayer 
## dimensions  : 100, 100, 10000  (nrow, ncol, ncell)
## resolution  : 0.98802, 0.987822  (x, y)
## extent      : 272568.5, 272667.4, 3882398, 3882496  (xmin, xmax, ymin, ymax)
## coord. ref. : NA 
## data source : in memory
## names       : index_1 
## values      : 0, 20.41133  (min, max)

Performing individual tree crown (ITC) detection on a CHM with the standard variable-window and watershed algorithms; both allow user-provided height-to-crown-radius functions

mw   <- itc.mw(chm, ht2rad=function(x) 0.15746*x)
wat  <- itc.wat(chm, ht2rad=function(x) 0.15746*x)

Creating a stacked pit-free CHM and performing individual tree crown (ITC) detection with the hierarchical variable-window and watershed algorithms; these also allow users to input empirical height-to-crown-radius functions

mw   <- itc.mw.h(chm, ht2rad=function(x) 0.15746*x, silent=TRUE)
wat  <- itc.wat.h(chm, ht2rad=function(x) 0.15746*x, silent=TRUE)

The itc algorithms store values for trees and crown.area in a two-element named numeric vector.

Please submit any issues or pull requests at the gapfraction page on GitHub at adam-erickson/gapfraction.

  1. Erickson, A. (2017) A hybrid modeling approach to simulating past-century understory solar irradiation in Alberta, Canada. University of British Columbia.

  2. LAStools: http://rapidlasso.com/lastools/

  3. USDA Fusion: http://forsys.cfr.washington.edu/fusion/fusionlatest.html

  4. lidR: https://github.com/Jean-Romain/lidR

  5. rLiDAR: https://cran.r-project.org/web/packages/rLiDAR/index.html