Skip to content

CLI reference: lsdtt-surface-metrics

Extracts surface statistics and derived rasters from a DEM without requiring flow routing. All analyses operate directly on the input raster. The DEM must already be in a projected (metre-unit) CRS.

Usage

lsdtt-surface-metrics <path> <parameter_file>
lsdtt-surface-metrics <parameter_file>         # path defaults to ./
lsdtt-surface-metrics -h                       # print help and exit
lsdtt-surface-metrics -v                       # print version and exit
lsdtt-surface-metrics -c                       # print citation and exit

Parameter file format

# Lines beginning with # are comments.
key: value

Pipeline overview

Step Trigger
1. Hillshade write_hillshade_raster: true
2. Local relief write_local_relief_raster: true
3. Polynomial surface fit + derived metrics write_polyfit_rasters: true or polyfit_metrics is non-empty
3b. Surface shape classification (SMAP) write_shape_classification_raster: true
4. MADk2 roughness write_madk2_rasters: true
5. Frangi filter write_frangi_raster: true or write_frangi_scale_raster: true
6. Otsu threshold segmentation write_otsu_raster: true
7. Hough line extraction write_hough_lines_raster: true
8. Curvature skeletons write_curvature_skeleton_rasters: true
9. VEC adaptive thresholding write_vec_adaptive_threshold_rasters: true

Input / output parameters

Parameter Type Default Description
read_path string directory of parameter file Directory containing the input DEM.
read_fname string parameter file stem Input raster filename.
write_path string same as read_path Directory for output files.
write_fname string same as read_fname Output filename stem.
write_output_format string cog Output raster format. cog = Cloud Optimised GeoTIFF. gtiff = plain compressed GeoTIFF. same_as_input = match the input format. png = 8-bit scaled image with a worldfile and PAM sidecar, for quick visualisation only, not for analysis reuse. Output files take the extension of the chosen format.

Threading

Parameter Type Default Description
n_threads int 0 Number of OpenMP threads. 0 uses all hardware threads (default); 1 is serial. Applies to wavelet/direct polynomial fits, the polyfit metric engine, Frangi, and the 8-bit image-operation passes. Set an explicit limit no greater than your physical-core allocation in shared environments.

Step 1: Hillshade

Output: <write_fname>_hillshade.tif

Computed directly from the input DEM — no pit fill is applied first.

Parameter Type Default Description
write_hillshade_raster bool false Enable hillshade computation. Uses Zevenbergen and Thorne (1987).
hillshade_azimuth float 315 Sun azimuth in degrees clockwise from north. 315° (northwest) is the standard cartographic convention.
hillshade_altitude float 45 Sun altitude above the horizon in degrees.
hillshade_z_factor float 1.0 Vertical exaggeration applied before computing the hillshade. Values greater than 1 emphasise relief in flat terrain.

Step 2: Local relief

Output: <write_fname>_local_relief.tif

Parameter Type Default Description
write_local_relief_raster bool false Enable local relief computation (local max − local min within a moving window over valid pixels).
local_relief_radius_metres float 10.0 Radius of the moving window in metres.
local_relief_window_shape string circular Window shape. circular or square.

Step 3: Polynomial surface fit

Fits a quadratic polynomial z = ax² + by² + cxy + dx + ey + f over a moving window and optionally derives surface metrics from the coefficients.

Fit algorithm

Parameter Type Default Description
write_polyfit_rasters bool false Write the six raw coefficient rasters (a–f) for the fitted surface.
polyfit_lambda_metres float 70.0 Characteristic lengthscale in metres controlling the moving window size. Default (70 m) is tuned for Copernicus 30 m data. Reduce for lidar (e.g. 10–30 m).
polyfit_method string direct Algorithm for the fit. direct (default, preferred): separable rolling-moment O(n) fit (no FFTW needed); faster and better at resolving fine-scale features. wavelet: FFT-based Gaussian wavelet fit (requires FFTW). both: run both algorithms and print a timing comparison. Output files are prefixed _wavelet_polyfit_* or _direct_polyfit_* so both sets coexist.
polyfit_z_factor float 1.0 Vertical scaling applied before interpreting derivatives. Scales first and second derivatives consistently in the metric engine.
polyfit_flat_slope_tolerance float 1e-12 Slope magnitude below which direction-dependent metrics (aspect, plan curvature, profile curvature, tangential curvature, rotor) are set to nodata.

Derived metrics

Set polyfit_metrics to a comma-separated list of metric names, or all to write every metric.

No spaces in the list. Write slope,aspect_degrees,mean_curvature, not slope, aspect_degrees, mean_curvature. The parameter parser terminates a value at the first space, so a spaced list is silently truncated to its first entry — the run succeeds and quietly computes only that one metric. The same applies to slope_thresholds and to comma-separated lists in other CLIs (m_over_n, gsd_fractions, psi_mm).

Parameter Type Default Description
polyfit_metrics string (empty) Comma-separated list of derived metrics to compute and write. Empty = none.

Available metric names and their output suffixes:

