-
Notifications
You must be signed in to change notification settings - Fork 0
Add RayCloudTools #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
hagreven
wants to merge
2
commits into
main
Choose a base branch
from
raycloudtools
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| <tool id="3dtrees_raycloudtools" name="3Dtrees: RayCloudTools" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="25.1" license="BSD-3-Clause"> | ||
| <description>Tree instance segmentation</description> | ||
| <macros> | ||
| <token name="@TOOL_VERSION@">1.1.1</token> | ||
| <token name="@VERSION_SUFFIX@">0</token> | ||
| </macros> | ||
| <requirements> | ||
| <container type="docker"> | ||
| ghcr.io/3dtrees-earth/3dtrees_rct:@TOOL_VERSION@ | ||
| </container> | ||
| </requirements> | ||
|
|
||
| <command detect_errors="exit_code"><![CDATA[ | ||
| mkdir 'in' && | ||
| mkdir 'out' && | ||
| ln -s '$input' 'in/$input.element_identifier' && | ||
| python3 -u /src/run.py | ||
| --dataset-path 'in/$input.element_identifier' | ||
| --output-dir 'out' | ||
| --gradient '$gradient' | ||
| --max-diameter '$max_diameter' | ||
| --crop-length '$crop_length' | ||
| --distance-limit '$distance_limit' | ||
| --height-min '$height_min' | ||
| --girth-height-ratio '$girth_height_ratio' | ||
| --global-taper '$global_taper' | ||
| --global-taper-factor '$global_taper_factor' | ||
| --gravity-factor '$gravity_factor' | ||
| #if $branch_segmentation: | ||
| --branch-segmentation | ||
| #end if | ||
| #if $treeinfo: | ||
| --treeinfo | ||
| #end if | ||
| #if $branch_data: | ||
| --branch_data | ||
| #end if | ||
| ]]> | ||
| </command> | ||
|
|
||
| <inputs> | ||
| <param name="input" type="data" format="laz" label="Input Dataset (.laz)" | ||
| help="Input file to process"/> | ||
| <!-- Add your specific parameters from parameters.py --> | ||
| <!-- rayextract terrain --> | ||
| <param argument="--gradient" type="float" min="0.001" max="1000" value="1" label="Gradient" help="Gradient threshold for terrain extraction"/> | ||
| <!-- rayextract trees --> | ||
| <param argument="--max-diameter" type="float" min="0.01" max="100" value="0.9" label="Maximum diameter" help="maximum trunk diameter in segmenting trees (m)"/> | ||
| <param argument="--crop-length" type="float" min="0.01" max="100" value="1" label="Crop length" help="Crops branches up to this distance from tip (m)."/> | ||
| <param argument="--distance-limit" type="float" min="0.01" max="10" value="1" label="Distance limit" help="Maximum distance between neighbour points in a tree (m)"/> | ||
| <param argument="--height-min" type="float" min="0.01" max="1000" value="2" label="Minimum tree height" help="Minimum height counted as a tree (m)"/> | ||
| <param argument="--girth-height-ratio" type="float" min="0.001" max="0.5" value="0.12" label="Girth height ratio" help="Amount up tree's height to estimate trunk girth"/> | ||
| <param argument="--global-taper" type="float" min="0" max="1" value="0.024" label="Global taper" help="Force taper value (diameter per length) for trees under global_taper_factor of max tree height - use 0 to estimate global taper from the data"/> | ||
| <param argument="--global-taper-factor" type="float" min="0" max="1" value="0.3" label="Global taper factor" help="1 estimates same taper for whole scan, 0 is per-tree tapering, values between 0 and 1 produce soft cutoff at this amount of max tree height"/> | ||
| <param argument="--gravity-factor" type="float" min="0" max="1" value="0.3" label="Gravity factor" help="Larger values preference vertical trees"/> | ||
| <param argument="--branch-segmentation" type="boolean" checked="false" label="Branch segmentation" help="Segments per branch segment - assigns IDs per branch segment instead of per tree instance"/> | ||
| <!-- treeinfo --> | ||
| <param argument="--treeinfo" type="boolean" checked="false" label="Treeinfo" help="Calculate tree attributes - dbh, height, crown radius, volume, ..."/> | ||
| <param argument="--branch-data" type="boolean" checked="false" label="Branch data" help="Calculate branch attributes - branch number, segment_length, branch order number, extension and position in branch integers per-segment"/> | ||
| </inputs> | ||
|
|
||
| <outputs> | ||
| <!-- collection with terrain, segmented point cloud, and treefile --> | ||
| <collection name="raycloudtools_outputs_default" type="list" label="RayCloudTools"> | ||
| <!--to exclude tree meshes pattern="(?P<designation>.*_segmented|.*_trees|^(?!.*trees).*_mesh)\.(?P<ext>laz|txt|(?<=_mesh\.)ply)"--> | ||
| <discover_datasets pattern="(?P<designation>.*_segmented|.*_trees|.*_mesh)\.(?P<ext>laz|txt|(?<=_mesh\.)ply)" directory="out" ext="$ext"/> | ||
| <filter>not treeinfo</filter> | ||
| </collection> | ||
| <!-- collection with terrain, segmented point cloud, and treefile with tree attributes --> | ||
| <collection name="raycloudtools_outputs_treeinfo" type="list" label="RayCloudTools (treeinfo)"> | ||
| <!-- to exclude tree meshes pattern="(?P<designation>.*_segmented|.*_trees_info|^(?!.*trees).*_mesh)\.(?P<ext>laz|txt|(?<=_mesh\.)ply)"--> | ||
| <discover_datasets pattern="(?P<designation>.*_segmented|.*_trees_info|.*_mesh)\.(?P<ext>laz|txt|(?<=_mesh\.)ply)" directory="out" ext="$ext"/> | ||
| <filter>treeinfo</filter> | ||
| </collection> | ||
| </outputs> | ||
|
|
||
| <tests> | ||
| <test expect_num_outputs="1"> | ||
| <param name="input" value="Example_Tree_RCT.laz"/> | ||
| <output_collection name="raycloudtools_outputs_default" count="4" type="list"> | ||
| <element name="Example_Tree_RCT_mesh" file="Example_Tree_RCT_mesh.ply" compare="contains"/> | ||
| <element name="Example_Tree_RCT_segmented" file="Example_Tree_RCT_segmented.laz" compare="contains"/> | ||
| <element name="Example_Tree_RCT_trees" file="Example_Tree_RCT_trees.txt" compare="contains"/> | ||
| <element name="Example_Tree_RCT_trees_mesh" file="Example_Tree_RCT_trees_mesh.ply" compare="contains"/> | ||
| </output_collection> | ||
| </test> | ||
| <test expect_num_outputs="1"> | ||
| <param name="input" value="Example_Tree_RCT.laz"/> | ||
| <param name="treeinfo" value="true"/> | ||
| <output_collection name="raycloudtools_outputs_treeinfo" count="4" type="list"> | ||
| <element name="Example_Tree_RCT_mesh" file="Example_Tree_RCT_mesh.ply" compare="contains"/> | ||
| <element name="Example_Tree_RCT_segmented" file="Example_Tree_RCT_segmented.laz" compare="contains"/> | ||
| <element name="Example_Tree_RCT_trees_info" file="Example_Tree_RCT_trees_info.txt" compare="contains"/> | ||
| <element name="Example_Tree_RCT_trees_mesh" file="Example_Tree_RCT_trees_mesh.ply" compare="contains"/> | ||
| </output_collection> | ||
| </test> | ||
| </tests> | ||
|
|
||
| <help format="markdown"> | ||
| **What it does** | ||
|
|
||
| This tool performs graph-based tree instance segmentation on LiDAR point clouds using the **RayExtract** algorithm (Devereux et al., 2026) implemented as part of **RayCloudTools** (Lowe & Stepanas, 2021). | ||
| It is platform-agnostic and works across airborne (ULS), terrestrial (TLS), and mobile (MLS) laser scanning data, as long as trees are well-represented by points along the entire tree length. | ||
|
|
||
| ----- | ||
|
|
||
| **Processing Steps** | ||
|
|
||
| - Convert input point cloud to LAZ 1.2 | ||
| - Import point cloud as ray cloud | ||
| - Extract terrain | ||
| - Extract trees | ||
| - Convert point color (segmentation result) to instance IDs | ||
| - Add instance IDs back to input point cloud | ||
|
|
||
| ----- | ||
|
|
||
| **Output** | ||
|
|
||
| Original LAZ point cloud + instance IDs in extra dimension 'PredInstance_RCT'. | ||
|
|
||
| ***Tip:** We recommend using the '3DTrees: Tile and Merge' or '3DTrees: Smart Tile' tool to process large point clouds (workflow: tile → segment → merge)!* | ||
|
|
||
| ----- | ||
|
|
||
| **Third-Party Components** | ||
|
|
||
| You agree to comply with the licence terms for these components as part of accessing the tool. | ||
|
|
||
| **RayCloudTools:** Copyright (c) 2020, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230 | [CSIRO-Open Source Software License (variation of the BSD / MIT License)](https://github.com/csiro-robotics/raycloudtools); | ||
| **PDAL:** Copyright (c) 2025, Hobu, Inc. (howard@hobu.co) | [pdal License (BSD)](https://github.com/PDAL/PDAL?tab=License-1-ov-file#readme); | ||
| **NumPy:** Copyright (c) 2005-2025, NumPy Developers | [numpy License (BSD)](https://github.com/numpy/numpy?tab=License-1-ov-file#readme); | ||
| **LasPy:** Copyright (c) 2012, Grant Brown, grant.brown73 at gmail.com, Copyright (c) 2012, Howard Butler, hobu.inc at gmail.com, Copyright (c) 2020, Thomas Montaigu, thomas.montaigu@laposte.net | [laspy License](https://github.com/laspy/laspy?tab=License-1-ov-file#readme); | ||
| **Open3D:** Copyright (c) 2018-2023 www.open3d.org | [Open3D License (MIT)](https://github.com/isl-org/Open3D?tab=License-1-ov-file#readme). | ||
| </help> | ||
| <creator> | ||
| <person name="Hannah Greven" email="hannah.greven@hnee.de"/> | ||
| <organization name="3Dtrees-Team, University of Freiburg" url="https://github.com/3dTrees-earth"/> | ||
| </creator> | ||
| <citations> | ||
| <citation type="doi">10.1016/j.rse.2025.115162</citation> | ||
| <citation type="doi">10.1109/ACCESS.2021.3084954</citation> | ||
| <citation type="bibtex"> | ||
| @misc{3dtrees_raycloudtools, title = {3Dtrees: RayCloudTools}, author = {3Dtrees-Project}, year = {2025}} | ||
| </citation> | ||
| </citations> | ||
| </tool> | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Underscore in
--branch_dataflag mismatches parameter definitionHigh Severity
The command passes
--branch_data(underscore) torun.py, but the parameter is declared withargument="--branch-data"(hyphen). Every other multi-word flag in the command uses hyphens consistently. If the Python script's argparse expects--branch-data, the underscore variant will be unrecognized and cause a runtime error when a user enables the branch data option.Additional Locations (1)
tools/raycloudtools.xml#L58-L59