{"id":20301,"name":"canopyLazR","description":"An R package that estimates leaf area density and leaf area index from airborne LiDAR point clouds.","url":"https://github.com/akamoske/canopyLazR","last_synced_at":"2026-06-01T15:30:20.491Z","repository":{"id":148019706,"uuid":"144175894","full_name":"akamoske/canopyLazR","owner":"akamoske","description":"R package to estimate leaf area density (LAD) and leaf area index (LAI) from airborne LiDAR point clouds","archived":false,"fork":false,"pushed_at":"2023-08-25T14:12:06.000Z","size":46680,"stargazers_count":46,"open_issues_count":0,"forks_count":14,"subscribers_count":6,"default_branch":"master","last_synced_at":"2026-05-12T06:04:05.512Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akamoske.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-08-09T16:08:02.000Z","updated_at":"2026-05-11T14:41:04.000Z","dependencies_parsed_at":"2023-09-21T19:58:53.522Z","dependency_job_id":null,"html_url":"https://github.com/akamoske/canopyLazR","commit_stats":{"total_commits":150,"total_committers":2,"mean_commits":75.0,"dds":"0.046666666666666634","last_synced_commit":"d0567cb0898be41c3ab26bb70a9581e5dcdd2cb1"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/akamoske/canopyLazR","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akamoske%2FcanopyLazR","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akamoske%2FcanopyLazR/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akamoske%2FcanopyLazR/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akamoske%2FcanopyLazR/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akamoske","download_url":"https://codeload.github.com/akamoske/canopyLazR/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akamoske%2FcanopyLazR/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33014201,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"owner":{"login":"akamoske","name":"Aaron Kamoske","uuid":"20822317","kind":"user","description":"Adaptive Management Analyst at USDA Forest Service","email":"","website":null,"location":"Minnesota","twitter":null,"company":null,"icon_url":"https://avatars.githubusercontent.com/u/20822317?u=71988291148ea1f81b70f0bc9c1c01e49a0ec815\u0026v=4","repositories_count":9,"last_synced_at":"2024-06-11T16:19:30.616Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/akamoske","funding_links":[],"total_stars":52,"followers":23,"following":10,"created_at":"2023-03-27T11:07:14.675Z","updated_at":"2024-06-11T16:19:32.765Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akamoske","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akamoske/repositories"},"packages":[],"commits":{"id":1254264,"full_name":"akamoske/canopyLazR","default_branch":"master","total_commits":150,"total_committers":2,"total_bot_commits":0,"total_bot_committers":0,"mean_commits":75.0,"dds":0.046666666666666634,"past_year_total_commits":0,"past_year_total_committers":0,"past_year_total_bot_commits":0,"past_year_total_bot_committers":0,"past_year_mean_commits":0.0,"past_year_dds":0.0,"last_synced_at":"2026-05-29T14:47:34.421Z","last_synced_commit":"d0567cb0898be41c3ab26bb70a9581e5dcdd2cb1","created_at":"2023-03-27T11:01:59.612Z","updated_at":"2026-05-29T14:47:34.397Z","committers":[{"name":"akamoske","email":"akamoske@gmail.com","login":"akamoske","count":143},{"name":"Shawn P. Serbin","email":"sserbin@bnl.gov","login":"serbinsh","count":7}],"past_year_committers":[],"commits_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories/akamoske%2FcanopyLazR/commits","host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-05-31T00:00:10.607Z","repositories_count":6251255,"commits_count":883831495,"contributors_count":35020102,"owners_count":1161497,"icon_url":"https://github.com/github.png","host_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories"}},"issues_stats":{"full_name":"akamoske/canopyLazR","html_url":"https://github.com/akamoske/canopyLazR","last_synced_at":"2026-05-12T06:00:52.700Z","status":"error","issues_count":1,"pull_requests_count":2,"avg_time_to_close_issue":68026.0,"avg_time_to_close_pull_request":338288.0,"issues_closed_count":1,"pull_requests_closed_count":2,"pull_request_authors_count":1,"issue_authors_count":1,"avg_comments_per_issue":34.0,"avg_comments_per_pull_request":18.5,"merged_pull_requests_count":2,"bot_issues_count":0,"bot_pull_requests_count":0,"past_year_issues_count":0,"past_year_pull_requests_count":0,"past_year_avg_time_to_close_issue":null,"past_year_avg_time_to_close_pull_request":null,"past_year_issues_closed_count":0,"past_year_pull_requests_closed_count":0,"past_year_pull_request_authors_count":0,"past_year_issue_authors_count":0,"past_year_avg_comments_per_issue":null,"past_year_avg_comments_per_pull_request":null,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":0,"past_year_merged_pull_requests_count":0,"created_at":"2023-05-09T10:40:36.040Z","updated_at":"2026-05-12T06:00:52.700Z","repository_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/akamoske%2FcanopyLazR","issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/akamoske%2FcanopyLazR/issues","issue_labels_count":{},"pull_request_labels_count":{},"issue_author_associations_count":{"CONTRIBUTOR":1},"pull_request_author_associations_count":{"CONTRIBUTOR":2},"issue_authors":{"serbinsh":1},"pull_request_authors":{"serbinsh":2},"host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-05-20T00:00:29.037Z","repositories_count":14647047,"issues_count":34136335,"pull_requests_count":111844029,"authors_count":11267185,"icon_url":"https://github.com/github.png","host_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories","owners_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/owners","authors_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors"},"past_year_issue_labels_count":{},"past_year_pull_request_labels_count":{},"past_year_issue_author_associations_count":{},"past_year_pull_request_author_associations_count":{},"past_year_issue_authors":{},"past_year_pull_request_authors":{},"maintainers":[],"active_maintainers":[]},"events":{"total":{"ForkEvent":2,"WatchEvent":8},"last_year":{"ForkEvent":1,"WatchEvent":1}},"keywords":[],"dependencies":[{"ecosystem":"cran","filepath":"DESCRIPTION","sha":null,"kind":"manifest","created_at":"2023-04-29T21:43:19.359Z","updated_at":"2023-04-29T21:43:19.359Z","repository_link":"https://github.com/akamoske/canopyLazR/blob/master/DESCRIPTION","dependencies":[{"id":9306407590,"package_name":"fields","ecosystem":"cran","requirements":"*","direct":true,"kind":"depends","optional":false},{"id":9306407591,"package_name":"plyr","ecosystem":"cran","requirements":"*","direct":true,"kind":"depends","optional":false},{"id":9306407592,"package_name":"rlas","ecosystem":"cran","requirements":"*","direct":true,"kind":"depends","optional":false},{"id":9306407593,"package_name":"raster","ecosystem":"cran","requirements":"*","direct":true,"kind":"depends","optional":false}]}],"score":4.5217885770490405,"created_at":"2023-09-11T14:52:11.504Z","updated_at":"2026-06-01T15:30:20.494Z","avatar_url":"https://github.com/akamoske.png","language":"R","category":"Biosphere","sub_category":"Forest Remote Sensing","monthly_downloads":0,"total_dependent_repos":0,"total_dependent_packages":0,"readme":"\n# canopyLazR\n\nR package to estimate leaf area density (LAD), leaf area index (LAI), and forest structural attributes from airborne LiDAR point clouds.\n\n## Information\n\nFor theory behind the package please see the citation below. Please cite with use.   \n\n*Kamoske A.G., Dahlin K.M., Stark S.C., and Serbin S.P. 2019. Leaf area density from airborne LiDAR: Comparing sensors and resolutions in a forest ecosystem. Forest Ecology and Management 433, 364-375.*\n\n### Corresponding Author\n\nDr. Aaron G. Kamoske\n   \n  + [USDA Forest Service, National Adaptive Management Analyst]        \n  + aaron.kamoske@usda.gov\n\n### Contributing Authors\n\nDr. Scott C. Stark\n   \n  + [Michigan State University, Department of Forestry](https://www.canr.msu.edu/for/)      \n  + [Tropical Forestry Ecology Lab](https://sites.google.com/site/scottcstarktropicalforest/)   \n  + scott.c.stark@gmail.com  \n  \nDr. Shawn P. Serbin\n\n  + [Brookhaven National Laboratory, Environmental and Climate Sciences Department](https://www.bnl.gov/envsci/)\n  + [Terrestrial Ecosystem Science and Technology (TEST) group](https://www.bnl.gov/testgroup)\n  + sserbin@bnl.gov\n  \nDr. Kyla M. Dahlin\n  + [Michigan State University, Department of Geography, Environment, and Spatial Sciences](http://geo.msu.edu/)\n  + [Michigan State University, Ecology, Evolutionary Biology, and Behavior Program](https://eebb.msu.edu/)\n  + [ERSAM Lab](https://www.ersamlab.com/)\n  + kdahlin@msu.edu\n  \n## Installation\n\nThe easiest way to install `canopyLazR` is via `install_github` from the `devtools` package:\n\n```\n# If you haven't already installed this package and its dependencies\ninstall.packages(\"devtools\")\n\n# If you alread have devtools installed or just installed it\nlibrary(devtools)\n\n# Install canopyLazR from GitHub\ninstall_github(\"akamoske/canopyLazR\")\n\n# Load the library\nlibrary(canopyLazR)\n```\n\nNow all functions should be available.\n\n## Downloading example data\n\n[NEON](https://www.neonscience.org/) provides a teaching LiDAR dataset that is easy to download via R. We can use this file as a test dataset here. Code to download this .las file follows:\n\n```\n# Install missing R package if needed\nlist.of.packages \u003c- c(\"uuid\",\"rlas\",\"devtools\")\nnew.packages \u003c- list.of.packages[!(list.of.packages %in% installed.packages()[, \"Package\"])]\nif (length(new.packages)) {\n  print(\"installing : \")\n  print(new.packages)\n  install.packages(new.packages, repos = \"http://cran.rstudio.com/\", dependencies = TRUE)\n}\n\n# Create a scratch folder to contain example LiDAR dataset\nscratch_folder \u003c- file.path(\"~/scratch/neon_data/\")\nif (! file.exists(scratch_folder)) dir.create(scratch_folder,recursive=TRUE)\nsetwd(file.path(scratch_folder))\ngetwd()\n\n# Download NEON example .las file\ndownload.file(url = \"https://ndownloader.figshare.com/files/7024955\",\n              destfile = file.path(scratch_folder,\"neon_lidar_example.las\"),\n              method = \"auto\",\n              mode = \"wb\")\n\n```\n\n## Example of usage (after installation)\n\nOnce the package is loaded into your R session, this is the an example of how to use the functions in this package\nto estimate LAD and LAI:\n\n```\n# Convert .laz or .las file into a voxelized lidar array\nlaz.data \u003c- laz.to.array(laz.file.path = file.path(scratch_folder,\"neon_lidar_example.las\"), \n                         voxel.resolution = 10, \n                         z.resolution = 1,\n                         use.classified.returns = TRUE)\n\n# Level the voxelized array to mimic a canopy height model\nlevel.canopy \u003c- canopy.height.levelr(lidar.array = laz.data)\n\n# Estimate LAD for each voxel in leveled array\nlad.estimates \u003c- machorn.lad(leveld.lidar.array = level.canopy, \n                           voxel.height = 1, \n                           beer.lambert.constant = NULL)\n\n# Convert the LAD array into a single raster stack\nlad.raster \u003c- lad.array.to.raster.stack(lad.array = lad.estimates, \n                                      laz.array = laz.data, \n                                      epsg.code = 32611)\n\n# Create a single LAI raster from the LAD raster stack\nlai.raster \u003c- raster::calc(lad.raster, fun = sum, na.rm = TRUE)\n\n# Convert the list of LAZ arrays into a ground and canopy height raster\ngrd.can.rasters \u003c- array.to.ground.and.canopy.rasters(laz.data, 32611)\n\n# Calculate max LAD and height of max LAD\nmax.lad \u003c- lad.ht.max(lad.array = lad.estimates, \n                      laz.array = laz.data, \n                      ht.cut = 5, \n                      epsg.code = 32618)\n\n# Calculate the ratio of filled and empty voxels in a given column of the canopy\nempty.filled.ratio \u003c- canopy.porosity.filled.ratio(lad.array = lad.estimates,\n                                                   laz.array = laz.data,\n                                                   ht.cut = 5,\n                                                   epsg.code = 32618)\n\n# Calculate the volume of filled and empty voxles in a given column of the canopy\nempty.filled.volume \u003c- canopy.porosity.filled.volume(lad.array = lad.estimates,\n                                                     laz.array = laz.data,\n                                                     ht.cut = 5,\n                                                     xy.res = 10,\n                                                     z.res = 1,\n                                                     epsg.code = 32618)\n\n# Calculate the within canopy rugosity\nwithin.can.rugosity \u003c- rugosity.within.canopy(lad.array = lad.estimates,\n                                              laz.array = laz.data,\n                                              ht.cut = 5,\n                                              epsg.code = 32618)\n\n# Calculate the heights of various LAD quantiles\nht.quantiles \u003c- lad.quantiles(lad.array = lad.estimates,\n                              laz.array = laz.data,\n                              ht.cut = 5,\n                              epsg.code = 32618)\n\n# Calculate various canopy volume metrics from Lefsky\ncan.volume \u003c- canopy.volume(lad.array = lad.estimates,\n                            laz.array = laz.data,\n                            ht.cut = 5,\n                            xy.res = 10,\n                            z.res = 1,\n                            epsg.code = 32618)\n\n# We can calculate the depth of the euphotic zone by dividing by the volume of the voxel\neuphotic.depth \u003c- can.volume$euphotic.volume.column.raster / ( 10 * 10 * 1)\n\n# Calculate the top of canopy rugosity volume\ntoc.rugos \u003c- toc.rugosity(chm.raster = grd.can.rasters$chm.raster,\n                          xy.res = 10,\n                          z.res = 1)\n\n# Plot the lai raster\nplot(lai.raster)\n\n# Plot the ground raster\nplot(grd.can.rasters$ground.raster)\n\n# Plot the canopy height raster\nplot(grd.can.rasters$canopy.raster)\n\n# Plot the canopy height model raster\nplot(grd.can.rasters$chm.raster)\n\n# Plot the max LAD raster\nplot(max.lad$max.lad.raster)\n\n# Plot the height of max LAD raster\nplot(max.lad$max.lad.ht.raster)\n\n# Plot filled voxel ratio raster\nplot(empty.filled.ratio$filled.raster)\n\n# Plot porosity voxel ratio raster\nplot(empty.filled.ratio$porosity.raster)\n\n# Plot filled voxel volume raster\nplot(empty.filled.volume$filled.raster)\n\n# Plot porosity voxel volume raster\nplot(empty.filled.volume$porosity.raster)\n\n# Plot the standard deviation of LAD within a vertical column raster\nplot(within.can.rugosity$vertical.sd.lad.raster)\n\n# Plot within canopy rugosity\nplot(within.can.rugosity$rugosity.raster)\n\n# Plot the height of the 10th quantile\nplot(ht.quantiles$quantile.10.raster)\n\n# Plot the height of the 25th quantile\nplot(ht.quantiles$quantile.25.raster)\n\n# Plot the height of the 50th quantile\nplot(ht.quantiles$quantile.50.raster)\n\n# Plot the height of the 75th quantile\nplot(ht.quantiles$quantile.75.raster)\n\n# Plot the height of the 90th quantile\nplot(ht.quantiles$quantile.90.raster)\n\n# Plot the height of the mean LAD\nplot(ht.quantiles$mean.raster)\n\n# Plot the volume of the euphotic zone for each column\nplot(can.volume$euphotic.volume.column.raster)\n\n# Plot the total leaf area in the euphotic zone for each column\nplot(can.volume$euphotic.tla.column.raster)\n\n# Plot the depth of the euphotic zone\nplot(euphotic.depth)\n\n# Plot the volume of the oligophotic zone for each column\nplot(can.volume$oligophotic.volume.column.raster)\n\n# Plot the total leaf area in the oligophotic zone for each column\nplot(can.volume$oligophotic.tla.column.raster)\n\n# Plot the volume of the empty space within a given colume\nplot(can.volume$empty.volume.column.raster)\n\n# Plot the volume of the empty space within a 3x3 moving window\nplot(can.volume$empty.canopy.volume.raster)\n\n# Plot the volume of the euphotic zone within a 3x3 moving window\nplot(can.volume$filled.canopy.euphotic.raster)\n\n# Plot the volume of the oligophotic zone within a 3x3 moving window\nplot(can.volume$filled.canopy.oligophotic.raster)\n\n# Plot the total leaf area of the euphotic zone within a 3x3 moving window\nplot(can.volume$filled.canopy.euphotic.tla.raster)\n\n# Plot the total leaf area of the oligophotic zone within a 3x3 moving window\nplot(can.volume$filled.canopy.oligophotic.tla.raster)\n\n# Plot the top of canopy rugosity volume\nplot(toc.rugos)\n\n```\n\n## License\n\nThis project is licensed under the GNU GPUv2 License - see the [LICENSE.md](LICENSE.md) file for details\n\n","funding_links":[],"readme_doi_urls":[],"works":{},"citation_counts":{},"total_citations":0,"keywords_from_contributors":["ecosystem-model"],"project_url":"https://ost.ecosyste.ms/api/v1/projects/20301","html_url":"https://ost.ecosyste.ms/projects/20301"}