Aspect convention. aspect_radians and aspect_degrees report the down-slope azimuth — the direction the slope faces — clockwise from north, so 0 = faces north, 90 = faces east. This matches GDAL, ArcGIS and the geomorphology literature. Changed 2026-07-22: before that release the value was the up-slope azimuth, i.e. 180° opposite, so rasters produced by earlier versions must be rotated by 180° before being compared with new ones.

Metric name Output suffix
fitted_surface _<method>_polyfit_fitted_surface.tif
dzdx _<method>_polyfit_dzdx.tif
dzdy _<method>_polyfit_dzdy.tif
d2zdx2 _<method>_polyfit_d2zdx2.tif
d2zdxdy _<method>_polyfit_d2zdxdy.tif
d2zdy2 _<method>_polyfit_d2zdy2.tif
slope _<method>_polyfit_slope.tif
slope_degrees _<method>_polyfit_slope_degrees.tif
aspect_radians _<method>_polyfit_aspect_radians.tif
aspect_degrees _<method>_polyfit_aspect_degrees.tif
laplacian _<method>_polyfit_laplacian.tif
hessian_determinant _<method>_polyfit_hessian_determinant.tif
mean_curvature _<method>_polyfit_mean_curvature.tif
gaussian_curvature _<method>_polyfit_gaussian_curvature.tif
maximum_curvature _<method>_polyfit_maximum_curvature.tif
minimum_curvature _<method>_polyfit_minimum_curvature.tif
curvedness _<method>_polyfit_curvedness.tif
shape_index _<method>_polyfit_shape_index.tif
profile_curvature _<method>_polyfit_profile_curvature.tif
plan_curvature _<method>_polyfit_plan_curvature.tif
tangential_curvature _<method>_polyfit_tangential_curvature.tif
difference_curvature _<method>_polyfit_difference_curvature.tif
horizontal_excess_curvature _<method>_polyfit_horizontal_excess_curvature.tif
vertical_excess_curvature _<method>_polyfit_vertical_excess_curvature.tif
accumulation_curvature _<method>_polyfit_accumulation_curvature.tif
ring_curvature _<method>_polyfit_ring_curvature.tif
rotor _<method>_polyfit_rotor.tif

Where <method> is wavelet or direct depending on polyfit_method.


Step 3b: Surface shape classification (SMAP)

Output: <write_fname>_<method>_shape_class.tif

A morphological surface-shape classification ported from the differential-geometry approach of TopoCurve (CurveObj.m / CurveCalc). Each pixel is labelled by the signs of Gaussian curvature (KG = k₁·k₂) and mean curvature (KM = ½(k₁+k₂)) formed from the two principal curvatures, after an optional threshold kt is applied to each principal curvature. This step builds on the polynomial fit, so it runs whenever write_shape_classification_raster: true (the polyfit is triggered automatically and the required curvature metrics are added to polyfit_metrics for you).

The classification uses the lsdtt3 curvature sign convention: convex-up terrain (ridge, peak) → negative mean curvature; concave-up terrain (channel, basin) → positive mean curvature.

Class codes

The shape_class raster stores these integer codes (as float32; nodata elsewhere):

Code Class KG KM Character
3 Peak / dome > 0 < 0 Convex in all directions
2 Antiformal saddle < 0 < 0 Saddle, net convex
1 Antiform = 0 < 0 Cylindrical ridge
0 Plane = 0 = 0 Flat
-1 Synform = 0 > 0 Cylindrical valley
-2 Synformal saddle < 0 > 0 Saddle, net concave
-3 Basin > 0 > 0 Concave in all directions
-4 Perfect saddle < 0 = 0 Symmetric saddle

With kt = 0 only the four generic classes (3, 2, -2, -3) appear, because the cylindrical/planar classes require a principal curvature of exactly zero. Increasing kt zeroes weak principal curvatures and so introduces the 1, -1, and 0 classes — use it to suppress low-amplitude, long-wavelength structure (e.g. a background basin).

Curvature method

Parameter Type Default Description
write_shape_classification_raster bool false Enable the shape classification. Requires the polynomial fit; maximum_curvature/minimum_curvature (polyfit method) or fitted_surface (fundamental_form method) are added to polyfit_metrics automatically.
shape_curvature_method string polyfit Source of the principal curvatures. polyfit: analytic principal curvatures from the polynomial fit. fundamental_form: differential-geometry curvatures ported from TopoCurve CurveCalc, computed from the polyfit fitted_surface via the first and second fundamental forms (gradients of the surface and of its unit normal field). The smoothing scale is set by polyfit_lambda_metres.
shape_curvature_threshold float 0.0 Curvature threshold kt (units: 1/m). Principal curvatures with magnitude ≤ kt are set to zero before KG/KM are formed.
write_shape_curvature_rasters bool false Also write the post-threshold Gaussian and mean curvature rasters used for the classification. These differ from the raw gaussian_curvature/mean_curvature polyfit metrics because they reflect kt.

Outputs

File When
_<method>_shape_class.tif Always (SMAP integer codes)
_<method>_ff_maximum_curvature.tif, _<method>_ff_minimum_curvature.tif shape_curvature_method: fundamental_form (the fundamental-form principal curvatures)
_<method>_shape_gaussian_curvature.tif, _<method>_shape_mean_curvature.tif write_shape_curvature_rasters: true (post-threshold KG/KM)

