Diagnostic Tools

Terrain-maker includes comprehensive diagnostic tools for visualizing and debugging terrain processing pipelines. These tools help you understand how transforms affect your data and optimize rendering parameters.

Overview

The terrain.diagnostics module provides visualization functions for:

  • Wavelet denoising - Analyze noise removal and frequency decomposition

  • Slope-adaptive smoothing - Visualize smoothing intensity based on terrain slope

  • Bump removal - Debug morphological filtering effects

  • Score upscaling - Compare original vs upscaled score grids

  • Render histograms - Analyze color distribution in output images

Wavelet Denoising Diagnostics

plot_wavelet_diagnostics

Shows before/after comparison of wavelet denoising with difference maps and cross-section profiles.

from src.terrain.diagnostics import plot_wavelet_diagnostics

plot_wavelet_diagnostics(
    original=dem_original,
    denoised=dem_denoised,
    output_path=Path("diagnostics/wavelet.png"),
    title_prefix="DEM Wavelet Denoising",
    profile_row=500,  # Row for cross-section
)

Output panels:

  1. Original DEM

  2. Denoised DEM

  3. Difference (noise removed)

  4. Cross-section profile comparison

plot_wavelet_coefficients

Visualizes the wavelet decomposition showing detail coefficients at each level.

from src.terrain.diagnostics import plot_wavelet_coefficients

plot_wavelet_coefficients(
    data=dem_data,
    output_path=Path("diagnostics/wavelet_coeffs.png"),
    wavelet="db4",
    levels=3,
)

generate_full_wavelet_diagnostics

Generates complete wavelet diagnostic report with multiple visualizations.

from src.terrain.diagnostics import generate_full_wavelet_diagnostics

generate_full_wavelet_diagnostics(
    original=dem_original,
    denoised=dem_denoised,
    output_dir=Path("diagnostics/"),
    wavelet="db4",
    levels=3,
    threshold_sigma=2.0,
)

Slope-Adaptive Smoothing Diagnostics

plot_adaptive_smooth_diagnostics

Visualizes how smoothing varies based on terrain slope - showing more smoothing on flat areas and less on steep terrain.

from src.terrain.diagnostics import plot_adaptive_smooth_diagnostics

plot_adaptive_smooth_diagnostics(
    original=dem_original,
    smoothed=dem_smoothed,
    output_path=Path("diagnostics/adaptive_smooth.png"),
    pixel_size=30.0,  # meters per pixel
)

Adaptive Smooth Diagnostics

Output panels:

  1. Original DEM

  2. Smoothed DEM

  3. Computed slope map

  4. Smoothing weight mask (bright = more smoothing)

  5. Difference map

  6. Cross-section profiles

plot_adaptive_smooth_histogram

Shows histograms comparing original vs smoothed elevation distributions.

from src.terrain.diagnostics import plot_adaptive_smooth_histogram

plot_adaptive_smooth_histogram(
    original=dem_original,
    smoothed=dem_smoothed,
    output_path=Path("diagnostics/adaptive_histogram.png"),
)

Adaptive Smooth Histogram

Bump Removal Diagnostics

plot_bump_removal_diagnostics

Visualizes morphological bump removal showing original, smoothed, and removed features.

from src.terrain.diagnostics import plot_bump_removal_diagnostics

plot_bump_removal_diagnostics(
    original=dem_original,
    smoothed=dem_smoothed,
    output_path=Path("diagnostics/bump_removal.png"),
    kernel_size=5,
    structure="disk",
)

Bump Removal Diagnostics

Output panels:

  1. Original DEM

  2. After bump removal

  3. Removed features (bumps)

  4. Histograms of elevation changes

Score Upscaling Diagnostics

plot_upscale_diagnostics

Compares original and upscaled score grids with zoomed regions and histograms.

from src.terrain.diagnostics import plot_upscale_diagnostics

plot_upscale_diagnostics(
    original=scores_lowres,
    upscaled=scores_hires,
    output_path=Path("diagnostics/upscale.png"),
    scale=4,
    method="esrgan",
    title_prefix="Sledding Scores",
)

Upscale Diagnostics

Output panels:

  1. Original score grid (full view)

  2. Upscaled score grid (full view)

  3. Zoomed comparison of high-variance region

  4. Value distribution histograms

  5. Edge sharpness comparison

generate_upscale_diagnostics

