Estimates the canopy structure from a discrete returns scan from different TLS.
canopy_structure(
TLS.type,
scan,
zenith.range,
zenith.rings,
azimuth.range,
vertical.resolution,
TLS.pulse.counts,
TLS.resolution = NULL,
TLS.coordinates = c(0, 0, 0),
TLS.frame = NULL,
TLS.angles = NULL,
threads = 1
)
A character
describing is the TLS used. It most be one of "single"
return, "multiple"
return, or "fixed.angle"
scanner.
If TLS.type
is equal to "single"
or "fixed.angle"
, a data.table
with three columns describing *XYZ* coordinates of the discrete return. If
TLS.type
is equal to "multiple"
, a data.table
with four columns describing *XYZ* coordinates and the target count pulses. Currently, "fixed.angle"
present errors, use with discretion.
If TLS.type
is equal to "single"
or "multiple"
, a numeric
vector of length two describing the min
and max
range of the zenith angle to use.
Theoretically, the max
range should be lower than 90 degrees.
If TLS.type
is equal to "single"
or "multiple"
, a numeric
vector of length one describing the number of zenith rings to use between zenith.range
.
This is used to estimate the frequency of laser shots from the scanner and returns in scan
. If TLS.type = "fixed.angle"
, zenith.rings = 1
be default.
A numeric
vector of length two describing the range of the azimuth angle to use. Theoretically, it should be between 0 and 360 degrees.
A numeric
vector of length one describing the vertical resolution to extract the vertical profiles. Low values lead to more variable profiles.
The scale used needs to be in congruence with the scale of scan
.
If TLS.type
is equal to "single"
or "multiple"
, a numeric
vector of length two describing the horizontal and vertical pulse counts of the scanner.
If TLS.type
is equal to "fixed.angle"
, a numeric
vector of length one describing the horizontal pulse counts resolution.
Preferred parameter over TLS.resolution
to estimate the number of pulses.
If TLS.pulse.counts = NULL
, the code use the angles resolution to estimate the pulse counts in a given TLS.frame
. If TLS.type
is equal to "single"
or "multiple"
, a numeric
vector of length two describing the horizontal and vertical angle resolution of the scanner.
If TLS.type
is equal to "fixed.angle"
, a numeric
vector of length one describing the horizontal angle resolution.
A numeric
vector of length three describing the scanner coordinates within scan
.
It assumes that the coordinates are c(X = 0, Y = 0, Z = 0)
for default.
If TLS.type
is equal to "single"
or "multiple"
, a numeric
vector of length four describing the min
and max
of the zenith and azimuth angle of the scanner frame.
If TLS.type = "fixed.angle"
, a numeric
vector of length three describing the fixed zenith angle and the min
and max
of the azimuth angle of the scanner frame.
If NULL
, it assumes that a complete hemisphere (c(zenith.min = 0, zenith.max = 90, azimuth.min = 0, azimuth.max = 360)
), or a cone projection (c(zenith = 57.5, azimuth.min = 0, azimuth.max = 360)
) depending on TLS.type
.
A numeric
vector of length three describing the roll (*X*), pitch (*Y*), and yaw (*Z*) angles of the scanner during the scan.
If NULL
, it assumes that there is no need to to correction of angles.
This needs to be used if TLS.type
is equal to "single"
or "multiple"
, since it assumes that "fixed.angle"
scanner is previously balanced. NULL
as default.
An integer
specifying the number of threads to use. Experiment to see what works best for your data on your hardware.
For any TLS.type
, it returns a data.table
with the height profiles defined by vertical.resolution
, the gap probability based on the zenith.range
and zenith.rings
, and
the accumulative L(z) profiles based on the closest zenith ring to 57.5 degrees (hinge angle). If TLS.type
is equal to "fixed.angle"
, it returns f(z) or commonly named PAVD based on
on the ratio of the derivative of L(z) and the derivative of height (z). If TLS.type
is equal to "single"
or "multiple"
, it returns the normalized average weighting L/LAI, and PAVD: based
on the L (hinge angle) at the highest height and the ratio between the derivative of L/LAI average weighted and the derivative of z.
Since scan
describes discrete returns measured by the TLS, canopy_structre
first simulates the number of pulses emitted based on Danson et al. (2007). The simulated pulses are
created based on the TLS properties (TLS.pulse.counts, TLS.resolution, TLS.frame
) assuming that the scanner is perfectly balance. Then these pulses are rotated (rotate3D
) based on the TLS.angles
roll, pitch, and yaw, and move to TLS.coordintates
to simulate the positioning of the scanner during the scan
. Rotated simulated-pulses of interest and scan
returns are then extracted based on the zenith.range
and azimuth.range
for a given number of zenith.rings
, azimuth.rings
and vertical profiles.
The probability of gap (Pgap) is then estimated using the frequency of pulses and returns. For TLS.type = "multiple"
, the frequency of returns is estimated using the sum of 1/target count following Lovell et al. (2011).
Using the Pgap estimated per each zenith ring and vertical profile, canopy_structure
then estimates the accumulative L(z) profiles based on the closest
zenith ring to 57.5 (hinge region) and, if TLS.type = "fixed.angle"
, the f(z) or commonly named PAVD based on the ratio of the
derivative of L(z) and height (z) following Jupp et al. 2009 (Equation 18). If TLS.type
is equal to "single"
or "multiple"
, canopy_structure
also
estimates the normalized average weighted L/LAI, and then PAVD based on the L (hinge angle) at the highest height (LAI) and the ratio between the derivative
of L/LAI (average weighted) and the derivative of z (Jupp et al. 2009; Equation 21).
Jupp et al. 2009 excludes the zero zenith or fist ring to conduct the average weighted L/LAI estimations, canopy_structre
does not excludes this sections since it depends on the regions of interest of the user.
Therefore, user should consider this difference since it may introduce more variability to profile estimations.
Danson F.M., Hetherington D., Morsdorf F., Koetz B., Allgower B. 2007. Forest canopy gap fraction from terrestrial laser scanning. IEEE Geosci. Remote Sensing Letters 4:157-160. doi: 10.1109/LGRS.2006.887064
Lovell J.L., Jupp D.L.B., van Gorsel E., Jimenez-Berni J., Hopkinson C., Chasmer L. 2011. Foliage profiles from ground based waveform and discrete point LiDAR. In: SilviLaser 2011, Hobart, Australia, 16–20 October 2011.
Jupp D.L.B., Culvenor D.S., Lovell J.L., Newnham G.J., Strahler A.H., Woodcock C.E. 2009. Estimating forest LAI profiles and structural parameters using a ground-based laser called “Echidna®”. Tree Physiology 29(2): 171-181. doi: 10.1093/treephys/tpn022
# \donttest{
data(TLS_scan)
#Using a multiple return file
#Select the four columns required
TLS_scan <- TLS_scan[, 1:4]
#This will take a while#
a <- canopy_structure(TLS.type = "multiple",
scan = TLS_scan,
zenith.range = c(50, 70),
zenith.rings = 4,
azimuth.range = c(0, 360),
vertical.resolution = 0.25,
TLS.pulse.counts = c(2082, 580),
TLS.frame = c(30, 130.024, 0, 359.90),
TLS.angles = c(1.026, 0.760, -110.019))
#Using a single return file
data(TLS_scan)
#Subset to first return observations
TLS_scan <- TLS_scan[Target_index == 1, 1:3]
#> Error in .checkTypos(e, names_x): Object 'Target_index' not found amongst X, Y, Z, Target_count
#This will take a while#
canopy_structure(TLS.type = "single",
scan = TLS_scan,
zenith.range = c(50, 70),
zenith.rings = 4,
azimuth.range = c(0, 360),
vertical.resolution = 0.25,
TLS.pulse.counts = c(2082, 580),
TLS.frame = c(30, 130.024, 0, 359.90),
TLS.angles = c(1.026, 0.760, -110.019))
#> height Pgap(52.5) Pgap(57.5) Pgap(62.5) Pgap(67.5) L (hinge)
#> 1: 0.25 1.00000000 1.00000000 1.0000000 1.0000000 0.00000000
#> 2: 0.50 1.00000000 1.00000000 1.0000000 0.9764347 0.00000000
#> 3: 0.75 0.99818031 0.97200862 0.9672550 0.9281773 0.03122967
#> 4: 1.00 0.98459764 0.92356646 0.9212362 0.8729762 0.08746377
#> 5: 1.25 0.94280979 0.85510441 0.8373519 0.7223373 0.17218487
#> 6: 1.50 0.92588019 0.80260192 0.7051786 0.5266560 0.24188607
#> 7: 1.75 0.82755203 0.65435863 0.5908526 0.4360572 0.46650968
#> 8: 2.00 0.74826561 0.58629433 0.4879443 0.3728684 0.58732668
#> 9: 2.25 0.63084697 0.45266821 0.3863783 0.3421441 0.87185543
#> 10: 2.50 0.48523940 0.38261518 0.3260419 0.2860812 1.05679810
#> 11: 2.75 0.40296349 0.27543918 0.2677438 0.2394478 1.41832729
#> 12: 3.00 0.34656940 0.21761684 0.2330599 0.1870805 1.67752133
#> 13: 3.25 0.31087426 0.19022207 0.2074737 0.1616260 1.82551938
#> 14: 3.50 0.25394401 0.17048392 0.1750104 0.1474073 1.94602570
#> 15: 3.75 0.21595802 0.14526019 0.1437070 0.1421706 2.12215159
#> 16: 4.00 0.20278152 0.10790520 0.1326705 0.1409443 2.44915240
#> 17: 4.25 0.16398317 0.08945973 0.1233574 0.1406128 2.65536339
#> 18: 4.50 0.14835334 0.06872721 0.1158174 0.1406128 2.94537106
#> 19: 4.75 0.13751645 0.05619821 0.1105311 0.1405631 3.16675741
#> 20: 5.00 0.12871046 0.04255883 0.1099843 0.1405631 3.47255463
#> 21: 5.25 0.11623260 0.03559828 0.1098848 0.1405631 3.66900386
#> 22: 5.50 0.10573689 0.03395757 0.1098848 0.1405631 3.72090770
#> 23: 5.75 0.08919722 0.03002983 0.1098848 0.1405631 3.85612043
#> 24: 6.00 0.07704431 0.02512430 0.1098848 0.1405631 4.05231194
#> 25: 6.25 0.07124405 0.02499171 0.1098848 0.1405631 4.05813206
#> 26: 6.50 0.06901818 0.02492542 0.1098848 0.1405631 4.06105371
#> 27: 6.75 0.06659735 0.02492542 0.1098848 0.1405631 4.06105371
#> 28: 7.00 0.06575249 0.02477627 0.1098848 0.1405631 4.06765593
#> 29: 7.25 0.06557377 0.02466026 0.1098848 0.1405631 4.07281853
#> 30: 7.50 0.06549253 0.02466026 0.1098848 0.1405631 4.07281853
#> 31: 7.75 0.06549253 0.02466026 0.1098848 0.1405631 4.07281853
#> 32: 8.00 0.06549253 0.02466026 0.1098848 0.1405631 4.07281853
#> height Pgap(52.5) Pgap(57.5) Pgap(62.5) Pgap(67.5) L (hinge)
#> L/LAI (weighted mean) PAVD
#> 1: 0.000000000 0.0792017904
#> 2: 0.004861608 0.2680908352
#> 3: 0.021317708 0.3646951846
#> 4: 0.043703630 0.9340795288
#> 5: 0.101039816 1.4961111526
#> 6: 0.192874938 1.2652301743
#> 7: 0.270537997 1.1002953598
#> 8: 0.338076935 1.1317610455
#> 9: 0.407547318 1.2749174884
#> 10: 0.485805009 1.4272248720
#> 11: 0.573411715 1.4241631995
#> 12: 0.660830489 0.9264699570
#> 13: 0.717699580 0.8997225967
#> 14: 0.772926850 0.7940195737
#> 15: 0.821665799 0.5048485224
#> 16: 0.852654690 0.4607920015
#> 17: 0.880939280 0.4314586220
#> 18: 0.907423312 0.3270122704
#> 19: 0.927496160 0.2951670462
#> 20: 0.945614267 0.2201061983
#> 21: 0.959124947 0.0980857835
#> 22: 0.965145703 0.2098353951
#> 23: 0.978025935 0.2444928039
#> 24: 0.993033528 0.0514349745
#> 25: 0.996190738 0.0213080163
#> 26: 0.997498678 0.0213397832
#> 27: 0.998808569 0.0129122739
#> 28: 0.999601157 0.0057567814
#> 29: 0.999954523 0.0007408768
#> 30: 1.000000000 0.0000000000
#> 31: 1.000000000 0.0000000000
#> 32: 1.000000000 NA
#> L/LAI (weighted mean) PAVD
# }