Here <method> is wavelet or direct (the polyfit_method); for fundamental_form it denotes the polyfit method used to produce the smoothed fitted_surface.


Step 3c: Slope threshold layers

Writes one raster per threshold showing where slope_degrees exceeds that threshold. Requires the polynomial fit; slope_degrees is added to polyfit_metrics automatically.

Outputs: <write_fname>_<method>_slope_threshold_<threshold>.tif, one per value.

Parameter Type Default Description
write_slope_threshold_layers bool false Enable the slope-threshold layers.
slope_thresholds string 3,7,12 Comma-separated threshold values in degrees. Defaults to the categories used by the Environment Agency's ALERT tool. No spaces — see the warning under Derived metrics.
clamp_slope_to_threshold bool true true: pixels above the threshold take the threshold value. false: they keep their original slope_degrees value.

Step 3d: Cloth-drape envelope

Runs a Verlet cloth simulation: a flat sheet starting at the maximum DEM elevation falls under gravity and comes to rest on ridges and summits. The resting surface is an upper envelope of the topography, and the gap between it and the DEM is a measure of valley incision.

Parameter Type Default Description
write_cloth_envelope_raster bool false Write the resting cloth surface. Output _cloth_envelope.tif.
write_cloth_incision_raster bool false Write envelope minus DEM. Positive = how far terrain lies below the envelope (incision depth). Output _cloth_incision.tif.
write_cloth_crest_mask_raster bool false Write the contact mask: 1 where a cloth particle was pinned by terrain (ridge or summit), 0 where it settled freely. Useful for diagnosing whether the cloth is too rigid or too slack. Output _cloth_crest_mask.tif.
cloth_rigidity float 1.0 Stiffness of the sheet: higher spans wider valleys without sagging.
cloth_gravity float 0.3 Step size for the fall.
cloth_max_iterations int 500 Iteration cap.
cloth_convergence_tolerance_metres float 0.005 Movement below which the cloth is considered settled.
cloth_class_threshold float 0.5 Contact distance for the crest mask.

Run lsdtt-surface-metrics -h <parameter> for the current defaults and the full guidance on each.


Step 4: MADk2 roughness

Computes omnidirectional roughness (OR), direction of maximum continuity (DMC), and roughness anisotropy (RA) following Trevisani et al. (2023) using second-order directional differences.

Outputs: <write_fname>_madk2_or.tif, _madk2_dmc.tif, _madk2_ra.tif

Parameter Type Default Description
write_madk2_rasters bool false Enable MADk2 roughness computation.
madk2_window_radius_metres float 10.0 Circular moving-window radius in metres.
madk2_lag_pixels int 1 Lag in pixels for the second-order directional differences. Must be ≥ 1. Typical values are 1 or 2.

Step 5: Frangi filter

Enhances line-like terrain features (ridges or valleys) over multiple Gaussian smoothing scales using the eigenvalues of the Hessian matrix. The maximum response across all scales is retained per pixel.

Outputs: <write_fname>_frangi.tif, <write_fname>_frangi_scale.tif

Parameter Type Default Description
write_frangi_raster bool false Write the Frangi filter response raster.
write_frangi_scale_raster bool false Write the scale-at-maximum-response raster (physical scale in metres).
frangi_sigma_min_metres float 1.0 Minimum Gaussian smoothing scale in metres.
frangi_sigma_max_metres float 5.0 Maximum Gaussian smoothing scale. This general terrain workflow searches broader lineaments up to 5 m; the drain-specific feature finder stops at 2.5 m.
frangi_n_scales int 4 Number of scales sampled logarithmically between min and max.
frangi_beta float 0.5 Controls suppression of blob-like structure. The general terrain default is 0.5; the drain finder uses 0.4 to prefer narrow lines more strongly.
frangi_c float 1.0 Controls suppression of low-structureness responses. Phase 5 intentionally changes the scientific default from 15 to 1 under approved decision D7, matching lsdtt-feature-finder; set 15 explicitly to reproduce the former response.
frangi_target string ridges Feature polarity. ridges or valleys.

Step 6: Otsu threshold segmentation

Output: <write_fname>_otsu.tif

Normalises the DEM to 8-bit and applies Otsu's method to select the threshold that minimises intra-class greyscale variance. Output is a binary raster: 1.0 = foreground (above threshold), 0.0 = background.

The 8-bit scaling uses the minimum and maximum of the valid pixels only, and the Otsu histogram counts valid pixels only, so nodata does not affect the threshold. (Before these operations were reimplemented natively, nodata entered both as zeros; on a DEM with a nodata border that made every valid pixel foreground.)

Parameter Type Default Description
write_otsu_raster bool false Enable Otsu segmentation.

Step 7: Hough line extraction

Output: <write_fname>_hough_lines.tif

Applies the progressive probabilistic Hough transform (Matas et al. 2000) to a Canny edge image derived from the DEM, and draws the detected segments 1 pixel wide. Output is a binary raster marking detected line pixels.

The algorithm and parameters are those of OpenCV's HoughLinesP. The order in which edge points are visited is random; lsdtt3 uses its own fixed-seed generator, so the result is identical on every run and platform, but the exact segments differ from OpenCV's.