Convenience function that handles file paths and method detection.

from src.terrain.diagnostics import generate_upscale_diagnostics

generate_upscale_diagnostics(
    original=scores,
    upscaled=scores_upscaled,
    output_dir=Path("diagnostics/"),
    name="sledding",
    scale=4,
    method="esrgan",
)

Render Histogram Analysis

generate_rgb_histogram

Creates RGB channel histograms for rendered images to analyze color balance.

from src.terrain.diagnostics import generate_rgb_histogram

generate_rgb_histogram(
    image_path=Path("render.png"),
    output_path=Path("render_histogram.png"),
)

Shows:

  • Overlaid R, G, B channel histograms

  • Mean and standard deviation for each channel

  • Useful for detecting color casts or imbalances

generate_luminance_histogram

Creates luminance (brightness) histogram with clipping analysis.

from src.terrain.diagnostics import generate_luminance_histogram

generate_luminance_histogram(
    image_path=Path("render.png"),
    output_path=Path("render_luminance.png"),
)

Shows:

  • Luminance distribution (ITU-R BT.601 formula)

  • Pure black (0) and pure white (255) pixel counts

  • Clipping warnings for print preparation

CLI Integration

The detroit_combined_render.py example automatically generates diagnostics when using certain flags:

# Generate upscale diagnostics
python examples/detroit_combined_render.py --upscale-scores

# Generates:
#   diagnostics/sledding_upscale_diagnostics.png
#   diagnostics/xc_upscale_diagnostics.png

# Generate adaptive smooth diagnostics
python examples/detroit_combined_render.py --adaptive-smooth --diagnostics

# Generate all render diagnostics (histograms)
python examples/detroit_combined_render.py --print-quality

# Generates:
#   output_histogram.png
#   output_luminance.png

Best Practices

When to Use Diagnostics

  1. Tuning parameters - Use diagnostics to find optimal values for smoothing, denoising, upscaling

  2. Debugging artifacts - Identify source of visual problems in renders

  3. Print preparation - Check histograms for clipping before printing

  4. Quality assurance - Verify transforms produce expected results

Performance Considerations

  • Diagnostic plots add ~1-3 seconds to processing time

  • Large arrays (>4000x4000) may use significant memory for plotting

  • Consider generating diagnostics only during development, not production

API Reference

terrain.diagnostics.plot_wavelet_diagnostics(original, denoised, output_path, title_prefix='Wavelet Denoising', nodata_value=nan, profile_row=None, cmap='terrain')[source]

Generate diagnostic plots showing wavelet denoising effects.

Creates a multi-panel figure showing: - Original DEM - Denoised DEM - Difference (noise removed) - Cross-section profile comparison

Parameters:
  • original (ndarray) – Original DEM before denoising

  • denoised (ndarray) – DEM after wavelet denoising

  • output_path (Path) – Path to save the diagnostic plot

  • title_prefix (str) – Prefix for plot titles

  • nodata_value (float) – Value treated as no data

  • profile_row (int | None) – Row index for cross-section (default: middle row)

  • cmap (str) – Colormap for elevation visualization

Returns:

Path to saved diagnostic plot

Return type:

Path

terrain.diagnostics.plot_wavelet_coefficients(original, output_path, wavelet='db4', levels=3, threshold_sigma=2.0, nodata_value=nan)[source]

Generate diagnostic plots showing wavelet coefficient distributions.

Creates a figure showing: - Coefficient histograms before/after thresholding - Decomposition levels visualization - Threshold line for each level

Parameters:
  • original (ndarray) – Original DEM

  • output_path (Path) – Path to save the diagnostic plot

  • wavelet (str) – Wavelet type used for decomposition

  • levels (int) – Number of decomposition levels

  • threshold_sigma (float) – Sigma multiplier for thresholding

  • nodata_value (float) – Value treated as no data

Returns:

Path to saved diagnostic plot

Return type:

Path

terrain.diagnostics.generate_full_wavelet_diagnostics(original, denoised, output_dir, prefix='wavelet', wavelet='db4', levels=3, threshold_sigma=2.0, nodata_value=nan)[source]

Generate all wavelet diagnostic plots.

Creates both the before/after comparison and the coefficient analysis.

