ecological-agent-skills 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT_CONTEXT.md +191 -0
- package/CATALOG.md +329 -0
- package/LICENSE +692 -0
- package/README.md +347 -0
- package/bin/install.mjs +168 -0
- package/docs/comparison-with-alternatives.md +38 -0
- package/docs/global-examples-index.md +103 -0
- package/docs/repository-statistics.md +101 -0
- package/docs/theoretical-foundations.md +188 -0
- package/environment.yaml +106 -0
- package/examples/community/arctic_tundra_vegetation_example.md +247 -0
- package/examples/community/bird_landuse_example.md +63 -0
- package/examples/community/phytoplankton_reservoir_example.md +60 -0
- package/examples/community/reef_fish_indopacific_example.md +221 -0
- package/examples/impact/baci_road_example.md +57 -0
- package/examples/impact/ecosystem_services_atlantic_forest.md +83 -0
- package/examples/impact/forest_loss_borneo_timeseries_example.md +225 -0
- package/examples/occupancy/puma_camera_example.md +61 -0
- package/examples/occupancy/snow_leopard_himalayas_example.md +204 -0
- package/examples/reproducible/whittaker_biome_sdm_example.md +406 -0
- package/examples/sdm/anteater_cerrado_example.md +69 -0
- package/examples/sdm/jaguar_amazon_example.md +80 -0
- package/examples/sdm/koala_climate_change_example.md +170 -0
- package/examples/sdm/wolf_recolonization_europe_example.md +193 -0
- package/package.json +43 -0
- package/renv.lock +194 -0
- package/skills/SKILL_INDEX.json +1020 -0
- package/skills/acoustic-monitoring/SKILL.md +163 -0
- package/skills/acoustic-monitoring/examples/example-prompts.md +100 -0
- package/skills/acoustic-monitoring/examples/temperate_forest_birds_example.md +285 -0
- package/skills/acoustic-monitoring/resources/acoustic-indices-reference.md +93 -0
- package/skills/acoustic-monitoring/resources/soundscape-ecology-guide.md +90 -0
- package/skills/acoustic-monitoring/resources/species-id-tools-comparison.md +89 -0
- package/skills/acoustic-monitoring/scripts/batch_species_detection.py +360 -0
- package/skills/acoustic-monitoring/scripts/compute_acoustic_indices.R +235 -0
- package/skills/acoustic-monitoring/scripts/compute_acoustic_indices.py +374 -0
- package/skills/biostatistics-workbench/SKILL.md +140 -0
- package/skills/biostatistics-workbench/examples/example-prompts.md +39 -0
- package/skills/biostatistics-workbench/resources/effect-size-reference.md +81 -0
- package/skills/biostatistics-workbench/resources/glm-family-link-reference.md +47 -0
- package/skills/biostatistics-workbench/resources/test-selection-guide.md +93 -0
- package/skills/biostatistics-workbench/scripts/glm_pipeline.R +78 -0
- package/skills/biostatistics-workbench/scripts/glm_pipeline.py +210 -0
- package/skills/camera-trap-processing/SKILL.md +159 -0
- package/skills/camera-trap-processing/examples/example-prompts.md +103 -0
- package/skills/camera-trap-processing/examples/leopard_serengeti_example.md +231 -0
- package/skills/camera-trap-processing/resources/activity-patterns-reference.md +113 -0
- package/skills/camera-trap-processing/resources/camtrapR-workflow-guide.md +130 -0
- package/skills/camera-trap-processing/resources/detection-event-definition-guide.md +89 -0
- package/skills/camera-trap-processing/scripts/estimate_activity.R +169 -0
- package/skills/camera-trap-processing/scripts/process_camtrap_data.R +179 -0
- package/skills/camera-trap-processing/scripts/process_camtrap_data.py +192 -0
- package/skills/community-ecology-ordination/SKILL.md +133 -0
- package/skills/community-ecology-ordination/examples/example-prompts.md +35 -0
- package/skills/community-ecology-ordination/resources/dissimilarity-metric-guide.md +53 -0
- package/skills/community-ecology-ordination/resources/nmds-interpretation-guide.md +104 -0
- package/skills/community-ecology-ordination/scripts/__pycache__/community_analysis.cpython-311.pyc +0 -0
- package/skills/community-ecology-ordination/scripts/community_analysis.R +143 -0
- package/skills/community-ecology-ordination/scripts/community_analysis.py +231 -0
- package/skills/ecological-data-foundation/SKILL.md +129 -0
- package/skills/ecological-data-foundation/examples/example-prompts.md +40 -0
- package/skills/ecological-data-foundation/resources/coordinate-cleaning-flags.md +66 -0
- package/skills/ecological-data-foundation/resources/darwin-core-glossary.md +91 -0
- package/skills/ecological-data-foundation/resources/data-citation-guide.md +265 -0
- package/skills/ecological-data-foundation/resources/gbif-data-citation-guide.md +193 -0
- package/skills/ecological-data-foundation/resources/qa-checklist.md +83 -0
- package/skills/ecological-data-foundation/scripts/__pycache__/clean_occurrences.cpython-311.pyc +0 -0
- package/skills/ecological-data-foundation/scripts/__pycache__/download_from_ebird.cpython-311.pyc +0 -0
- package/skills/ecological-data-foundation/scripts/__pycache__/download_from_inat.cpython-311.pyc +0 -0
- package/skills/ecological-data-foundation/scripts/__pycache__/download_from_iucn.cpython-311.pyc +0 -0
- package/skills/ecological-data-foundation/scripts/__pycache__/download_from_obis.cpython-311.pyc +0 -0
- package/skills/ecological-data-foundation/scripts/clean_occurrences.R +230 -0
- package/skills/ecological-data-foundation/scripts/clean_occurrences.py +268 -0
- package/skills/ecological-data-foundation/scripts/download_from_ebird.R +251 -0
- package/skills/ecological-data-foundation/scripts/download_from_ebird.py +364 -0
- package/skills/ecological-data-foundation/scripts/download_from_gbif.R +315 -0
- package/skills/ecological-data-foundation/scripts/download_from_gbif.py +407 -0
- package/skills/ecological-data-foundation/scripts/download_from_inat.R +238 -0
- package/skills/ecological-data-foundation/scripts/download_from_inat.py +304 -0
- package/skills/ecological-data-foundation/scripts/download_from_iucn.R +273 -0
- package/skills/ecological-data-foundation/scripts/download_from_iucn.py +344 -0
- package/skills/ecological-data-foundation/scripts/download_from_obis.R +248 -0
- package/skills/ecological-data-foundation/scripts/download_from_obis.py +318 -0
- package/skills/ecological-impact-assessment/SKILL.md +123 -0
- package/skills/ecological-impact-assessment/examples/example-prompts.md +32 -0
- package/skills/ecological-impact-assessment/resources/baci-design-guide.md +55 -0
- package/skills/ecological-impact-assessment/resources/fragmentation-metrics-reference.md +86 -0
- package/skills/ecological-impact-assessment/resources/pressure-index-template.md +78 -0
- package/skills/ecological-impact-assessment/resources/study-design-guide.md +168 -0
- package/skills/ecological-impact-assessment/scripts/baci_analysis.R +161 -0
- package/skills/ecological-impact-assessment/scripts/fragmentation_analysis.py +141 -0
- package/skills/ecological-impact-assessment/scripts/power_analysis_baci.R +274 -0
- package/skills/ecosystem-services-assessment/SKILL.md +125 -0
- package/skills/ecosystem-services-assessment/examples/example-prompts.md +24 -0
- package/skills/ecosystem-services-assessment/resources/es-indicator-reference.md +45 -0
- package/skills/ecosystem-services-assessment/resources/invest-parameter-guide.md +86 -0
- package/skills/ecosystem-services-assessment/resources/rusle-coefficients.md +88 -0
- package/skills/ecosystem-services-assessment/scripts/__pycache__/compute_es.cpython-311.pyc +0 -0
- package/skills/ecosystem-services-assessment/scripts/compute_es.py +189 -0
- package/skills/ecosystem-services-assessment/scripts/tradeoff_analysis.R +161 -0
- package/skills/environmental-time-series/SKILL.md +125 -0
- package/skills/environmental-time-series/examples/example-prompts.md +33 -0
- package/skills/environmental-time-series/resources/anomaly-indices-reference.md +88 -0
- package/skills/environmental-time-series/resources/bfast-parameter-guide.md +69 -0
- package/skills/environmental-time-series/scripts/__pycache__/recovery_trajectory.cpython-311.pyc +0 -0
- package/skills/environmental-time-series/scripts/__pycache__/trend_analysis.cpython-311.pyc +0 -0
- package/skills/environmental-time-series/scripts/recovery_trajectory.R +305 -0
- package/skills/environmental-time-series/scripts/recovery_trajectory.py +178 -0
- package/skills/environmental-time-series/scripts/trend_analysis.R +192 -0
- package/skills/environmental-time-series/scripts/trend_analysis.py +184 -0
- package/skills/geoprocessing-for-ecology/SKILL.md +123 -0
- package/skills/geoprocessing-for-ecology/examples/example-prompts.md +32 -0
- package/skills/geoprocessing-for-ecology/resources/crs-reference.md +62 -0
- package/skills/geoprocessing-for-ecology/resources/global-predictor-sources.md +331 -0
- package/skills/geoprocessing-for-ecology/resources/resampling-methods.md +57 -0
- package/skills/geoprocessing-for-ecology/scripts/__pycache__/download_predictors.cpython-311.pyc +0 -0
- package/skills/geoprocessing-for-ecology/scripts/download_predictors.R +239 -0
- package/skills/geoprocessing-for-ecology/scripts/download_predictors.py +379 -0
- package/skills/geoprocessing-for-ecology/scripts/stack_and_extract.R +224 -0
- package/skills/geoprocessing-for-ecology/scripts/stack_and_extract.py +172 -0
- package/skills/landscape-connectivity/SKILL.md +170 -0
- package/skills/landscape-connectivity/examples/example-prompts.md +96 -0
- package/skills/landscape-connectivity/examples/jaguar_mesoamerica_corridor_example.md +271 -0
- package/skills/landscape-connectivity/resources/circuitscape-parameter-guide.md +155 -0
- package/skills/landscape-connectivity/resources/graph-theory-for-ecology.md +134 -0
- package/skills/landscape-connectivity/resources/resistance-surface-guide.md +141 -0
- package/skills/landscape-connectivity/scripts/connectivity_analysis.py +387 -0
- package/skills/landscape-connectivity/scripts/connectivity_metrics.R +274 -0
- package/skills/landscape-connectivity/scripts/resistance_surface.R +239 -0
- package/skills/model-validation-and-uncertainty/SKILL.md +131 -0
- package/skills/model-validation-and-uncertainty/examples/example-prompts.md +30 -0
- package/skills/model-validation-and-uncertainty/resources/extrapolation-risk-guide.md +236 -0
- package/skills/model-validation-and-uncertainty/resources/metric-selection-guide.md +52 -0
- package/skills/model-validation-and-uncertainty/resources/threshold-selection-guide.md +64 -0
- package/skills/model-validation-and-uncertainty/scripts/__pycache__/validate_model.cpython-311.pyc +0 -0
- package/skills/model-validation-and-uncertainty/scripts/extrapolation_risk.R +315 -0
- package/skills/model-validation-and-uncertainty/scripts/validate_model.py +226 -0
- package/skills/model-validation-and-uncertainty/scripts/validate_sdm.R +162 -0
- package/skills/occupancy-and-detection/SKILL.md +126 -0
- package/skills/occupancy-and-detection/examples/example-prompts.md +33 -0
- package/skills/occupancy-and-detection/resources/detection-history-format.md +100 -0
- package/skills/occupancy-and-detection/resources/occupancy-study-design.md +47 -0
- package/skills/occupancy-and-detection/scripts/__pycache__/occupancy_analysis.cpython-311.pyc +0 -0
- package/skills/occupancy-and-detection/scripts/occupancy_analysis.R +160 -0
- package/skills/occupancy-and-detection/scripts/occupancy_analysis.py +159 -0
- package/skills/population-viability-analysis/SKILL.md +161 -0
- package/skills/population-viability-analysis/examples/african_elephant_pva_example.md +266 -0
- package/skills/population-viability-analysis/examples/example-prompts.md +95 -0
- package/skills/population-viability-analysis/resources/extinction-risk-thresholds.md +128 -0
- package/skills/population-viability-analysis/resources/matrix-model-guide.md +139 -0
- package/skills/population-viability-analysis/resources/sensitivity-elasticity-reference.md +182 -0
- package/skills/population-viability-analysis/scripts/matrix_pva.R +258 -0
- package/skills/population-viability-analysis/scripts/pva_analysis.py +442 -0
- package/skills/population-viability-analysis/scripts/stochastic_pva.R +353 -0
- package/skills/predictive-modeling-best-practices/SKILL.md +136 -0
- package/skills/predictive-modeling-best-practices/examples/example-prompts.md +58 -0
- package/skills/predictive-modeling-best-practices/resources/collinearity-decision-tree.md +65 -0
- package/skills/predictive-modeling-best-practices/resources/sampling-bias-correction.md +267 -0
- package/skills/predictive-modeling-best-practices/resources/spatial-cv-guide.md +73 -0
- package/skills/predictive-modeling-best-practices/scripts/__pycache__/spatial_cv.cpython-311.pyc +0 -0
- package/skills/predictive-modeling-best-practices/scripts/collinearity_check.R +112 -0
- package/skills/predictive-modeling-best-practices/scripts/spatial_cv.py +182 -0
- package/skills/reproducible-ecology-pipeline/SKILL.md +139 -0
- package/skills/reproducible-ecology-pipeline/examples/example-prompts.md +35 -0
- package/skills/reproducible-ecology-pipeline/resources/directory-structure-template.md +94 -0
- package/skills/reproducible-ecology-pipeline/resources/params-yaml-template.yaml +84 -0
- package/skills/reproducible-ecology-pipeline/resources/reproducibility-checklist-template.md +66 -0
- package/skills/reproducible-ecology-pipeline/scripts/generate_file_manifest.py +110 -0
- package/skills/reproducible-ecology-pipeline/scripts/init_project.sh +53 -0
- package/skills/spatial-prioritization/SKILL.md +162 -0
- package/skills/spatial-prioritization/examples/biodiversity_hotspot_prioritization_example.md +289 -0
- package/skills/spatial-prioritization/examples/example-prompts.md +93 -0
- package/skills/spatial-prioritization/resources/cost-surface-reference.md +130 -0
- package/skills/spatial-prioritization/resources/marxan-vs-prioritizr-comparison.md +125 -0
- package/skills/spatial-prioritization/resources/prioritizr-formulation-guide.md +188 -0
- package/skills/spatial-prioritization/resources/representation-targets-guide.md +186 -0
- package/skills/spatial-prioritization/scripts/prioritization_sensitivity.R +320 -0
- package/skills/spatial-prioritization/scripts/run_prioritization.R +336 -0
- package/skills/species-distribution-modeling/SKILL.md +139 -0
- package/skills/species-distribution-modeling/examples/example-prompts.md +36 -0
- package/skills/species-distribution-modeling/resources/algorithm-comparison.md +25 -0
- package/skills/species-distribution-modeling/resources/calibration-area-guide.md +71 -0
- package/skills/species-distribution-modeling/resources/climate-scenario-preparation.md +170 -0
- package/skills/species-distribution-modeling/resources/maxent-calibration-guide.md +211 -0
- package/skills/species-distribution-modeling/resources/sdm-checklist.md +37 -0
- package/skills/species-distribution-modeling/scripts/predict_distribution.R +236 -0
- package/skills/species-distribution-modeling/scripts/predict_distribution.py +286 -0
- package/skills/species-distribution-modeling/scripts/prepare_future_layers.R +351 -0
- package/skills/species-distribution-modeling/scripts/project_scenarios.R +220 -0
- package/skills/species-distribution-modeling/scripts/run_ensemble_sdm.R +99 -0
- package/skills/species-distribution-modeling/scripts/sdm_pipeline.py +318 -0
- package/skills/species-distribution-modeling/scripts/tune_maxnet.R +344 -0
- package/templates/SKILL_TEMPLATE.md +225 -0
- package/templates/checklists/data-submission-checklist.md +38 -0
- package/templates/checklists/post-analysis-checklist.md +55 -0
- package/templates/checklists/pre-analysis-checklist.md +31 -0
- package/templates/prompts/debug-skill.md +47 -0
- package/templates/prompts/invoke-skill.md +34 -0
- package/templates/prompts/invoke-workflow.md +45 -0
- package/templates/reports/technical-report-template.md +80 -0
- package/templates/scripts/logger_setup.R +79 -0
- package/templates/scripts/logger_setup.py +119 -0
- package/templates/scripts/params_loader.R +28 -0
- package/templates/scripts/params_loader.py +38 -0
- package/workflows/analyze-community-structure/WORKFLOW.md +72 -0
- package/workflows/analyze-environmental-change/WORKFLOW.md +73 -0
- package/workflows/assess-ecological-impact/WORKFLOW.md +75 -0
- package/workflows/assess-ecosystem-services/WORKFLOW.md +68 -0
- package/workflows/assess-landscape-connectivity/WORKFLOW.md +84 -0
- package/workflows/build-fire-risk-map/WORKFLOW.md +79 -0
- package/workflows/produce-technical-report/WORKFLOW.md +113 -0
- package/workflows/run-camera-trap-occupancy/WORKFLOW.md +87 -0
- package/workflows/run-conservation-prioritization/WORKFLOW.md +89 -0
- package/workflows/run-multispecies-screening/WORKFLOW.md +197 -0
- package/workflows/run-occupancy-analysis/WORKFLOW.md +74 -0
- package/workflows/run-population-viability/WORKFLOW.md +90 -0
- package/workflows/run-sdm-study/WORKFLOW.md +99 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill_id: landscape-connectivity
|
|
3
|
+
example_type: full_walkthrough
|
|
4
|
+
taxon: Jaguar (Panthera onca)
|
|
5
|
+
region: Mesoamerican Biological Corridor
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Jaguar Corridor Analysis — Mesoamerican Biological Corridor Walkthrough
|
|
9
|
+
|
|
10
|
+
## Study Context
|
|
11
|
+
|
|
12
|
+
**Location:** Guatemala–Honduras–Nicaragua corridor, Mesoamerican Biological Corridor (MBC)
|
|
13
|
+
**Objective:** Identify critical habitat patches and movement corridors for jaguars along the MBC; prioritise areas for protection and restoration
|
|
14
|
+
**Input data:**
|
|
15
|
+
- Forest cover 2023 (30-m resolution, derived from Global Forest Watch)
|
|
16
|
+
- Land cover map (11 classes, 30-m resolution)
|
|
17
|
+
- DEM (SRTM 30 m)
|
|
18
|
+
- Road network (OSM)
|
|
19
|
+
- 124 camera trap stations with jaguar detections (occupancy data)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Step 1 — Build Resistance Surface
|
|
24
|
+
|
|
25
|
+
### Resistance table (jaguar-specific)
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
data/jaguar_resistance.csv:
|
|
29
|
+
lc_code, resistance, description
|
|
30
|
+
1, 1, Dense tropical forest
|
|
31
|
+
2, 3, Secondary forest
|
|
32
|
+
3, 5, Riparian gallery forest
|
|
33
|
+
4, 8, Cerrado/savanna
|
|
34
|
+
5, 15, Shrubland
|
|
35
|
+
6, 25, Pasture (low density)
|
|
36
|
+
7, 50, Pasture (high density)
|
|
37
|
+
8, 80, Paved road
|
|
38
|
+
9,200, Highway
|
|
39
|
+
10,500, Urban
|
|
40
|
+
11, 10, Wetland/swamp
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
Rscript resistance_surface.R \
|
|
45
|
+
data/landcover_2023_mbc.tif \
|
|
46
|
+
data/jaguar_resistance.csv \
|
|
47
|
+
outputs/resistance/ \
|
|
48
|
+
data/dem_srtm_30m.tif \
|
|
49
|
+
data/roads_osm.shp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Output statistics:**
|
|
53
|
+
|
|
54
|
+
| Statistic | Value |
|
|
55
|
+
|-----------|-------|
|
|
56
|
+
| Min resistance | 1.0 |
|
|
57
|
+
| Median | 8.3 |
|
|
58
|
+
| Mean | 24.7 |
|
|
59
|
+
| Q95 | 95.4 |
|
|
60
|
+
| Max (capped) | 1000.0 |
|
|
61
|
+
|
|
62
|
+
**Decision:** Highway cells assigned resistance = 200 (not 1000) for this analysis, because jaguars have been documented crossing highways via culverts at night. Decision logged with citation (Quigley & Crawshaw 1992).
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Step 2 — Delineate Forest Patches
|
|
67
|
+
|
|
68
|
+
```r
|
|
69
|
+
suppressPackageStartupMessages(library(terra))
|
|
70
|
+
suppressPackageStartupMessages(library(sf))
|
|
71
|
+
|
|
72
|
+
forest <- rast("data/forest_cover_2023_mbc.tif")
|
|
73
|
+
# Patches: connected forest cells ≥ 500 ha
|
|
74
|
+
patches_r <- patches(forest == 1, directions = 8)
|
|
75
|
+
# Compute patch sizes
|
|
76
|
+
patch_sizes <- freq(patches_r)
|
|
77
|
+
large_patches <- patch_sizes[patch_sizes$count * 0.09 >= 500, ] # 30m² = 0.0009 ha
|
|
78
|
+
forest_patches <- as.polygons(patches_r %in% large_patches$value)
|
|
79
|
+
forest_patches_sf <- st_as_sf(forest_patches)
|
|
80
|
+
forest_patches_sf$area_ha <- as.numeric(st_area(forest_patches_sf)) / 1e4
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Result:** 214 forest patches ≥ 500 ha identified.
|
|
84
|
+
- Median patch area: 1,240 ha
|
|
85
|
+
- Largest patch: 312,000 ha (Maya Biosphere Reserve)
|
|
86
|
+
- Range: 502–312,000 ha
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Step 3 — Graph Connectivity Analysis
|
|
91
|
+
|
|
92
|
+
### Sensitivity analysis across dispersal distances
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Jaguar max dispersal: 50–500 km reported; use range 20–80 km
|
|
96
|
+
for dmax in 20000 50000 80000; do
|
|
97
|
+
Rscript connectivity_metrics.R \
|
|
98
|
+
data/forest_patches_500ha.shp \
|
|
99
|
+
outputs/connectivity/dmax_${dmax}/ \
|
|
100
|
+
$dmax \
|
|
101
|
+
area_ha
|
|
102
|
+
done
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Sensitivity results:**
|
|
106
|
+
|
|
107
|
+
| dmax (m) | IIC | PC | n_components | Largest component |
|
|
108
|
+
|----------|-----|----|----|---|
|
|
109
|
+
| 20,000 | 0.0412 | 0.0389 | 18 | 71 patches |
|
|
110
|
+
| 50,000 | 0.0847 | 0.0814 | 7 | 142 patches |
|
|
111
|
+
| 80,000 | 0.1183 | 0.1156 | 3 | 198 patches |
|
|
112
|
+
|
|
113
|
+
**Interpretation:** At all dispersal distances, landscape connectivity is < 0.12 — indicating high fragmentation. The MBC is not functionally connected for jaguars across most of its length.
|
|
114
|
+
|
|
115
|
+
**Decision:** Analysis proceeds with dmax = 50,000 m (50 km), representing conservative mid-range jaguar dispersal (Rabinowitz & Zeller 2010).
|
|
116
|
+
|
|
117
|
+
### Top patches by dPC
|
|
118
|
+
|
|
119
|
+
```r
|
|
120
|
+
metrics <- read.csv("outputs/connectivity/dmax_50000/patch_metrics.csv")
|
|
121
|
+
head(metrics[, c("patch_id", "area_ha", "dPC_pct", "BC_norm")], 10)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
| patch_id | area_ha | dPC (%) | BC (norm) |
|
|
125
|
+
|----------|---------|---------|-----------|
|
|
126
|
+
| P001 | 312,000 | 18.4 | 0.42 |
|
|
127
|
+
| P017 | 85,200 | 12.1 | 0.38 |
|
|
128
|
+
| P003 | 142,100 | 9.7 | 0.29 |
|
|
129
|
+
| P089 | 8,400 | **7.2** | **0.81** |
|
|
130
|
+
| P122 | 3,200 | 5.1 | 0.76 |
|
|
131
|
+
| P071 | 12,800 | 4.8 | 0.67 |
|
|
132
|
+
|
|
133
|
+
**Key finding:** Patch P089 (8,400 ha) has disproportionately high dPC (7.2%) and betweenness centrality (0.81) relative to its size. It is a **stepping stone** connecting the two largest forest blocks. High BC = critical corridor function.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Step 4 — Circuitscape Current Flow
|
|
138
|
+
|
|
139
|
+
```r
|
|
140
|
+
source("scripts/run_circuitscape.R")
|
|
141
|
+
|
|
142
|
+
# Use top 20 patches by dPC as focal nodes
|
|
143
|
+
focal_patches <- metrics[1:20, "patch_id"]
|
|
144
|
+
focal_shp <- forest_patches_sf[forest_patches_sf$patch_id %in% focal_patches, ]
|
|
145
|
+
st_write(focal_shp, "data/focal_nodes.shp", delete_dsn = TRUE)
|
|
146
|
+
|
|
147
|
+
cur_map <- run_circuitscape(
|
|
148
|
+
resistance_tif = "outputs/resistance/resistance_combined.tif",
|
|
149
|
+
focal_points_shp = "data/focal_nodes.shp",
|
|
150
|
+
output_dir = "outputs/circuitscape/",
|
|
151
|
+
scenario = "pairwise"
|
|
152
|
+
)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Pinch point extraction:**
|
|
156
|
+
|
|
157
|
+
```r
|
|
158
|
+
cur <- rast("outputs/circuitscape/cs_output_cum_curmap.asc")
|
|
159
|
+
q95 <- quantile(values(cur), 0.95, na.rm = TRUE)
|
|
160
|
+
pinch <- cur >= q95
|
|
161
|
+
writeRaster(pinch, "outputs/circuitscape/pinchpoints.tif", overwrite = TRUE)
|
|
162
|
+
# Extract pinch point polygons for reporting
|
|
163
|
+
pinch_poly <- as.polygons(pinch)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Results:** 23 pinch point clusters identified, totalling ~180 km². Top 5:
|
|
167
|
+
|
|
168
|
+
| Pinch point | Area (km²) | Location | Threat |
|
|
169
|
+
|-------------|-----------|----------|--------|
|
|
170
|
+
| PP01 | 42 | Petén–Alta Verapaz junction | Active deforestation |
|
|
171
|
+
| PP02 | 31 | Río Motagua corridor | Highway CA-9 |
|
|
172
|
+
| PP03 | 18 | Honduras–Nicaragua border | Cattle expansion |
|
|
173
|
+
| PP04 | 12 | Caribbean lowlands Guatemala | Oil palm |
|
|
174
|
+
| PP05 | 8 | Bay Islands bridge | Tourism development |
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Step 5 — Scenario Analysis: Corridor Protection
|
|
179
|
+
|
|
180
|
+
**Question:** If PP01 (42 km²) were protected and restored to forest, how much would PC increase?
|
|
181
|
+
|
|
182
|
+
```r
|
|
183
|
+
# Create scenario patch: add PP01 as new forest patch
|
|
184
|
+
pp01 <- data.frame(
|
|
185
|
+
patch_id = "PP01_restored",
|
|
186
|
+
x = centroid_x, y = centroid_y,
|
|
187
|
+
area_ha = 4200
|
|
188
|
+
)
|
|
189
|
+
patches_scenario <- rbind(patches_original, pp01)
|
|
190
|
+
|
|
191
|
+
# Recompute connectivity
|
|
192
|
+
python_cmd <- sprintf(
|
|
193
|
+
"python connectivity_analysis.py data/patches_scenario.csv outputs/scenario/ --dmax 50000"
|
|
194
|
+
)
|
|
195
|
+
system(python_cmd)
|
|
196
|
+
|
|
197
|
+
pc_scenario <- read.csv("outputs/scenario/landscape_summary.csv")
|
|
198
|
+
pc_baseline <- 0.0814
|
|
199
|
+
pc_new <- pc_scenario$value[pc_scenario$metric == "PC"]
|
|
200
|
+
cat(sprintf("PC improvement: %.4f → %.4f (+%.1f%%)\n",
|
|
201
|
+
pc_baseline, pc_new, (pc_new - pc_baseline) / pc_baseline * 100))
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Result:** Restoring PP01 increases PC from 0.0814 to 0.1021 (+25.4%). This is the single highest-leverage restoration action in the landscape.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Step 6 — Final Outputs
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
outputs/
|
|
212
|
+
├── resistance/
|
|
213
|
+
│ ├── resistance_lc.tif
|
|
214
|
+
│ ├── resistance_combined.tif # LC + slope + road proximity
|
|
215
|
+
│ └── resistance_stats.csv
|
|
216
|
+
├── connectivity/
|
|
217
|
+
│ └── dmax_50000/
|
|
218
|
+
│ ├── patch_metrics.csv # 214 patches, ranked by dPC
|
|
219
|
+
│ ├── landscape_summary.csv
|
|
220
|
+
│ └── connectivity_graph.png
|
|
221
|
+
├── circuitscape/
|
|
222
|
+
│ ├── cs_output_cum_curmap.asc # Cumulative current flow
|
|
223
|
+
│ ├── pinchpoints.tif # Top 5% current cells
|
|
224
|
+
│ └── pinchpoints.shp # Polygon pinch points
|
|
225
|
+
└── scenario/
|
|
226
|
+
└── landscape_summary.csv # PC after PP01 restoration
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Summary Table
|
|
232
|
+
|
|
233
|
+
| Metric | Baseline | PP01 restored | Change |
|
|
234
|
+
|--------|---------|--------------|--------|
|
|
235
|
+
| IIC | 0.0847 | 0.1094 | +29.2% |
|
|
236
|
+
| PC | 0.0814 | 0.1021 | +25.4% |
|
|
237
|
+
| n components | 7 | 6 | −1 |
|
|
238
|
+
| Largest component (patches) | 142 | 158 | +16 |
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Decision Log
|
|
243
|
+
|
|
244
|
+
```yaml
|
|
245
|
+
- date: 2025-01-20
|
|
246
|
+
skill_id: landscape-connectivity
|
|
247
|
+
decision: "Highway resistance set to 200, not 1000"
|
|
248
|
+
rationale: "Culvert crossings documented; Quigley & Crawshaw (1992)"
|
|
249
|
+
outputs: ["outputs/resistance/resistance_combined.tif"]
|
|
250
|
+
|
|
251
|
+
- date: 2025-01-21
|
|
252
|
+
skill_id: landscape-connectivity
|
|
253
|
+
decision: "Dispersal distance set to 50 km for main analysis"
|
|
254
|
+
rationale: "Conservative mid-range; sensitivity shows IIC robust ±20% across 20-80km"
|
|
255
|
+
outputs: ["outputs/connectivity/dmax_50000/landscape_summary.csv"]
|
|
256
|
+
|
|
257
|
+
- date: 2025-01-22
|
|
258
|
+
skill_id: landscape-connectivity
|
|
259
|
+
decision: "Patch P089 flagged as critical stepping stone"
|
|
260
|
+
rationale: "High BC (0.81) despite small area; bridges components 3 and 4"
|
|
261
|
+
outputs: ["outputs/connectivity/dmax_50000/patch_metrics.csv"]
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## References
|
|
267
|
+
|
|
268
|
+
- Rabinowitz, A. & Zeller, K.A. (2010). A range-wide model of landscape connectivity and conservation for the jaguar. *Biological Conservation*, 143(4), 939–945. DOI: 10.1016/j.biocon.2010.01.002
|
|
269
|
+
- Pascual-Hortal, L. & Saura, S. (2006). Comparison and development of new graph-based landscape connectivity indices. *Landscape Ecology*, 21(7), 959–967. DOI: 10.1007/s10980-006-0013-z
|
|
270
|
+
- McRae, B.H. et al. (2008). Using circuit theory to model connectivity in ecology. *Ecology*, 89(10), 2712–2724. DOI: 10.1890/07-1861.1
|
|
271
|
+
- Zeller, K.A. et al. (2012). Estimating landscape resistance to movement. *Landscape Ecology*, 27(6), 777–797. DOI: 10.1007/s10980-012-9737-0
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
resource_id: circuitscape-parameter-guide
|
|
3
|
+
skill_id: landscape-connectivity
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Circuitscape Parameter Guide
|
|
7
|
+
|
|
8
|
+
## What Circuitscape Models
|
|
9
|
+
|
|
10
|
+
Circuitscape applies circuit theory to landscape connectivity. Each raster cell is a resistor; current flows from source to ground nodes. **High current = high movement probability.** Unlike least-cost paths (single path), Circuitscape identifies all possible movement paths simultaneously, making it robust to barrier uncertainty.
|
|
11
|
+
|
|
12
|
+
**When to use Circuitscape:**
|
|
13
|
+
- Species with exploratory or random-walk dispersal (amphibians, many invertebrates)
|
|
14
|
+
- Gene flow modelling (isolation by resistance)
|
|
15
|
+
- Identifying multiple corridors and bottlenecks simultaneously
|
|
16
|
+
|
|
17
|
+
**When least-cost path may be preferred:**
|
|
18
|
+
- Species with directed, optimal-path movement (large carnivores following trails)
|
|
19
|
+
- Fine-resolution analysis where single corridors are sufficient
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Key Parameters
|
|
24
|
+
|
|
25
|
+
| Parameter | Options | Recommended default | Effect |
|
|
26
|
+
|-----------|---------|---------------------|--------|
|
|
27
|
+
| `scenario` | `pairwise`, `one-to-all`, `all-to-one` | `pairwise` | Analysis mode |
|
|
28
|
+
| `data_type` | `raster`, `network` | `raster` | Input format |
|
|
29
|
+
| `resistance_file` | path to .asc/.tif | — | Resistance surface |
|
|
30
|
+
| `point_file` | path to focal nodes .shp | — | Source/destination points |
|
|
31
|
+
| `write_cum_cur_map_only` | True/False | True (pairwise sums) | Output cumulative vs all pairwise maps |
|
|
32
|
+
| `log_transform_maps` | True/False | True | Log-scale current maps easier to visualise |
|
|
33
|
+
| `compress_grids` | True/False | True | Reduce output file size |
|
|
34
|
+
| `solver` | `cg+amg`, `cholmod` | `cg+amg` | Large rasters; cholmod for small/medium |
|
|
35
|
+
| `max_parallel` | int | n_cores - 1 | Parallelisation |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Running Circuitscape from R (via System Call)
|
|
40
|
+
|
|
41
|
+
```r
|
|
42
|
+
# Usage: source("run_circuitscape.R")
|
|
43
|
+
suppressPackageStartupMessages(library(terra))
|
|
44
|
+
|
|
45
|
+
run_circuitscape <- function(resistance_tif, focal_points_shp, output_dir,
|
|
46
|
+
scenario = "pairwise", solver = "cg+amg") {
|
|
47
|
+
dir.create(output_dir, recursive = TRUE, showWarnings = FALSE)
|
|
48
|
+
|
|
49
|
+
# Export resistance as .asc (Circuitscape requires ASCII grid or GeoTIFF)
|
|
50
|
+
res <- rast(resistance_tif)
|
|
51
|
+
asc_path <- file.path(output_dir, "resistance.asc")
|
|
52
|
+
writeRaster(res, asc_path, filetype = "AAIGrid", overwrite = TRUE)
|
|
53
|
+
|
|
54
|
+
# Write Circuitscape INI configuration
|
|
55
|
+
ini_path <- file.path(output_dir, "cs_config.ini")
|
|
56
|
+
ini_content <- sprintf(
|
|
57
|
+
"[circuitscape options]
|
|
58
|
+
scenario = %s
|
|
59
|
+
data_type = raster
|
|
60
|
+
resistance_file = %s
|
|
61
|
+
point_file = %s
|
|
62
|
+
output_file = %s
|
|
63
|
+
write_cum_cur_map_only = True
|
|
64
|
+
log_transform_maps = True
|
|
65
|
+
compress_grids = True
|
|
66
|
+
solver = %s
|
|
67
|
+
max_parallel = %d
|
|
68
|
+
",
|
|
69
|
+
scenario,
|
|
70
|
+
normalizePath(asc_path),
|
|
71
|
+
normalizePath(focal_points_shp),
|
|
72
|
+
normalizePath(file.path(output_dir, "cs_output")),
|
|
73
|
+
solver,
|
|
74
|
+
max(1L, parallel::detectCores() - 1L)
|
|
75
|
+
)
|
|
76
|
+
writeLines(ini_content, ini_path)
|
|
77
|
+
|
|
78
|
+
# Call Circuitscape (must be installed and on PATH)
|
|
79
|
+
cmd <- sprintf("cs_run.py %s", shQuote(ini_path))
|
|
80
|
+
ret <- system(cmd)
|
|
81
|
+
if (ret != 0) warning("Circuitscape returned non-zero exit code: ", ret)
|
|
82
|
+
return(file.path(output_dir, "cs_output_cum_curmap.asc"))
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Interpreting Circuitscape Output Maps
|
|
89
|
+
|
|
90
|
+
| Output file | What it shows |
|
|
91
|
+
|-------------|--------------|
|
|
92
|
+
| `*_cum_curmap.asc` | Summed current across all pairwise flows — identifies corridors |
|
|
93
|
+
| `*_resistances.out` | Effective resistance between each pair of nodes |
|
|
94
|
+
| `*_curmap_X_Y.asc` | Current map for specific node pair X→Y |
|
|
95
|
+
|
|
96
|
+
### Post-processing current map in R
|
|
97
|
+
|
|
98
|
+
```r
|
|
99
|
+
suppressPackageStartupMessages(library(terra))
|
|
100
|
+
|
|
101
|
+
cur <- rast("outputs/circuitscape/cs_output_cum_curmap.asc")
|
|
102
|
+
|
|
103
|
+
# Log-scale for visualisation
|
|
104
|
+
cur_log <- log1p(cur)
|
|
105
|
+
|
|
106
|
+
# Identify pinch points: cells with high current in narrow flow paths
|
|
107
|
+
# Threshold: top 5% of current values
|
|
108
|
+
q95 <- quantile(values(cur_log), 0.95, na.rm = TRUE)
|
|
109
|
+
pinchpoints <- cur_log >= q95
|
|
110
|
+
writeRaster(pinchpoints, "outputs/circuitscape/pinchpoints.tif", overwrite = TRUE)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Choosing Focal Nodes
|
|
116
|
+
|
|
117
|
+
| Scenario | Recommended focal nodes |
|
|
118
|
+
|----------|------------------------|
|
|
119
|
+
| Cross-landscape connectivity | Large core habitat patches (> 100 ha) |
|
|
120
|
+
| Corridor between two areas | Source and destination patches only |
|
|
121
|
+
| Full landscape assessment | All patches > minimum size threshold |
|
|
122
|
+
| Genetic sampling sites | Population sampling locations |
|
|
123
|
+
|
|
124
|
+
**Rule:** Keep focal node count ≤ 50 for pairwise scenario on standard hardware. More nodes → O(n²) compute time.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Computational Considerations
|
|
129
|
+
|
|
130
|
+
| Raster resolution | Focal nodes | Typical runtime | Solver recommendation |
|
|
131
|
+
|------------------|-------------|----------------|----------------------|
|
|
132
|
+
| 30 m, 10×10 km extent | 20 | 2–5 min | cg+amg |
|
|
133
|
+
| 30 m, 100×100 km extent | 50 | 30–90 min | cg+amg |
|
|
134
|
+
| 10 m, 50×50 km extent | 30 | 2–8 h | cholmod or HPC |
|
|
135
|
+
| 1 m, any extent | — | Not feasible | Resample to ≥ 10 m |
|
|
136
|
+
|
|
137
|
+
**Tip:** Resample resistance raster to the coarsest resolution that still captures key barriers (e.g., roads, rivers). Test with 100 m resolution first; refine if necessary.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Pitfalls
|
|
142
|
+
|
|
143
|
+
- **Current maps conflate corridors with high-permeability areas:** High current can result from many paths OR from a single wide, low-resistance path. Always check raster context (road maps, imagery) around high-current cells.
|
|
144
|
+
- **Focal nodes inside high-resistance cells:** Circuitscape places current sources at node locations. If a node is on a road (high resistance), effective resistance will be artificially inflated. Snap nodes to nearest low-resistance cell.
|
|
145
|
+
- **Ignoring NoData handling:** NoData cells are treated as barriers. Ensure NoData correctly represents barriers (not missing data). Fill missing cells with average neighbourhood resistance before analysis.
|
|
146
|
+
- **Comparing Circuitscape between landscapes without standardisation:** Cumulative current scales with number of focal nodes and landscape size. Only compare effective resistance values, not raw current maps, across landscapes.
|
|
147
|
+
- **Using Circuitscape for directed movement:** Circuitscape is symmetric. For strongly directional dispersal (stream-mediated, prevailing winds), use directional least-cost models instead.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## References
|
|
152
|
+
|
|
153
|
+
- McRae, B.H., Dickson, B.G., Keitt, T.H. & Shah, V.B. (2008). Using circuit theory to model connectivity in ecology, evolution, and conservation. *Ecology*, 89(10), 2712–2724. DOI: 10.1890/07-1861.1
|
|
154
|
+
- Shah, V.B. & McRae, B.H. (2008). Circuitscape: a tool for landscape ecology. *Proceedings of the 7th Python in Science Conference*, 62–65.
|
|
155
|
+
- Dickson, B.G. et al. (2019). Informing strategic efforts to expand and connect protected areas using a model of ecological flow, with application to the western United States. *Conservation Letters*, 12(3), e12647. DOI: 10.1111/conl.12647
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
resource_id: graph-theory-for-ecology
|
|
3
|
+
skill_id: landscape-connectivity
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Graph Theory for Landscape Ecology
|
|
7
|
+
|
|
8
|
+
## Core Connectivity Metrics
|
|
9
|
+
|
|
10
|
+
| Metric | Formula | Scale | Interpretation | Requires |
|
|
11
|
+
|--------|---------|-------|----------------|---------|
|
|
12
|
+
| **IIC** (Integral Index of Connectivity) | (1/A²) Σ (aᵢ × aⱼ) / (1 + nᵢⱼ) | 0–1 | Landscape-level binary connectivity | Dispersal threshold |
|
|
13
|
+
| **PC** (Probability of Connectivity) | (1/A²) Σ pᵢⱼ* × aᵢ × aⱼ | 0–1 | Landscape-level probabilistic connectivity | Dispersal function |
|
|
14
|
+
| **dIIC** (patch contribution to IIC) | [(IIC − IICremove) / IIC] × 100 | % | Importance of patch i to overall IIC | — |
|
|
15
|
+
| **dPC** (patch contribution to PC) | [(PC − PCremove) / PC] × 100 | % | Importance of patch i to overall PC | — |
|
|
16
|
+
| **BC** (Betweenness Centrality) | fraction of shortest paths through node i | 0–1 | Stepping stone / corridor value | — |
|
|
17
|
+
| **EC** (Eigenvalue Centrality) | dominant eigenvector component | 0–∞ | Well-connected patches in dense cluster | — |
|
|
18
|
+
|
|
19
|
+
**Landscape area A:** total study area (same units as patch areas).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## When to Use IIC vs PC
|
|
24
|
+
|
|
25
|
+
| Condition | Recommended metric | Reason |
|
|
26
|
+
|-----------|--------------------|--------|
|
|
27
|
+
| Dispersal threshold unknown | IIC | Binary; only requires yes/no connection |
|
|
28
|
+
| Dispersal probability decay known | PC | Incorporates full movement function |
|
|
29
|
+
| Comparing two landscapes | dIIC, dPC | Relative patch importance is comparable |
|
|
30
|
+
| Identifying stepping stones | BC | Patches with high BC are corridor nodes |
|
|
31
|
+
| Data on gene flow or mark-recapture | PC | Can calibrate pᵢⱼ* with empirical data |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Computing IIC and dPC in R (igraph)
|
|
36
|
+
|
|
37
|
+
```r
|
|
38
|
+
# Usage: source("connectivity_metrics.R")
|
|
39
|
+
suppressPackageStartupMessages(library(igraph))
|
|
40
|
+
suppressPackageStartupMessages(library(sf))
|
|
41
|
+
|
|
42
|
+
# Patches: sf polygon layer with attribute 'area_ha'
|
|
43
|
+
# Dispersal threshold: dmax in map units (e.g., metres)
|
|
44
|
+
|
|
45
|
+
compute_iic <- function(patches, dmax) {
|
|
46
|
+
n <- nrow(patches)
|
|
47
|
+
A <- sum(patches$area_ha)
|
|
48
|
+
coords <- st_centroid(patches) %>% st_coordinates()
|
|
49
|
+
dist_mat <- as.matrix(dist(coords))
|
|
50
|
+
|
|
51
|
+
# Binary adjacency: connected if distance < dmax
|
|
52
|
+
adj <- (dist_mat < dmax) * 1
|
|
53
|
+
diag(adj) <- 0
|
|
54
|
+
g <- graph_from_adjacency_matrix(adj, mode = "undirected")
|
|
55
|
+
|
|
56
|
+
# Shortest paths (hop count)
|
|
57
|
+
sp <- distances(g, algorithm = "bfs")
|
|
58
|
+
|
|
59
|
+
IIC_num <- 0
|
|
60
|
+
for (i in seq_len(n)) {
|
|
61
|
+
for (j in seq_len(n)) {
|
|
62
|
+
nij <- sp[i, j]
|
|
63
|
+
if (is.finite(nij)) {
|
|
64
|
+
IIC_num <- IIC_num +
|
|
65
|
+
(patches$area_ha[i] * patches$area_ha[j]) / (1 + nij)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
IIC <- IIC_num / A^2
|
|
70
|
+
return(IIC)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# Patch importance: dIIC
|
|
74
|
+
compute_diic <- function(patches, dmax) {
|
|
75
|
+
IIC_full <- compute_iic(patches, dmax)
|
|
76
|
+
diic_vec <- numeric(nrow(patches))
|
|
77
|
+
for (i in seq_len(nrow(patches))) {
|
|
78
|
+
IIC_i <- compute_iic(patches[-i, ], dmax)
|
|
79
|
+
diic_vec[i] <- (IIC_full - IIC_i) / IIC_full * 100
|
|
80
|
+
}
|
|
81
|
+
patches$dIIC <- diic_vec
|
|
82
|
+
return(patches)
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Interpreting dPC Values
|
|
89
|
+
|
|
90
|
+
| dPC (%) | Patch importance | Recommended action |
|
|
91
|
+
|---------|-----------------|-------------------|
|
|
92
|
+
| > 10 | Critical | Highest protection priority; any loss severely disrupts connectivity |
|
|
93
|
+
| 5–10 | High | Priority for protection or restoration buffer |
|
|
94
|
+
| 1–5 | Moderate | Monitor; stepping-stone function likely |
|
|
95
|
+
| < 1 | Low | May contribute if adjacent patches are lost |
|
|
96
|
+
| 0 | Isolated | Not connected within dispersal distance; restoration needed first |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Dispersal Distance Sensitivity Analysis
|
|
101
|
+
|
|
102
|
+
When the species dispersal distance is uncertain, run connectivity across a range:
|
|
103
|
+
|
|
104
|
+
```r
|
|
105
|
+
dmax_values <- c(500, 1000, 2000, 5000) # metres
|
|
106
|
+
results <- lapply(dmax_values, function(d) {
|
|
107
|
+
iic <- compute_iic(patches, dmax = d)
|
|
108
|
+
data.frame(dmax = d, IIC = iic)
|
|
109
|
+
})
|
|
110
|
+
sens_df <- dplyr::bind_rows(results)
|
|
111
|
+
plot(sens_df$dmax, sens_df$IIC, type = "b",
|
|
112
|
+
xlab = "Dispersal distance (m)", ylab = "IIC",
|
|
113
|
+
main = "Connectivity sensitivity to dispersal distance")
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Rule:** If IIC changes < 10% across the plausible dmax range → results are robust to dispersal distance uncertainty.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Pitfalls
|
|
121
|
+
|
|
122
|
+
- **Euclidean vs cost distance:** Graph edges based on straight-line distance ignore barriers (roads, rivers). Use cost distance for species with limited matrix permeability.
|
|
123
|
+
- **Patch definition:** Patches defined at too coarse a resolution inflate IIC by merging sub-patches that are not functionally connected.
|
|
124
|
+
- **Island patches:** Isolated patches (not connected to any other patch) contribute only their intra-patch value to IIC/PC. Report isolation separately.
|
|
125
|
+
- **Directed vs undirected graphs:** Most landscape connectivity models assume undirected movement. For rivers or wind-pollinated species, use directed graphs.
|
|
126
|
+
- **Comparing across study areas:** IIC and PC scale with A². Always normalise by landscape area when comparing sites.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## References
|
|
131
|
+
|
|
132
|
+
- Pascual-Hortal, L. & Saura, S. (2006). Comparison and development of new graph-based landscape connectivity indices. *Landscape Ecology*, 21(7), 959–967. DOI: 10.1007/s10980-006-0013-z
|
|
133
|
+
- Saura, S. & Torné, J. (2009). Conefor Sensinode 2.2: A software package for quantifying the importance of habitat patches for landscape connectivity. *Environmental Modelling & Software*, 24(1), 135–139. DOI: 10.1016/j.envsoft.2008.05.005
|
|
134
|
+
- Urban, D. & Keitt, T. (2001). Landscape connectivity: a graph-theoretic perspective. *Ecology*, 82(5), 1205–1218. DOI: 10.1890/0012-9658(2001)082[1205:LCAGTP]2.0.CO;2
|