Parameter Type Default Description
write_hough_lines_raster bool false Enable Hough line extraction.
hough_rho float 1.0 Distance resolution of the Hough accumulator in pixels.
hough_theta_degrees float 1.0 Angle resolution of the accumulator in degrees.
hough_threshold int 50 Minimum accumulator votes required to accept a line. Increase to suppress short or faint lines.
hough_min_line_length float 30.0 Minimum line segment length in pixels.
hough_max_line_gap float 10.0 Maximum gap in pixels between collinear points to bridge into one segment.
canny_threshold float 50.0 Lower Canny hysteresis threshold in 8-bit greyscale space [0, 255].
canny_ratio float 2.0 Ratio of upper to lower Canny threshold. Canny recommends 2.0–3.0.
canny_gaussian_sigma float 1.0 Sigma for Gaussian blur applied before Canny edge detection. 0.0 = no blur.

Step 8: Curvature skeletons

Extracts slope-break skeletons from the vertical excess curvature (VEC) and the local relief of profile curvature, using a direct polynomial fit at curvature_skeleton_lambda_metres.

Outputs:

File Description
<write_fname>_vec_skeleton_curvature.tif Raw VEC raster
<write_fname>_vec_skeleton_binary.tif Binary VEC threshold mask
<write_fname>_vec_skeleton.tif Thinned VEC skeleton
<write_fname>_profile_curvature.tif Raw profile curvature raster
<write_fname>_profile_curvature_relief.tif Local relief of profile curvature
<write_fname>_profile_skeleton_binary.tif Binary profile curvature relief mask
<write_fname>_profile_skeleton.tif Thinned profile curvature skeleton
<write_fname>_vec_skeleton_cdf.csv VEC CDF (when vec_skeleton_write_cdf: true)
Parameter Type Default Description
write_curvature_skeleton_rasters bool false Enable curvature skeleton extraction.
curvature_skeleton_lambda_metres float 100.0 Polyfit half-wavelength in metres for the direct fit. Larger values suppress noise; smaller values resolve finer features.
vec_skeleton_threshold float 0.0 VEC value above which pixels are classified as slope-break candidates. Ignored when vec_skeleton_use_cdf_threshold is true. Run once and read the printed CDF divergence threshold to tune this.
vec_skeleton_use_cdf_threshold bool false Auto-select the VEC threshold using CDF divergence. Overrides vec_skeleton_threshold.
vec_skeleton_write_cdf bool false Write the VEC CDF to _vec_skeleton_cdf.csv.
profile_relief_window_metres float 50.0 Circular window radius (m) for computing local relief of profile curvature.
profile_relief_threshold float 0.1 Threshold on profile curvature local relief for binarisation.
curvature_skeleton_spur_max_pixels int 10 Maximum endpoint-rooted spur length (pixels) pruned from skeletons after thinning. 0 = skip pruning.
curvature_skeleton_min_component_pixels int 1 Minimum component size retained in skeletons after thinning and pruning.

Step 9: VEC adaptive thresholding

Applies adaptive mean and Gaussian thresholding to the vertical excess curvature. Each pixel is compared to the local neighbourhood mean (or Gaussian-weighted mean) minus the constant vec_adaptive_C.

Outputs: <write_fname>_vec_adaptive_curvature.tif, _vec_adaptive_mean.tif, _vec_adaptive_gaussian.tif, and optionally their skeletons.

Parameter Type Default Description
write_vec_adaptive_threshold_rasters bool false Enable VEC adaptive thresholding. Uses curvature_skeleton_lambda_metres for the polyfit scale.
vec_adaptive_block_size_pixels int 51 Neighbourhood block size in pixels. Must be odd and ≥ 3. Should exceed the typical feature width but be smaller than the between-feature spacing.
vec_adaptive_C float 0.0 Constant subtracted from the local mean before thresholding. 0 = threshold at the local mean. Negative (e.g. -5) = stricter; positive = looser.
vec_adaptive_gaussian_sigma float 0.0 Sigma for optional Gaussian pre-blur before thresholding. 0 = no blur.
write_vec_adaptive_skeleton_rasters bool false Thin the adaptive binary masks to 1-pixel-wide Zhang-Suen skeletons. Uses curvature_skeleton_spur_max_pixels and curvature_skeleton_min_component_pixels. Only active when write_vec_adaptive_threshold_rasters is true.

Example parameter file

read_path:  /data/dems/
read_fname: my_dem
write_path: /data/output/
write_fname: my_dem_metrics

n_threads: 0

# Hillshade
write_hillshade_raster: true
hillshade_azimuth:      315
hillshade_altitude:     45
hillshade_z_factor:     1.0

# Polynomial surface fit — slope and curvatures at 30 m scale
polyfit_lambda_metres: 70.0
polyfit_method:        direct
polyfit_metrics:       slope,plan_curvature,profile_curvature,vertical_excess_curvature

# Surface shape classification (SMAP)
write_shape_classification_raster: true
shape_curvature_method:        fundamental_form
shape_curvature_threshold:     0.0
write_shape_curvature_rasters: true

# MADk2 roughness
write_madk2_rasters:          true
madk2_window_radius_metres:   20.0
madk2_lag_pixels:             1

