lichen-mapping-with-spl

# Lichen mapping with Single Photon LiDAR (SPL)
Open-source Python workflow for lichen mapping facilitated by Single-Photon LiDAR (SPL).
Open-Source Code and Project Website:https://qianyorku.github.io/lichen-mapping-with-spl/.

## **Overview**
This repository provides a reproducible workflow for lichen mapping facilitated by Single Photon LiDAR (SPL) in boreal mixedwood forests.  
It implements a modular Python pipeline for:

- Coordinate cleaning and consistent UTM projection for field plots  
- Plot-level clipping of SPL canopy height models (CHM) and point clouds (LAZ)  
- Individual Tree Crown (ITC) detection and delineation  
- Plot-level LiDAR feature extraction from CHM and LAZ  
- Lichen presence modeling with multiple classifiers (RF, Logit-EN, SVM-RBF)

The code is designed as an open, self-contained project guide so that researchers and practitioners can adapt the workflow to other regions and forest types.

---

## **Repository structure**

```text
lichen-mapping-with-spl/
├─ src/
│   ├─ verify_and_convert_coords_for_clipping.py
│   ├─ clip_plots_20m.py
│   ├─ itc_delineation_and_plot_features.py
│   ├─ plot_chm_laz_features.py
│   └─ lichen_models_rf_logit_svm.py
│
├─ data/
│   └─ demo_clipped_plots/
│       ├─ DEMO001_CHM_20m.tif
│       ├─ DEMO001_LAZ_20m.laz
│       └─ (optional: a few more tiny CHM/LAZ demo plots)
│
├─ outputs/
│   ├─ itc_delineation/        # ITC crowns & per-plot ITC metrics
│   ├─ plot_level_features/    # CHM/LAZ plot-level features
│   └─ lichen_models/          # model metrics, figures, tables
│
├─ README.md
├─ requirements.txt
├─ .gitignore
└─ LICENSE

Scripts overview

All Python scripts are in src/:

verify_and_convert_coords_for_clipping.py

Cleans and validates the plot coordinate table (CSV).

Uses latitude/longitude to:

Outputs:


clip_plots_20m.py

Uses the cleaned coordinate CSV and the original SPL CHM/LAZ tiles.

For each plot, it:

Outputs:

In this repository, you start from already clipped demo plots in data/demo_clipped_plots/.


itc_delineation_and_plot_features.py

Batch ITC detection and crown delineation when CHM and LAZ are in the same folder.

Automatically pairs files such as:

ITC detection:

Crown delineation:

Outputs per plot:

Outputs per batch:


plot_chm_laz_features.py

Extracts plot-level LiDAR features directly from CHM rasters and LAZ point clouds.

Uses filename patterns like:

CHM features include:

LAZ features include:

Output:


lichen_models_rf_logit_svm.py

Builds and evaluates lichen presence models using:

Assumes the feature table has a binary column lichen_presence.

Workflow:

Outputs:


Installation

1. Create a Python environment

It is recommended to use conda or mamba:

conda create -n spl_lichen python=3.10
conda activate spl_lichen

2. Install dependencies

From the repository root:

pip install -r requirements.txt

If you encounter issues with rasterio or geopandas, you may install them via conda first.


Demo data

Small demo clipped plots (e.g., DEMO001_CHM_20m.tif, DEMO001_LAZ_20m.laz) are provided under:

data/demo_clipped_plots/

The full SPL tiles and the original plot coordinate CSV used in the real project are not included in this repository.


Example workflow

1. ITC delineation and ITC-based plot features

python src/itc_delineation_and_plot_features.py

By default, the script assumes:

DATA_DIR = "data/demo_clipped_plots"
OUT_ROOT = "outputs/itc_delineation"

Outputs will be written to outputs/itc_delineation/.


2. Plot-level CHM + LAZ features

python src/plot_chm_laz_features.py

Default paths:

CLIPPED_DIR = Path("data/demo_clipped_plots")
OUTPUT_CSV  = Path("outputs/plot_level_features/lichen_features.csv")

You can merge this table with your own lichen ground truth to add a lichen_presence column.


3. Lichen presence modeling

After adding a lichen_presence column to lichen_features.csv, run:

python src/lichen_models_rf_logit_svm.py

By default:

file_path = "outputs/plot_level_features/lichen_features.csv"
out_dir   = "outputs/lichen_models"

Data and privacy notes