Parameters:
  • original (ndarray) – Original DEM before denoising

  • denoised (ndarray) – DEM after wavelet denoising

  • output_dir (Path) – Directory to save diagnostic plots

  • prefix (str) – Filename prefix for saved plots

  • wavelet (str) – Wavelet type used for denoising

  • levels (int) – Number of decomposition levels

  • threshold_sigma (float) – Sigma multiplier used for thresholding

  • nodata_value (float) – Value treated as no data

Returns:

Tuple of (comparison_plot_path, coefficient_plot_path)

Return type:

Tuple[Path, Path]

terrain.diagnostics.plot_adaptive_smooth_diagnostics(original, smoothed, output_path, slope_threshold=2.0, smooth_sigma=5.0, transition_width=1.0, title_prefix='Slope-Adaptive Smoothing', nodata_value=nan, profile_row=None, cmap='terrain', pixel_size=None, edge_threshold=None, edge_window=5)[source]

Generate diagnostic plots showing slope-adaptive smoothing effects.

Creates a multi-panel figure showing: - Original DEM - Computed slope map - Smoothing weight mask (where smoothing is applied) - Smoothed DEM - Difference (noise removed) - Cross-section profile comparison

Parameters:
  • original (ndarray) – Original DEM before smoothing

  • smoothed (ndarray) – DEM after slope-adaptive smoothing

  • output_path (Path) – Path to save the diagnostic plot

  • slope_threshold (float) – Slope threshold in degrees used for smoothing

  • smooth_sigma (float) – Gaussian sigma used for smoothing

  • transition_width (float) – Width of sigmoid transition zone

  • title_prefix (str) – Prefix for plot titles

  • nodata_value (float) – Value treated as no data

  • profile_row (int | None) – Row index for cross-section (default: middle row)

  • cmap (str) – Colormap for elevation visualization

  • pixel_size (float | None) – Pixel size in meters (e.g., 30.0 for SRTM data). Required for accurate slope calculation.

  • edge_threshold (float | None) – Edge preservation threshold in meters (default: None). If set, shows which areas are protected due to sharp elevation changes.

  • edge_window (int) – Window size for edge detection (default: 5).

Returns:

Path to saved diagnostic plot

Return type:

Path

terrain.diagnostics.plot_adaptive_smooth_histogram(original, smoothed, output_path, slope_threshold=2.0, transition_width=1.0, title_prefix='Slope-Adaptive Smoothing', nodata_value=nan, pixel_size=None)[source]

Generate histogram analysis of slope-adaptive smoothing.

Shows distribution of slopes and how much smoothing was applied at different slope values.

Parameters:
  • original (ndarray) – Original DEM before smoothing

  • smoothed (ndarray) – DEM after slope-adaptive smoothing

  • output_path (Path) – Path to save the diagnostic plot

  • slope_threshold (float) – Slope threshold in degrees used for smoothing

  • transition_width (float) – Width of sigmoid transition zone

  • title_prefix (str) – Prefix for plot titles

  • nodata_value (float) – Value treated as no data

  • pixel_size (float | None) – Pixel size in meters (e.g., 30.0 for SRTM data). Required for accurate slope calculation.

Returns:

Path to saved diagnostic plot

Return type:

Path

terrain.diagnostics.generate_full_adaptive_smooth_diagnostics(original, smoothed, output_dir, prefix='adaptive_smooth', slope_threshold=2.0, smooth_sigma=5.0, transition_width=1.0, nodata_value=nan, pixel_size=None, edge_threshold=None, edge_window=5)[source]

Generate all slope-adaptive smoothing diagnostic plots.

Creates both the spatial comparison and the histogram analysis.

Parameters:
  • original (ndarray) – Original DEM before smoothing

  • smoothed (ndarray) – DEM after slope-adaptive smoothing

  • output_dir (Path) – Directory to save diagnostic plots

  • prefix (str) – Filename prefix for saved plots

  • slope_threshold (float) – Slope threshold in degrees

  • smooth_sigma (float) – Gaussian sigma used for smoothing

  • transition_width (float) – Width of sigmoid transition zone

  • nodata_value (float) – Value treated as no data

  • pixel_size (float | None) – Pixel size in meters (e.g., 30.0 for SRTM data). Required for accurate slope calculation.

  • edge_threshold (float | None) – Edge preservation threshold in meters (default: None). If set, shows which areas are protected due to sharp elevation changes.

  • edge_window (int) – Window size for edge detection (default: 5).

Returns:

Tuple of (spatial_plot_path, histogram_plot_path)