# Frangi ridge filter
write_frangi_raster:      true
frangi_sigma_min_metres:  50.0
frangi_sigma_max_metres:  200.0
frangi_n_scales:          4
frangi_target:            ridges

Parameters

This section is generated from the executable's -h json registry. Do not edit it manually.

Status: stable.

File I/O

Parameter Type Default Role Parent Description Guidance
read_path string ./ io - Directory from which input files are read. Defaults to the directory holding the parameter file.
read_fname string - io - Input filename, with or without extension (e.g. my_dem.tif). Read from read_path. lsdtt3 uses GDAL, so any GDAL-readable raster format works. If empty, defaults to the parameter filename stem.
write_path string - io - Directory to which output files are written. Defaults to read_path when not set.
write_fname string - io - Output filename prefix (no path, no extension). All outputs are named <write_fname>_<descriptor>.<ext>. Defaults to the stem of read_fname when not set.

Threading

Parameter Type Default Role Parent Description Guidance
n_threads int 0 io - Number of OpenMP threads. 0 = use all hardware threads (default). 1 = serial. In shared environments, set an explicit limit no greater than the physical-core allocation. Applies to the direct and wavelet quadratic fits, polyfit metric engine, and the 8-bit image-operation passes (Otsu, adaptive thresholds, Canny, Hough).

Output format

Parameter Type Default Role Parent Description Guidance
write_output_format string cog io - Output raster format. Allowed values: cog, gtiff, same_as_input, png. cog: Cloud Optimised GeoTIFF (default). gtiff: plain compressed GeoTIFF. same_as_input: match the input raster format. png: 8-bit scaled image with a worldfile and PAM sidecar for georeferencing - for quick visualisation only, not for analysis reuse. Output files take the extension of the chosen format.

Hillshade

Parameter Type Default Role Parent Description Guidance
write_hillshade_raster bool false switch - Write a hillshade raster. Uses Zevenbergen and Thorne (1987). Computed directly from the input DEM - no fill is applied.
hillshade_azimuth float 315 param write_hillshade_raster Sun azimuth in degrees clockwise from grid north (grid up). 315 (northwest) is the cartographic convention. It is relative to the raster grid, so in an oblique frame it lights from the frame's north-west; bearings_relative_to_true_north never changes it.
hillshade_altitude float 45 param write_hillshade_raster Sun altitude above the horizon in degrees. 45 degrees is a typical default.
hillshade_z_factor float 1.0 param write_hillshade_raster Vertical exaggeration factor applied before computing hillshade. Values greater than 1 emphasise relief in flat terrain.

Local relief

Parameter Type Default Role Parent Description Guidance
write_local_relief_raster bool false switch - Write a local relief raster. Local relief is computed as local_max - local_min within a moving window over valid pixels only.
local_relief_radius_metres float 10.0 param write_local_relief_raster Radius of the local-relief window in metres. This is a physical radius in the raster CRS. The default window shape is circular.
local_relief_window_shape string circular param write_local_relief_raster Shape of the local-relief window. Valid options are circular or square. Default is circular.

Polynomial surface fit

Parameter Type Default Role Parent Description Guidance
write_polyfit_rasters bool false switch - Write the six quadratic polynomial fit coefficient rasters. Computes a, b, c, d, e, f where z = ax^2 + by^2 + cxy + dx + ey + f over a moving window controlled by polyfit_lambda.
polyfit_lambda_metres float 70.0 param - Characteristic lengthscale (metres) for the quadratic polynomial fit. Controls the size of the moving window. Default (70 m) is tuned for Copernicus 30 m data. Reduce for lidar (e.g. 10-30 m).
polyfit_metrics string - param - Comma-separated list of derived polyfit metrics to write. Examples: slope,aspect_degrees,plan_curvature,profile_curvature. Use all to write every supported metric. Available metrics: fitted_surface, dzdx, dzdy, d2zdx2, d2zdxdy, d2zdy2, slope, slope_degrees,aspect_radians, aspect_degrees, laplacian, hessian_determinant, mean_curvature, gaussian_curvature, maximum_curvature, minimum_curvature, curvedness, shape_index, profile_curvature, plan_curvature, tangential_curvature, difference_curvature, horizontal_excess_curvature, vertical_excess_curvature, accumulation_curvature, ring_curvature, rotor.
polyfit_z_factor float 1.0 param - Vertical scaling applied before interpreting polyfit derivatives. Scales first and second derivatives consistently in the polyfit metric engine.
polyfit_flat_slope_tolerance float 1e-12 param - Slope tolerance below which direction-dependent polyfit metrics are nodata. Applies to aspect, plan curvature, tangential curvature, profile curvature, and rotor.
polyfit_method string direct param - Algorithm used for the quadratic polynomial fit. direct: separable rolling-moment O(n) fit (no FFTW needed). Default and preferred: faster and better at resolving fine-scale features. wavelet: FFT-based Gaussian wavelet fit (requires FFTW). both: run both methods and write outputs from each; also prints a timing comparison. Outputs are prefixed wavelet_polyfit* or direct_polyfit* so results from both methods can coexist in the same directory.
compute_backend string auto param - Preferred compute backend for kernels that have a GPU port. auto: use the GPU when a device and GPU kernels are both available, otherwise CPU (default). cpu: force CPU. gpu: prefer the GPU, falling back to CPU per-function when no GPU kernel exists or no device is present. Currently only direct_polyfit has a GPU port; all other metrics run on the CPU regardless of this setting. Has no effect in a build without GPU support (-DLSDTT_GPU=OFF).
write_slope_threshold_layers bool false switch - Writes layers for each slope threshold where the polyfit metric slope_degrees exceeds the threshold Thresholds are to be supplied in a comma-separated string under the parameter slope_tresholds.
clamp_slope_to_threshold bool true param - If true, the slope threshold layers will have the value of the threshold where the original slope_degrees layer exceeds the threshold. If false, slopes from slope_degrees layer are preserved where slopes exceed threshold. In both cases, nodatavalue below threshold. Defaults to true.
slope_thresholds string 3,7,12 param - The threshold values for which slope threshold layers are to be written. Defaults to the categories used by the Environment Agency's ALERT tool.

Surface shape classification (SMAP, TopoCurve-style)

Parameter Type Default Role Parent Description Guidance
write_shape_classification_raster bool false switch - Write the morphological surface-shape classification raster (SMAP). Reproduces the differential-geometry shape classification of the TopoCurve approach. Each pixel is labelled by the signs of Gaussian and mean curvature derived from the polyfit principal curvatures: peak (3), antiformal saddle (2), antiform (1), plane (0), synform (-1), synformal saddle (-2), basin (-3), perfect saddle (-4). Requires the polynomial fit; maximum_curvature and minimum_curvature are added to the requested metrics automatically. Output: _<method>_shape_class.<ext>; write_output_format selects the extension.
shape_curvature_method string polyfit param - Source of the principal curvatures used for the shape classification. polyfit: principal curvatures from the polynomial fit (compute_polyfit_metrics maximum/minimum_curvature). Default. fundamental_form: the differential-geometry method ported from TopoCurve CurveCalc, computed from the fitted surface via the first and second fundamental forms (gradients of the surface and of its unit normal field). Both feed the same classifier. With fundamental_form the polyfit fitted_surface is used as the smoothed input (smoothing scale set by polyfit_lambda_metres), and the fundamental-form principal curvatures are written as _<method>_ff_maximum_curvature.<ext> / _<method>_ff_minimum_curvature.<ext>.
shape_curvature_threshold float 0.0 param - Curvature threshold (kt) applied to each principal curvature before shape classification. Principal curvatures with magnitude <= kt are set to zero, so KG and KM collapse toward planar/cylindrical classes. Increase to remove low-amplitude, long-wavelength structure (e.g. a background basin) from the classification. Units: 1/m. Default 0 keeps every pixel in a non-planar class.
write_shape_curvature_rasters bool false switch - Write the post-threshold Gaussian and mean curvature rasters used for the shape classification. These differ from the raw gaussian_curvature/mean_curvature polyfit metrics because they reflect shape_curvature_threshold (kt). Outputs: _<method>_shape_gaussian_curvature.<ext>, _<method>_shape_mean_curvature.<ext>. Only active when write_shape_classification_raster = true.

MADk2 roughness

Parameter Type Default Role Parent Description Guidance
write_madk2_rasters bool false switch - Write MADk2 roughness rasters. Writes omnidirectional roughness (OR), direction of maximum continuity (DMC), and roughness anisotropy (RA) following Trevisani et al. (2023).
madk2_window_radius_metres float 10.0 param write_madk2_rasters Circular MADk2 window radius in metres. This is the radius of the moving circular support window in projected map units.
madk2_lag_pixels int 1 param write_madk2_rasters Lag in pixels for the MADk2 second-order directional differences. Must be >= 1. Typical values are 1 or 2.

Frangi filter

Parameter Type Default Role Parent Description Guidance
write_frangi_raster bool false switch - Write a Frangi filter response raster. Enhances line-like terrain features over multiple scales using the Hessian of a Gaussian-smoothed DEM.
write_frangi_scale_raster bool false switch - Write the scale-at-maximum-Frangi-response raster. Stores the physical scale in metres at which the maximum Frangi response occurred for each pixel.
frangi_sigma_min_metres float 1.0 param - Minimum Frangi scale in metres. This is the smallest Gaussian smoothing scale tested by the Frangi filter.
frangi_sigma_max_metres float 5.0 param - Maximum Frangi scale in metres. This general terrain-metrics workflow searches broader lineaments up to 5 m; the drain-specific feature finder deliberately stops at 2.5 m.
frangi_n_scales int 4 param - Number of Frangi scales. Scales are sampled logarithmically between frangi_sigma_min_metres and frangi_sigma_max_metres.
frangi_beta float 0.5 param - Frangi beta parameter. Controls suppression of blob-like structure relative to line-like structure. The neutral 0.5 default supports general ridge/valley exploration; the drain finder uses 0.4 to prefer narrow lines more strongly.
frangi_c float 1.0 param - Frangi c parameter. Controls suppression of low-structureness responses. Phase 5 decision D7 intentionally changed the scientific default from 15 to 1, matching lsdtt-feature-finder; set 15 explicitly to reproduce the former response.
frangi_target string ridges param - Feature polarity for the Frangi filter. Valid options are ridges or valleys.