Return type:

Tuple[Path, Path]

terrain.diagnostics.plot_bump_removal_diagnostics(original, after_removal, output_path, kernel_size=3, title_prefix='Bump Removal', nodata_value=nan, cmap='terrain')[source]

Generate diagnostic plot for morphological bump removal.

Shows: - Original DEM - After bump removal - Bumps removed (difference) - always positive since only peaks are removed - Histogram of bump heights

Parameters:
  • original (ndarray) – Original DEM before bump removal

  • after_removal (ndarray) – DEM after morphological opening

  • output_path (Path) – Path to save the diagnostic plot

  • kernel_size (int) – Kernel size used for removal

  • title_prefix (str) – Prefix for plot titles

  • nodata_value (float) – Value treated as no data

  • cmap (str) – Colormap for elevation visualization

Returns:

Path to saved diagnostic plot

Return type:

Path

terrain.diagnostics.generate_bump_removal_diagnostics(original, after_removal, output_dir, prefix='bump_removal', kernel_size=3, nodata_value=nan)[source]

Generate bump removal diagnostic plot.

Parameters:
  • original (ndarray) – Original DEM before bump removal

  • after_removal (ndarray) – DEM after morphological opening

  • output_dir (Path) – Directory to save diagnostic plot

  • prefix (str) – Filename prefix

  • kernel_size (int) – Kernel size used for removal

  • nodata_value (float) – Value treated as no data

Returns:

Path to saved diagnostic plot

Return type:

Path

terrain.diagnostics.plot_upscale_diagnostics(original, upscaled, output_path, scale=4, method='unknown', title_prefix='Score Upscaling', nodata_value=nan, cmap='viridis')[source]

Generate diagnostic plots showing score upscaling effects.

Creates a multi-panel figure showing: - Original score grid - Upscaled score grid - Zoomed comparison of a region - Histograms of value distributions - Edge detail comparison

Parameters:
  • original (ndarray) – Original score grid before upscaling

  • upscaled (ndarray) – Score grid after upscaling

  • output_path (Path) – Path to save the diagnostic plot

  • scale (int) – Upscaling factor used

  • method (str) – Upscaling method name (for title)

  • title_prefix (str) – Prefix for plot titles

  • nodata_value (float) – Value treated as no data

  • cmap (str) – Colormap for score visualization

Returns:

Path to saved diagnostic plot

Return type:

Path

terrain.diagnostics.generate_upscale_diagnostics(original, upscaled, output_dir, prefix='score_upscale', scale=4, method='unknown', nodata_value=nan, cmap='viridis')[source]

Generate upscale diagnostic plot.

Parameters:
  • original (ndarray) – Original score grid before upscaling

  • upscaled (ndarray) – Score grid after upscaling

  • output_dir (Path) – Directory to save diagnostic plot

  • prefix (str) – Filename prefix

  • scale (int) – Upscaling factor used

  • method (str) – Upscaling method name

  • nodata_value (float) – Value treated as no data

  • cmap (str) – Colormap for score visualization

Returns:

Path to saved diagnostic plot

Return type:

Path

terrain.diagnostics.generate_rgb_histogram(image_path, output_path)[source]

Generate and save an RGB histogram of a rendered image.

Creates a figure with histograms for each color channel (R, G, B) overlaid on the same axes with transparency. Useful for analyzing color balance and distribution in rendered outputs.

Parameters:
  • image_path (Path) – Path to the rendered image (PNG, JPEG, etc.)

  • output_path (Path) – Path to save the histogram image

Returns:

Path to saved histogram image, or None if failed

Return type:

Path | None

terrain.diagnostics.generate_luminance_histogram(image_path, output_path)[source]

Generate and save a luminance (B&W) histogram of a rendered image.

Shows distribution of brightness values with annotations for pure black and pure white pixel counts. Useful for checking exposure and clipping in rendered outputs, especially for print preparation.

Parameters:
  • image_path (Path) – Path to the rendered image (PNG, JPEG, etc.)

  • output_path (Path) – Path to save the histogram image

Returns:

Path to saved histogram image, or None if failed

Return type:

Path | None

See Also

  • Combined Render: Full-Featured Example - Full example using diagnostics

  • wavelet_denoise_dem() - Wavelet denoising transform

  • slope_adaptive_smooth() - Adaptive smoothing transform

  • upscale_scores() - Score upscaling function