Otsu threshold segmentation

Parameter Type Default Role Parent Description Guidance
write_otsu_raster bool false switch - Write a binary raster produced by Otsu threshold segmentation. The DEM is normalised to 8-bit and Otsu's method selects the threshold that minimises intra-class greyscale variance. Output: 1.0 = foreground (above threshold), 0.0 = background.

Hough line extraction

Parameter Type Default Role Parent Description Guidance
write_hough_lines_raster bool false switch - Write a binary raster of detected straight line segments. Uses the progressive probabilistic Hough transform (Matas et al. 2000) on a Canny edge image derived from the DEM. The algorithm and parameters are those of OpenCV's HoughLinesP; the random order in which edge points are visited uses lsdtt3's own fixed-seed generator, so results are reproducible on every platform but not identical to OpenCV's. Output: 1.0 = line pixel, 0.0 = other.
hough_rho float 1.0 param write_hough_lines_raster Distance resolution of the Hough accumulator in pixels. Smaller values give finer angular resolution but increase memory and compute cost.
hough_theta_degrees float 1.0 param write_hough_lines_raster Angle resolution of the Hough accumulator in degrees. Converted to radians internally. Typical range: 0.5-2.0 degrees.
hough_threshold int 50 param write_hough_lines_raster Minimum number of accumulator votes required to accept a line. Increase to suppress short or faint lines. Decrease to detect more lines in noisy data.
hough_min_line_length float 30.0 param write_hough_lines_raster Minimum line segment length in pixels. Segments shorter than this are discarded. Scale this relative to your pixel resolution.
hough_max_line_gap float 10.0 param write_hough_lines_raster Maximum gap in pixels between collinear points to bridge into one segment. Increase to connect dashed or broken linear features.

Shared Canny parameters (used by Hough; also available standalone)

Parameter Type Default Role Parent Description Guidance
canny_threshold float 50.0 param - Lower Canny hysteresis threshold in 8-bit greyscale space [0,255]. Used internally by the Hough line step. Pixels with gradient magnitude below this are definitely not edges.
canny_ratio float 2.0 param - Ratio of upper to lower Canny threshold (high = canny_threshold * ratio). Canny recommends 2.0-3.0. Increase to suppress weak edges.
canny_gaussian_sigma float 1.0 param - Sigma for the Gaussian blur applied before Canny edge detection. 0.0 = no blur. Increase (e.g. 1.5-3.0) for noisy or coarse DEMs.

Curvature skeleton (VEC + plan curvature relief)

Parameter Type Default Role Parent Description Guidance
write_curvature_skeleton_rasters bool false switch - Extract slope-break skeletons directly from curvature rasters. Computes vertical_excess_curvature and plan_curvature via direct polyfit (curvature_skeleton_lambda_metres), then: (1) thresholds VEC at vec_skeleton_threshold (or CDF divergence auto-threshold) and skeletonises; (2) computes local relief of plan_curvature over plan_relief_window_metres, thresholds at plan_relief_threshold, and skeletonises. Outputs use the selected raster extension: _vec_skeleton_curvature.<ext>, _vec_skeleton_binary.<ext>, _vec_skeleton.<ext>, _profile_curvature.<ext>, _profile_curvature_relief.<ext>, _profile_skeleton_binary.<ext>, _profile_skeleton.<ext>.
curvature_skeleton_lambda_metres float 100.0 param write_curvature_skeleton_rasters Polyfit half-wavelength (m) for the direct fit used by curvature skeleton. Controls the smoothing scale of the fitted surface. Larger values suppress noise; smaller values resolve finer features.
vec_skeleton_threshold float 0.0 param write_curvature_skeleton_rasters VEC threshold for binarising vertical_excess_curvature. Pixels with VEC >= this value are classified as slope-break candidates. Run once with write_curvature_skeleton_rasters=true and read the printed CDF divergence threshold to choose an appropriate value. Ignored when vec_skeleton_use_cdf_threshold=true.
vec_skeleton_use_cdf_threshold bool false param write_curvature_skeleton_rasters Auto-select the VEC threshold using CDF divergence. Overrides vec_skeleton_threshold when true.
vec_skeleton_write_cdf bool false param write_curvature_skeleton_rasters Write the VEC CDF to a CSV file alongside the skeleton outputs. Output suffix: _vec_skeleton_cdf.csv.
profile_relief_window_metres float 50.0 param write_curvature_skeleton_rasters Circular moving-window radius (m) for the profile curvature local relief. Larger windows smooth sign-change boundaries but blur fine features.
profile_relief_threshold float 0.1 param write_curvature_skeleton_rasters Threshold on profile curvature local relief for binarisation. Pixels whose within-window profile curvature range >= this value are classified as slope-break candidates.
curvature_skeleton_spur_max_pixels int 10 param write_curvature_skeleton_rasters Maximum endpoint-rooted spur length (pixels) pruned from curvature skeletons. 0 = skip spur pruning.
curvature_skeleton_min_component_pixels int 1 param write_curvature_skeleton_rasters Minimum component size (pixels) retained in curvature skeletons. Applied after thinning and spur pruning.

VEC adaptive thresholding

Parameter Type Default Role Parent Description Guidance
write_vec_adaptive_threshold_rasters bool false switch - Apply adaptive mean and Gaussian thresholding to vertical_excess_curvature. Uses curvature_skeleton_lambda_metres for the polyfit scale. Each pixel is compared to the mean (or Gaussian-weighted mean) of its local neighbourhood minus the constant vec_adaptive_C: a pixel is foreground if its normalised 8-bit value > local_mean - vec_adaptive_C. Negative C is stricter (retains only locally brightest pixels). Outputs: _vec_adaptive_mean.<ext>, _vec_adaptive_gaussian.<ext>, and optionally their Zhang-Suen skeletons.
vec_adaptive_block_size_pixels int 51 param - Neighbourhood block size (pixels) for adaptive VEC thresholding. Must be odd and >= 3. Should be larger than the typical feature width but smaller than the between-feature spacing. Larger values make the threshold surface smoother and less sensitive to local intensity variation.
vec_adaptive_C float 0.0 param - Offset (grey levels) subtracted from the local neighbourhood mean before VEC thresholding. The VEC is rescaled to 0-255 grey levels between its minimum and maximum and C is rounded up to an integer: foreground where grey level > local mean - ceil(C). 0 = above the local mean. Negative (e.g. -5) = stricter; any C in (-1, 0] acts as 0. Positive = looser.
vec_adaptive_gaussian_sigma float 0.0 param - Sigma for optional Gaussian pre-blur before adaptive VEC thresholding. 0 = no blur. A small value (e.g. 1.0) smooths pixel-scale noise before the local threshold is applied.
write_vec_adaptive_skeleton_rasters bool false switch - Thin the adaptive-threshold VEC binary masks to 1-pixel skeletons. Applies Zhang-Suen thinning (and curvature_skeleton_spur_max_pixels pruning) to both the mean and Gaussian adaptive outputs. Outputs: _vec_adaptive_mean_skeleton.<ext>, _vec_adaptive_gaussian_skeleton.<ext>.Only active when write_vec_adaptive_threshold_rasters = true.

Cloth drape

Parameter Type Default Role Parent Description Guidance
write_cloth_envelope_raster bool false switch - Write the cloth-drape upper envelope surface. Runs a Verlet cloth simulation: a flat sheet at max DEM elevation falls under gravity and comes to rest on ridges and summits. The resting position is the upper landscape envelope. Output: _cloth_envelope.<ext>. For best results supply a pit-filled or breached DEM.
write_cloth_incision_raster bool false switch - Write the cloth-drape incision depth raster (envelope minus DEM). Positive values indicate how far the terrain surface lies below the envelope at each pixel (valley incision depth). Negative values indicate residual pits or nodata artefacts above the envelope. Output: _cloth_incision.<ext>.
write_cloth_crest_mask_raster bool false switch - Write the cloth contact (crest / summit) pixel mask. 1 = cloth particle was pinned by terrain contact (ridge or summit); 0 = particle settled freely between ridges. Useful for diagnosing which features govern the envelope shape. Output: _cloth_crest_mask.<ext>.
cloth_rigidity float 1.0 param - Spring stiffness of the cloth (controls envelope smoothness). Higher values produce a smoother, longer-wavelength envelope that bridges across narrow valleys and ridges. Equivalent to the Tension parameter in the Carretier and Valenti EnvelopSurface script. Typical range: 0.5 (closely follows terrain) to 20 (broad smooth drape).
cloth_gravity float 0.3 param - Downward gravitational force per Verlet step (m/step^2). Controls how quickly the cloth descends. Reducing gravity gives the cloth more time to equilibrate spring forces before contact, which can improve convergence on complex terrain. Default (0.3) follows Zhang et al. (2016) CSF.
cloth_class_threshold float 0.5 param - Contact tolerance in metres: cloth is pinned when within this distance of the DEM. Increase (1-5 m) for coarse-resolution DEMs, noisy data, or DEMs with residual artefact pits. Decrease (0.1 m) for smooth high-resolution lidar where precise ridge contact is desired.
cloth_max_iterations int 500 param - Maximum number of Verlet integration steps. The simulation stops early when max_displacement < cloth_convergence_tolerance_metres. Increase for large or complex DEMs where convergence is slow.
cloth_convergence_tolerance_metres float 0.005 param - Convergence tolerance: maximum cloth displacement (m) per step to declare settled. Tighten to 0.001 m for precise incision mapping on smooth terrain. Loosen to 0.01 m for faster runs on coarse DEMs where sub-centimetre precision is not needed.

Orientations

Parameter Type Default Role Parent Description Guidance
bearings_relative_to_true_north bool false param - Write bearings, aspects and orientations clockwise from true north. Off (default): they are clockwise from grid north (grid up), so in an oblique frame with the feature along +x, 90 degrees means along the feature. On: each value is converted with the grid convergence at its own location (each cell of a raster, each row of a table), which also removes the up to about 3 degree difference between UTM grid north and true north. Angles between two directions (junction angles, deflections, contrasts) are unchanged, and hillshade illumination always stays relative to grid up. Needs a raster with a CRS.