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,274 @@
|
|
|
1
|
+
# ecological-agent-skills / Copyright (C) 2026 Francisco Diego Barros Barata
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
# Usage: Rscript power_analysis_baci.R <output_dir> [effect_size] [n_sites] [n_surveys] [alpha] [variance_estimate]
|
|
5
|
+
# Compute statistical power for BACI designs and recommend minimum sample sizes.
|
|
6
|
+
# Outputs: power_curves.png, power_summary.csv, minimum_n_recommendation.md
|
|
7
|
+
|
|
8
|
+
# ── Inline logger ─────────────────────────────────────────────────────────────
|
|
9
|
+
SKILL_NAME <- "ecological-impact-assessment"
|
|
10
|
+
.log_ts <- function() format(Sys.time(), "[%Y-%m-%d %H:%M:%S]")
|
|
11
|
+
log_info <- function(...) message(.log_ts(), " [INFO] ", sprintf(...))
|
|
12
|
+
log_warn <- function(...) message(.log_ts(), " [WARN] ", sprintf(...))
|
|
13
|
+
log_error<- function(...) message(.log_ts(), " [ERROR] ", sprintf(...))
|
|
14
|
+
log_step <- function(n, d) log_info("-- STEP %d: %s", n, d)
|
|
15
|
+
log_decision <- function(v, val, why) log_info("DECISION | %s = %s | %s", v, val, why)
|
|
16
|
+
dir.create("logs", recursive=TRUE, showWarnings=FALSE)
|
|
17
|
+
|
|
18
|
+
suppressPackageStartupMessages({
|
|
19
|
+
library(ggplot2)
|
|
20
|
+
library(pwr)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
# ── Arguments ─────────────────────────────────────────────────────────────────
|
|
24
|
+
args <- commandArgs(trailingOnly = TRUE)
|
|
25
|
+
output_dir <- if (length(args) >= 1) args[1] else "outputs/power_analysis"
|
|
26
|
+
effect_size <- if (length(args) >= 2) as.numeric(args[2]) else 0.5
|
|
27
|
+
n_sites <- if (length(args) >= 3) as.integer(args[3]) else 10
|
|
28
|
+
n_surveys <- if (length(args) >= 4) as.integer(args[4]) else 4
|
|
29
|
+
alpha <- if (length(args) >= 5) as.numeric(args[5]) else 0.05
|
|
30
|
+
variance_estimate <- if (length(args) >= 6) as.numeric(args[6]) else 1.0
|
|
31
|
+
|
|
32
|
+
log_decision("effect_size", effect_size,
|
|
33
|
+
"Cohen's d: 0.2=small, 0.5=medium, 0.8=large. Use 0.5 if no pilot data available.")
|
|
34
|
+
log_decision("n_sites", n_sites,
|
|
35
|
+
"Number of control + impact sites each side. Minimum recommended: 5 per group.")
|
|
36
|
+
log_decision("n_surveys", n_surveys,
|
|
37
|
+
"Survey occasions before + after. Minimum recommended: 3 pre + 3 post = 6 total.")
|
|
38
|
+
log_decision("alpha", alpha,
|
|
39
|
+
"Type I error rate. Standard: 0.05. Use 0.10 for preliminary screening.")
|
|
40
|
+
log_decision("variance_estimate", variance_estimate,
|
|
41
|
+
"Within-group variance from pilot data or literature. Affects Cohen's d calculation.")
|
|
42
|
+
|
|
43
|
+
dir.create(output_dir, recursive = TRUE, showWarnings = FALSE)
|
|
44
|
+
|
|
45
|
+
# ── Helper: BACI power ────────────────────────────────────────────────────────
|
|
46
|
+
# BACI interaction term is tested as a two-sample t-test on the difference-in-differences.
|
|
47
|
+
# Effective n per group = n_sites * n_surveys (repeated measures increase precision).
|
|
48
|
+
# Cohen's d adjusted for variance: d = effect_size / sqrt(variance_estimate)
|
|
49
|
+
|
|
50
|
+
baci_power <- function(n_s, n_sv, eff, var_est, a) {
|
|
51
|
+
d_adj <- eff / sqrt(var_est)
|
|
52
|
+
n_eff <- n_s * n_sv # effective replication per group (control or impact)
|
|
53
|
+
result <- tryCatch(
|
|
54
|
+
pwr.t.test(n = n_eff, d = d_adj, sig.level = a, type = "two.sample",
|
|
55
|
+
alternative = "two.sided"),
|
|
56
|
+
error = function(e) NULL
|
|
57
|
+
)
|
|
58
|
+
if (is.null(result)) return(NA_real_)
|
|
59
|
+
result$power
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# ── Step 1: Curves — power × n_sites (n_surveys fixed) ───────────────────────
|
|
63
|
+
log_step(1, "Computing power × n_sites curve")
|
|
64
|
+
sites_range <- 2:30
|
|
65
|
+
pow_vs_sites <- data.frame(
|
|
66
|
+
n_sites = sites_range,
|
|
67
|
+
power = sapply(sites_range, baci_power,
|
|
68
|
+
n_sv = n_surveys, eff = effect_size,
|
|
69
|
+
var_est = variance_estimate, a = alpha)
|
|
70
|
+
)
|
|
71
|
+
log_info("Power at n_sites=%d (n_surveys=%d fixed): %.3f",
|
|
72
|
+
n_sites, n_surveys, baci_power(n_sites, n_surveys, effect_size, variance_estimate, alpha))
|
|
73
|
+
|
|
74
|
+
# ── Step 2: Curves — power × n_surveys (n_sites fixed) ───────────────────────
|
|
75
|
+
log_step(2, "Computing power × n_surveys curve")
|
|
76
|
+
surveys_range <- 1:20
|
|
77
|
+
pow_vs_surveys <- data.frame(
|
|
78
|
+
n_surveys = surveys_range,
|
|
79
|
+
power = sapply(surveys_range, function(sv)
|
|
80
|
+
baci_power(n_sites, sv, effect_size, variance_estimate, alpha))
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# ── Step 3: Curves — power × effect_size ─────────────────────────────────────
|
|
84
|
+
log_step(3, "Computing power × effect_size curve")
|
|
85
|
+
eff_range <- seq(0.1, 1.5, by = 0.05)
|
|
86
|
+
pow_vs_eff <- data.frame(
|
|
87
|
+
effect_size = eff_range,
|
|
88
|
+
power = sapply(eff_range, baci_power,
|
|
89
|
+
n_s = n_sites, n_sv = n_surveys,
|
|
90
|
+
var_est = variance_estimate, a = alpha)
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# ── Step 4: Minimum n calculations ────────────────────────────────────────────
|
|
94
|
+
log_step(4, "Calculating minimum n for power = 0.80 and 0.90")
|
|
95
|
+
|
|
96
|
+
find_min_n_sites <- function(target_power, n_sv, eff, var_est, a) {
|
|
97
|
+
for (ns in 2:200) {
|
|
98
|
+
if (!is.na(baci_power(ns, n_sv, eff, var_est, a)) &&
|
|
99
|
+
baci_power(ns, n_sv, eff, var_est, a) >= target_power) return(ns)
|
|
100
|
+
}
|
|
101
|
+
return(NA_integer_)
|
|
102
|
+
}
|
|
103
|
+
find_min_n_surveys <- function(target_power, ns, eff, var_est, a) {
|
|
104
|
+
for (nv in 1:100) {
|
|
105
|
+
if (!is.na(baci_power(ns, nv, eff, var_est, a)) &&
|
|
106
|
+
baci_power(ns, nv, eff, var_est, a) >= target_power) return(nv)
|
|
107
|
+
}
|
|
108
|
+
return(NA_integer_)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
min_sites_80 <- find_min_n_sites(0.80, n_surveys, effect_size, variance_estimate, alpha)
|
|
112
|
+
min_sites_90 <- find_min_n_sites(0.90, n_surveys, effect_size, variance_estimate, alpha)
|
|
113
|
+
min_surveys_80<- find_min_n_surveys(0.80, n_sites, effect_size, variance_estimate, alpha)
|
|
114
|
+
min_surveys_90<- find_min_n_surveys(0.90, n_sites, effect_size, variance_estimate, alpha)
|
|
115
|
+
|
|
116
|
+
log_info("Min sites for power=0.80: %d | power=0.90: %d (surveys=%d fixed)",
|
|
117
|
+
min_sites_80, min_sites_90, n_surveys)
|
|
118
|
+
log_info("Min surveys for power=0.80: %d | power=0.90: %d (sites=%d fixed)",
|
|
119
|
+
min_surveys_80, min_surveys_90, n_sites)
|
|
120
|
+
|
|
121
|
+
if (is.na(min_sites_80)) {
|
|
122
|
+
log_warn("Power 0.80 not achievable with sites<=200. Increase effect_size or reduce variance_estimate.")
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# ── Step 5: Power curves plot ─────────────────────────────────────────────────
|
|
126
|
+
log_step(5, "Generating power curves plot")
|
|
127
|
+
tryCatch({
|
|
128
|
+
p1 <- ggplot(pow_vs_sites, aes(n_sites, power)) +
|
|
129
|
+
geom_line(colour = "#2471a3", linewidth = 1) +
|
|
130
|
+
geom_hline(yintercept = c(0.80, 0.90), linetype = "dashed",
|
|
131
|
+
colour = c("#e74c3c","#27ae60")) +
|
|
132
|
+
geom_vline(xintercept = c(min_sites_80, min_sites_90), linetype = "dotted",
|
|
133
|
+
colour = c("#e74c3c","#27ae60")) +
|
|
134
|
+
annotate("text", x = min_sites_80 + 0.5, y = 0.05,
|
|
135
|
+
label = paste0("n=", min_sites_80, "\n(80%)"), hjust = 0, size = 3, colour = "#e74c3c") +
|
|
136
|
+
annotate("text", x = min_sites_90 + 0.5, y = 0.05,
|
|
137
|
+
label = paste0("n=", min_sites_90, "\n(90%)"), hjust = 0, size = 3, colour = "#27ae60") +
|
|
138
|
+
scale_y_continuous(limits = c(0, 1), labels = scales::percent) +
|
|
139
|
+
labs(title = paste0("BACI Power vs. Sites (n_surveys=", n_surveys, " fixed)"),
|
|
140
|
+
x = "Number of sites per group", y = "Statistical Power") +
|
|
141
|
+
theme_bw()
|
|
142
|
+
|
|
143
|
+
p2 <- ggplot(pow_vs_surveys, aes(n_surveys, power)) +
|
|
144
|
+
geom_line(colour = "#8e44ad", linewidth = 1) +
|
|
145
|
+
geom_hline(yintercept = c(0.80, 0.90), linetype = "dashed",
|
|
146
|
+
colour = c("#e74c3c","#27ae60")) +
|
|
147
|
+
scale_y_continuous(limits = c(0, 1), labels = scales::percent) +
|
|
148
|
+
labs(title = paste0("BACI Power vs. Surveys (n_sites=", n_sites, " fixed)"),
|
|
149
|
+
x = "Survey occasions (before + after)", y = "Statistical Power") +
|
|
150
|
+
theme_bw()
|
|
151
|
+
|
|
152
|
+
p3 <- ggplot(pow_vs_eff, aes(effect_size, power)) +
|
|
153
|
+
geom_line(colour = "#e67e22", linewidth = 1) +
|
|
154
|
+
geom_hline(yintercept = c(0.80, 0.90), linetype = "dashed",
|
|
155
|
+
colour = c("#e74c3c","#27ae60")) +
|
|
156
|
+
geom_vline(xintercept = effect_size, linetype = "dotted", colour = "grey40") +
|
|
157
|
+
scale_y_continuous(limits = c(0, 1), labels = scales::percent) +
|
|
158
|
+
labs(title = paste0("BACI Power vs. Effect Size (n=", n_sites, " sites, ",
|
|
159
|
+
n_surveys, " surveys)"),
|
|
160
|
+
x = "Effect size (Cohen's d)", y = "Statistical Power") +
|
|
161
|
+
theme_bw()
|
|
162
|
+
|
|
163
|
+
suppressPackageStartupMessages(library(patchwork))
|
|
164
|
+
combined <- p1 / p2 / p3
|
|
165
|
+
plot_file <- file.path(output_dir, "power_curves.png")
|
|
166
|
+
ggsave(plot_file, combined, width = 8, height = 12, dpi = 150)
|
|
167
|
+
log_info("Power curves plot saved: %s", plot_file)
|
|
168
|
+
}, error = function(e) {
|
|
169
|
+
log_warn("Plot generation failed: %s. Trying base graphics fallback.", conditionMessage(e))
|
|
170
|
+
tryCatch({
|
|
171
|
+
png(file.path(output_dir, "power_curves.png"), width = 800, height = 900)
|
|
172
|
+
par(mfrow = c(3, 1), mar = c(4, 4, 3, 1))
|
|
173
|
+
plot(pow_vs_sites$n_sites, pow_vs_sites$power, type = "l", col = "#2471a3", lwd = 2,
|
|
174
|
+
ylim = c(0,1), xlab = "Sites per group", ylab = "Power",
|
|
175
|
+
main = paste0("BACI Power vs Sites (surveys=", n_surveys, ")"))
|
|
176
|
+
abline(h = c(0.8, 0.9), lty = 2, col = c("red","darkgreen"))
|
|
177
|
+
plot(pow_vs_surveys$n_surveys, pow_vs_surveys$power, type = "l", col = "#8e44ad", lwd = 2,
|
|
178
|
+
ylim = c(0,1), xlab = "Survey occasions", ylab = "Power",
|
|
179
|
+
main = paste0("BACI Power vs Surveys (sites=", n_sites, ")"))
|
|
180
|
+
abline(h = c(0.8, 0.9), lty = 2, col = c("red","darkgreen"))
|
|
181
|
+
plot(pow_vs_eff$effect_size, pow_vs_eff$power, type = "l", col = "#e67e22", lwd = 2,
|
|
182
|
+
ylim = c(0,1), xlab = "Effect size (Cohen's d)", ylab = "Power",
|
|
183
|
+
main = "BACI Power vs Effect Size")
|
|
184
|
+
abline(h = c(0.8, 0.9), lty = 2, col = c("red","darkgreen"))
|
|
185
|
+
dev.off()
|
|
186
|
+
log_info("Base-graphics power curves saved.")
|
|
187
|
+
}, error = function(e2) {
|
|
188
|
+
log_error("Falha ao gerar grafico de poder: %s\nCausa provavel: pwr ou ggplot2 nao instalados.\nVerifique: install.packages(c('pwr','ggplot2','patchwork'))", conditionMessage(e2))
|
|
189
|
+
})
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
# ── Step 6: Power summary CSV ──────────────────────────────────────────────────
|
|
193
|
+
log_step(6, "Saving power summary CSV")
|
|
194
|
+
power_current <- baci_power(n_sites, n_surveys, effect_size, variance_estimate, alpha)
|
|
195
|
+
|
|
196
|
+
summary_df <- data.frame(
|
|
197
|
+
parameter = c("effect_size","n_sites","n_surveys","alpha","variance_estimate",
|
|
198
|
+
"power_current","min_sites_power80","min_sites_power90",
|
|
199
|
+
"min_surveys_power80","min_surveys_power90"),
|
|
200
|
+
value = c(effect_size, n_sites, n_surveys, alpha, variance_estimate,
|
|
201
|
+
round(power_current, 4),
|
|
202
|
+
min_sites_80, min_sites_90,
|
|
203
|
+
min_surveys_80, min_surveys_90),
|
|
204
|
+
stringsAsFactors = FALSE
|
|
205
|
+
)
|
|
206
|
+
csv_file <- file.path(output_dir, "power_summary.csv")
|
|
207
|
+
write.csv(summary_df, csv_file, row.names = FALSE)
|
|
208
|
+
log_info("Power summary saved: %s", csv_file)
|
|
209
|
+
|
|
210
|
+
# ── Step 7: Recommendation markdown ───────────────────────────────────────────
|
|
211
|
+
log_step(7, "Writing minimum-n recommendation report")
|
|
212
|
+
adequacy <- if (!is.na(power_current) && power_current >= 0.80) "ADEQUATE" else "INSUFFICIENT"
|
|
213
|
+
rec_lines <- c(
|
|
214
|
+
"# BACI Power Analysis — Field Protocol Recommendation",
|
|
215
|
+
"",
|
|
216
|
+
paste0("Generated: ", Sys.time()),
|
|
217
|
+
"",
|
|
218
|
+
"## Input Parameters",
|
|
219
|
+
paste0("- **Effect size (Cohen's d):** ", effect_size),
|
|
220
|
+
paste0("- **Number of sites (per group):** ", n_sites),
|
|
221
|
+
paste0("- **Survey occasions (before + after):** ", n_surveys),
|
|
222
|
+
paste0("- **Significance level (α):** ", alpha),
|
|
223
|
+
paste0("- **Variance estimate:** ", variance_estimate),
|
|
224
|
+
"",
|
|
225
|
+
"## Current Design Power",
|
|
226
|
+
paste0("**Statistical power = ", round(power_current * 100, 1), "%** (", adequacy, ")"),
|
|
227
|
+
"",
|
|
228
|
+
ifelse(adequacy == "INADEQUATE",
|
|
229
|
+
"> ⚠️ **WARNING:** The current design has insufficient power to detect the target effect.",
|
|
230
|
+
"> ✅ The current design has adequate power to detect the target effect."),
|
|
231
|
+
"",
|
|
232
|
+
"## Minimum Sample Size Recommendations",
|
|
233
|
+
"",
|
|
234
|
+
paste0("### To achieve power = 80% (α = ", alpha, ")"),
|
|
235
|
+
paste0("- **Sites per group:** ≥ ",
|
|
236
|
+
ifelse(is.na(min_sites_80), "not achievable with ≤200 sites", min_sites_80),
|
|
237
|
+
" (with ", n_surveys, " survey occasions)"),
|
|
238
|
+
paste0("- **Survey occasions:** ≥ ",
|
|
239
|
+
ifelse(is.na(min_surveys_80), "not achievable", min_surveys_80),
|
|
240
|
+
" (with ", n_sites, " sites)"),
|
|
241
|
+
"",
|
|
242
|
+
paste0("### To achieve power = 90% (α = ", alpha, ")"),
|
|
243
|
+
paste0("- **Sites per group:** ≥ ",
|
|
244
|
+
ifelse(is.na(min_sites_90), "not achievable with ≤200 sites", min_sites_90),
|
|
245
|
+
" (with ", n_surveys, " survey occasions)"),
|
|
246
|
+
paste0("- **Survey occasions:** ≥ ",
|
|
247
|
+
ifelse(is.na(min_surveys_90), "not achievable", min_surveys_90),
|
|
248
|
+
" (with ", n_sites, " sites)"),
|
|
249
|
+
"",
|
|
250
|
+
"## Interpretation",
|
|
251
|
+
paste0("- A Cohen's d of **", effect_size, "** corresponds to detecting a ",
|
|
252
|
+
round(effect_size * sqrt(variance_estimate), 3),
|
|
253
|
+
" unit difference between impact and control sites, adjusting for σ² = ", variance_estimate, "."),
|
|
254
|
+
"- **Rule of thumb:** BACI studies should have ≥5 control and ≥5 impact sites,",
|
|
255
|
+
" with ≥3 survey occasions before and ≥3 after the impact.",
|
|
256
|
+
"- If power is insufficient, prioritise adding **sites** (stronger than adding surveys)",
|
|
257
|
+
" because spatial replication reduces pseudo-replication bias.",
|
|
258
|
+
"",
|
|
259
|
+
"## How to Obtain Variance Estimate",
|
|
260
|
+
"1. **From pilot data:** compute SD of the response variable across sites, then var = SD².",
|
|
261
|
+
"2. **From literature:** use SD values reported for the same metric and habitat type.",
|
|
262
|
+
"3. **Conservative default:** use variance_estimate = 1.0 (corresponds to Cohen's d units).",
|
|
263
|
+
"",
|
|
264
|
+
"## References",
|
|
265
|
+
"- Cohen, J. (1988). *Statistical Power Analysis for the Behavioral Sciences* (2nd ed.).",
|
|
266
|
+
"- Underwood, A.J. (1994). On beyond BACI. *Ecological Applications*, 4(1), 3–15.",
|
|
267
|
+
"- Stewart-Oaten, A. & Bence, J.R. (2001). Temporal and spatial variation in",
|
|
268
|
+
" environmental impact assessment. *Ecological Monographs*, 71(2), 305–339."
|
|
269
|
+
)
|
|
270
|
+
md_file <- file.path(output_dir, "minimum_n_recommendation.md")
|
|
271
|
+
writeLines(rec_lines, md_file)
|
|
272
|
+
log_info("Recommendation report saved: %s", md_file)
|
|
273
|
+
|
|
274
|
+
log_step(8, "Done — power analysis outputs in: %s", output_dir)
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ecosystem-services-assessment
|
|
3
|
+
description: "Maps and quantifies ecosystem services including carbon stocks, water yield, soil erosion, and habitat quality with trade-off analysis. Use this skill when the user mentions ecosystem services, InVEST models, ES mapping, carbon sequestration, water yield estimation, RUSLE erosion modeling, habitat quality, pollination services, trade-off analysis, PES (payments for ecosystem services), natural capital, or ES valuation."
|
|
4
|
+
skill_version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill: ecosystem-services-assessment
|
|
8
|
+
|
|
9
|
+
**Domain:** ES indicators · Provisioning · Regulating · Cultural · Trade-offs
|
|
10
|
+
**Phase:** 3 — Specialist
|
|
11
|
+
**Used by:** assess-ecosystem-services
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
Guides the agent through the quantification and spatial representation of ecosystem services (ES): selecting appropriate indicators, computing biophysical ES estimates, mapping ES supply, and analysing trade-offs and synergies between services.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## When to Invoke
|
|
22
|
+
|
|
23
|
+
- Quantifying ecosystem services across a landscape or watershed
|
|
24
|
+
- Mapping ES supply and demand
|
|
25
|
+
- Analysing trade-offs between conservation and production services
|
|
26
|
+
- Supporting payments for ecosystem services (PES) design
|
|
27
|
+
- Environmental impact assessments requiring ES valuation
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Inputs
|
|
32
|
+
|
|
33
|
+
| Input | Format | Required |
|
|
34
|
+
|-------|--------|----------|
|
|
35
|
+
| Land cover / land use map | GeoTIFF, SHP | Yes |
|
|
36
|
+
| Biophysical data (rainfall, DEM, soil, biomass) | GeoTIFF, CSV | Yes |
|
|
37
|
+
| Socioeconomic data (population, demand) | GeoTIFF, CSV | Optional |
|
|
38
|
+
| Study area polygon | SHP, GPKG | Yes |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Outputs
|
|
43
|
+
|
|
44
|
+
| Output | Description |
|
|
45
|
+
|--------|-------------|
|
|
46
|
+
| `es_indicator_maps/` | One raster per ES indicator |
|
|
47
|
+
| `es_summary_table.csv` | ES value per land cover class |
|
|
48
|
+
| `tradeoff_matrix.csv` | Pairwise ES correlation matrix |
|
|
49
|
+
| `tradeoff_plot.png` | Scatter plots or heatmap of ES trade-offs |
|
|
50
|
+
| `es_report.md` | Full ES assessment narrative |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Steps
|
|
55
|
+
|
|
56
|
+
### 1. Define the ES Portfolio
|
|
57
|
+
Select relevant services for the context:
|
|
58
|
+
|
|
59
|
+
| Category | Examples |
|
|
60
|
+
|----------|---------|
|
|
61
|
+
| Provisioning | Timber, water, food, fibre, genetic resources |
|
|
62
|
+
| Regulating | Carbon sequestration, water regulation, erosion control, pollination |
|
|
63
|
+
| Cultural | Recreation, aesthetic value, spiritual significance |
|
|
64
|
+
| Supporting | Habitat, nutrient cycling (underlying processes) |
|
|
65
|
+
|
|
66
|
+
### 2. Select Indicators and Methods per Service
|
|
67
|
+
- **Carbon:** Above-ground biomass from REDD+ datasets or allometric models; soil carbon from SoilGrids
|
|
68
|
+
- **Water regulation:** Curve number (CN) approach; InVEST Seasonal Water Yield
|
|
69
|
+
- **Erosion control:** Revised Universal Soil Loss Equation (RUSLE); C-factor from land cover
|
|
70
|
+
- **Pollination:** Distance-weighted bee habitat index from land cover
|
|
71
|
+
- **Recreation:** Proximity index to natural areas weighted by accessibility
|
|
72
|
+
|
|
73
|
+
### 3. Compute Biophysical ES Values
|
|
74
|
+
- Apply selected method per service; store as raster layer
|
|
75
|
+
- Validate against field measurements or published benchmarks where possible
|
|
76
|
+
- Document all input parameters and data sources
|
|
77
|
+
|
|
78
|
+
### 4. Aggregate by Land Cover Class
|
|
79
|
+
- Zonal statistics: mean/total ES value per land cover polygon or raster class
|
|
80
|
+
- Build summary table: rows = land cover classes, columns = ES indicators
|
|
81
|
+
- Normalise to 0–1 for cross-service comparison
|
|
82
|
+
|
|
83
|
+
### 5. Trade-off and Synergy Analysis
|
|
84
|
+
- Compute pairwise Spearman correlations across pixels or land cover units
|
|
85
|
+
- Positive correlations = synergies; negative = trade-offs
|
|
86
|
+
- Visualise as correlation heatmap and scatter plots
|
|
87
|
+
- Identify land cover classes that maximise multiple services simultaneously
|
|
88
|
+
|
|
89
|
+
### 6. Beneficiary Mapping (optional)
|
|
90
|
+
- Map ES demand using population density, agricultural areas, or water intake points
|
|
91
|
+
- Overlay supply and demand to identify supply-demand gaps
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Key Decisions to Document
|
|
96
|
+
|
|
97
|
+
- ES portfolio selection rationale
|
|
98
|
+
- Method and data source per service
|
|
99
|
+
- Normalisation method for cross-service comparison
|
|
100
|
+
- Trade-off analysis unit (pixel, land cover class, watershed)
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Tools and Libraries
|
|
105
|
+
|
|
106
|
+
**R:** `raster`, `terra`, `dplyr`, `ggplot2`, `corrplot`
|
|
107
|
+
**Python:** `rasterio`, `geopandas`, `seaborn`
|
|
108
|
+
**Dedicated:** InVEST (Stanford Natural Capital Project), ARIES, Co$ting Nature
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Resources
|
|
113
|
+
|
|
114
|
+
- `resources/es-indicator-reference.md` — indicator definitions per service
|
|
115
|
+
- `resources/invest-parameter-guide.md` — InVEST model configuration
|
|
116
|
+
- `resources/rusle-coefficients.md` — RUSLE factor lookup tables
|
|
117
|
+
- `examples/` — worked carbon + water regulation example
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Notes
|
|
122
|
+
|
|
123
|
+
- ES assessment does not require monetary valuation; biophysical indicators are often sufficient and more defensible
|
|
124
|
+
- InVEST is the most widely used open-source platform; use it unless a specific method is required
|
|
125
|
+
- Always report uncertainty in ES estimates, especially for carbon stocks
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Example Invocation Prompts — ecosystem-services-assessment
|
|
2
|
+
|
|
3
|
+
## Multi-Service Assessment
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
Load skill: ecosystem-services-assessment
|
|
7
|
+
Task: Assess three ecosystem services across the Mata Atlântica remnants in São Paulo state.
|
|
8
|
+
|
|
9
|
+
Services: (1) carbon storage, (2) erosion control, (3) pollination habitat
|
|
10
|
+
Inputs:
|
|
11
|
+
- data/landcover_sp_2022.tif (MapBiomas, 30m)
|
|
12
|
+
- data/biomass_mapbiomas.tif (above-ground biomass, MgC/ha)
|
|
13
|
+
- data/dem_sp.tif (SRTM 30m)
|
|
14
|
+
- data/rainfall_erosivity_sp.tif (R-factor, MJ·mm/ha/h/yr)
|
|
15
|
+
- data/sp_boundary.shp
|
|
16
|
+
|
|
17
|
+
Steps:
|
|
18
|
+
1. Carbon: extract biomass values per land cover class.
|
|
19
|
+
2. Erosion control: compute RUSLE C-factor from land cover; compute avoided soil loss.
|
|
20
|
+
3. Pollination: compute distance-weighted natural habitat index (1 km radius).
|
|
21
|
+
4. Summarise ES per land cover class (zonal statistics).
|
|
22
|
+
5. Trade-off analysis: pairwise Spearman correlations across pixels.
|
|
23
|
+
Output: es_indicator_maps/, es_summary_table.csv, tradeoff_matrix.csv, es_report.md
|
|
24
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Ecosystem Services Indicator Reference
|
|
2
|
+
|
|
3
|
+
## Provisioning Services
|
|
4
|
+
|
|
5
|
+
| Service | Indicator | Unit | Data source |
|
|
6
|
+
|---------|-----------|------|-------------|
|
|
7
|
+
| Above-ground carbon | Biomass carbon density | MgC/ha | REDD+ / GEDI / allometric |
|
|
8
|
+
| Soil organic carbon | SOC stock | MgC/ha | SoilGrids 2.0 |
|
|
9
|
+
| Timber | Volume/basal area | m³/ha | NFI data |
|
|
10
|
+
| Water availability | Mean annual streamflow | mm/year | SWAT / InVEST |
|
|
11
|
+
| Food production | Agricultural yield index | — | MapBiomas + FAO |
|
|
12
|
+
|
|
13
|
+
## Regulating Services
|
|
14
|
+
|
|
15
|
+
| Service | Indicator | Unit | Method |
|
|
16
|
+
|---------|-----------|------|--------|
|
|
17
|
+
| Carbon sequestration | Net ecosystem productivity | MgC/ha/year | MODIS MOD17 |
|
|
18
|
+
| Water regulation | Baseflow index | — | InVEST Seasonal Water Yield |
|
|
19
|
+
| Erosion control | Avoided soil loss | t/ha/year | RUSLE C-factor reduction |
|
|
20
|
+
| Flood regulation | Curve number (CN) | — | USDA-NRCS method |
|
|
21
|
+
| Pollination | Habitat suitability index | 0–1 | Distance from natural habitat |
|
|
22
|
+
| Climate regulation | Evapotranspiration anomaly | mm/year | MOD16 |
|
|
23
|
+
| Water purification | Nutrient retention | kg/ha/year | InVEST Nutrient Delivery Ratio |
|
|
24
|
+
|
|
25
|
+
## Cultural Services
|
|
26
|
+
|
|
27
|
+
| Service | Indicator | Unit | Method |
|
|
28
|
+
|---------|-----------|------|--------|
|
|
29
|
+
| Recreation | Accessibility-weighted natural area | ha (weighted) | Proximity index |
|
|
30
|
+
| Aesthetic value | Viewshed from scenic areas | — | GIS viewshed |
|
|
31
|
+
| Ecotourism potential | Biodiversity + accessibility index | — | Composite |
|
|
32
|
+
| Spiritual | Indigenous territory presence | Binary | FUNAI / IBGE |
|
|
33
|
+
|
|
34
|
+
## RUSLE C-factor by Land Cover (Brazil)
|
|
35
|
+
|
|
36
|
+
| Land cover class | C-factor |
|
|
37
|
+
|-----------------|---------|
|
|
38
|
+
| Dense forest | 0.001 |
|
|
39
|
+
| Secondary forest | 0.01 |
|
|
40
|
+
| Savanna (Cerrado) | 0.05 |
|
|
41
|
+
| Planted pasture | 0.15 |
|
|
42
|
+
| Degraded pasture | 0.40 |
|
|
43
|
+
| Annual cropland | 0.25–0.45 |
|
|
44
|
+
| Bare soil | 1.00 |
|
|
45
|
+
| Water body | 0 |
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# InVEST Model Configuration Guide
|
|
2
|
+
|
|
3
|
+
InVEST (Integrated Valuation of Ecosystem Services and Tradeoffs) is the most widely used open-source platform for ES assessment. Developed by Stanford Natural Capital Project.
|
|
4
|
+
|
|
5
|
+
## Available Models (most relevant for ecology)
|
|
6
|
+
|
|
7
|
+
| Model | ES assessed | Key inputs |
|
|
8
|
+
|-------|------------|-----------|
|
|
9
|
+
| Carbon Storage and Sequestration | Carbon stocks | LULC map + carbon pools table |
|
|
10
|
+
| Seasonal Water Yield | Water provisioning | LULC, DEM, soil, rainfall |
|
|
11
|
+
| Nutrient Delivery Ratio (NDR) | Water quality (N, P) | LULC, DEM, soil, streams |
|
|
12
|
+
| Sediment Delivery Ratio (SDR) | Erosion / sedimentation | LULC, DEM, soil, rainfall erosivity |
|
|
13
|
+
| Habitat Quality | Biodiversity / habitat | LULC, threat sources, sensitivity table |
|
|
14
|
+
| Pollination | Crop pollination | LULC, nesting habitat, floral resources |
|
|
15
|
+
| Recreation | Ecotourism / recreation | LULC, access points, visitor data |
|
|
16
|
+
| Coastal Blue Carbon | Mangrove/seagrass carbon | LULC (coastal), carbon pools |
|
|
17
|
+
|
|
18
|
+
## Carbon Storage Model
|
|
19
|
+
|
|
20
|
+
**Inputs:**
|
|
21
|
+
- `lulc_current.tif` — Land use/land cover raster (integer class codes)
|
|
22
|
+
- `carbon_pools.csv` — Carbon pool values per LULC class
|
|
23
|
+
|
|
24
|
+
**Carbon pools table format:**
|
|
25
|
+
|
|
26
|
+
| lucode | LULC_name | C_above | C_below | C_soil | C_dead |
|
|
27
|
+
|--------|-----------|---------|---------|--------|--------|
|
|
28
|
+
| 1 | Dense forest | 150 | 30 | 80 | 5 |
|
|
29
|
+
| 2 | Secondary forest | 60 | 15 | 50 | 3 |
|
|
30
|
+
| 3 | Cerrado | 30 | 20 | 40 | 2 |
|
|
31
|
+
| 4 | Pasture | 5 | 3 | 20 | 0 |
|
|
32
|
+
| 5 | Cropland | 3 | 1 | 15 | 0 |
|
|
33
|
+
|
|
34
|
+
Units: Mg C / ha. Sources: IPCC Tier 1 default values; REDD+ national forest inventories; MapBiomas biomass layer.
|
|
35
|
+
|
|
36
|
+
## Sediment Delivery Ratio (SDR) — Key Parameters
|
|
37
|
+
|
|
38
|
+
| Parameter | Typical range | Notes |
|
|
39
|
+
|-----------|--------------|-------|
|
|
40
|
+
| Threshold flow accumulation | 1000–5000 cells | Higher = fewer streams |
|
|
41
|
+
| k_param (USLE K) | 0.01–0.8 t·ha·h/ha/MJ/mm | Soil erodibility factor |
|
|
42
|
+
| l_max | 122 m | Maximum USLE L factor slope length |
|
|
43
|
+
| sdr_max | 0.8 | Maximum SDR value |
|
|
44
|
+
|
|
45
|
+
## Habitat Quality Model
|
|
46
|
+
|
|
47
|
+
**Threat sources table:**
|
|
48
|
+
|
|
49
|
+
| threat | max_dist | weight | decay |
|
|
50
|
+
|--------|---------|--------|-------|
|
|
51
|
+
| roads | 5 | 0.8 | exponential |
|
|
52
|
+
| agriculture | 8 | 0.6 | linear |
|
|
53
|
+
| urban | 10 | 1.0 | exponential |
|
|
54
|
+
|
|
55
|
+
**Sensitivity table** (access_weight per threat × LULC):
|
|
56
|
+
|
|
57
|
+
| LULC | L_threat_roads | L_threat_agriculture | L_threat_urban |
|
|
58
|
+
|------|---------------|---------------------|---------------|
|
|
59
|
+
| Forest | 0.5 | 0.4 | 0.7 |
|
|
60
|
+
| Savanna | 0.6 | 0.5 | 0.8 |
|
|
61
|
+
| Wetland | 0.7 | 0.6 | 0.9 |
|
|
62
|
+
| Pasture | 0.0 | 0.0 | 0.3 |
|
|
63
|
+
|
|
64
|
+
## Running InVEST from Python
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
import natcap.invest.carbon
|
|
68
|
+
|
|
69
|
+
args = {
|
|
70
|
+
'workspace_dir': 'outputs/invest_carbon',
|
|
71
|
+
'lulc_cur_path': 'data/landcover_2022.tif',
|
|
72
|
+
'carbon_pools_path': 'data/carbon_pools.csv',
|
|
73
|
+
'calc_sequestration': False,
|
|
74
|
+
'do_redd': False,
|
|
75
|
+
'do_valuation': False,
|
|
76
|
+
}
|
|
77
|
+
natcap.invest.carbon.execute(args)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Installation
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install natcap.invest
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Or via Conda: `conda install -c conda-forge natcap.invest`
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# RUSLE Factor Reference
|
|
2
|
+
|
|
3
|
+
The Revised Universal Soil Loss Equation estimates annual soil loss:
|
|
4
|
+
|
|
5
|
+
**A = R × K × LS × C × P**
|
|
6
|
+
|
|
7
|
+
where A = soil loss (t/ha/yr).
|
|
8
|
+
|
|
9
|
+
## R Factor — Rainfall Erosivity (MJ·mm/ha/h/yr)
|
|
10
|
+
|
|
11
|
+
| Region (Brazil) | Typical R range | Source |
|
|
12
|
+
|----------------|----------------|--------|
|
|
13
|
+
| Amazon (high rainfall) | 8,000–12,000 | Panagos et al. 2017 |
|
|
14
|
+
| Cerrado | 5,000–9,000 | Oliveira et al. 2013 |
|
|
15
|
+
| Atlantic Forest coast | 6,000–10,000 | |
|
|
16
|
+
| Semi-arid Northeast | 1,000–3,000 | |
|
|
17
|
+
| Southern Brazil | 5,000–8,000 | |
|
|
18
|
+
|
|
19
|
+
Available layer: Global Rainfall Erosivity Database (ESDAC / Panagos et al. 2017)
|
|
20
|
+
DOI: 10.1016/j.scitotenv.2017.06.199
|
|
21
|
+
|
|
22
|
+
## K Factor — Soil Erodibility (t·ha·h/ha/MJ/mm)
|
|
23
|
+
|
|
24
|
+
| Soil texture | K range | Notes |
|
|
25
|
+
|-------------|---------|-------|
|
|
26
|
+
| Sandy / coarse | 0.01–0.10 | Low erodibility |
|
|
27
|
+
| Loamy sand | 0.05–0.15 | |
|
|
28
|
+
| Sandy loam | 0.10–0.25 | |
|
|
29
|
+
| Loam | 0.15–0.35 | Moderate |
|
|
30
|
+
| Silt loam | 0.25–0.45 | High |
|
|
31
|
+
| Clay loam | 0.20–0.40 | |
|
|
32
|
+
| Clay | 0.10–0.30 | Cohesive; lower K |
|
|
33
|
+
| Organic / Latosol | 0.01–0.08 | Low despite fine texture |
|
|
34
|
+
|
|
35
|
+
Source: SoilGrids 2.0 provides K factor globally at 250 m.
|
|
36
|
+
|
|
37
|
+
## LS Factor — Slope Length × Steepness
|
|
38
|
+
|
|
39
|
+
Computed from DEM using:
|
|
40
|
+
|
|
41
|
+
```r
|
|
42
|
+
library(terra)
|
|
43
|
+
library(whitebox)
|
|
44
|
+
dem <- rast("dem.tif")
|
|
45
|
+
wbt_slope(input = "dem.tif", output = "slope.tif", units = "degrees")
|
|
46
|
+
# LS factor: use standard RUSLE LS equations via saga or whitebox
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or use the pre-computed global LS factor from Panagos et al. 2015.
|
|
50
|
+
|
|
51
|
+
## C Factor — Cover Management (key for ES assessment)
|
|
52
|
+
|
|
53
|
+
The C factor represents the effect of land cover and management on soil erosion relative to bare fallow.
|
|
54
|
+
|
|
55
|
+
| Land cover (MapBiomas) | C factor |
|
|
56
|
+
|-----------------------|---------|
|
|
57
|
+
| Dense Amazon forest | 0.0001 |
|
|
58
|
+
| Open tropical forest | 0.001 |
|
|
59
|
+
| Savanna (Cerrado) | 0.01–0.05 |
|
|
60
|
+
| Secondary forest (old) | 0.005 |
|
|
61
|
+
| Secondary forest (young) | 0.05 |
|
|
62
|
+
| Planted pasture (good) | 0.01 |
|
|
63
|
+
| Planted pasture (degraded) | 0.25–0.50 |
|
|
64
|
+
| Annual crops (soy/corn) | 0.20–0.40 |
|
|
65
|
+
| Sugarcane | 0.15 |
|
|
66
|
+
| Natural wetland | 0.001 |
|
|
67
|
+
| Mangrove | 0.00001 |
|
|
68
|
+
| Bare soil / exposed rock | 1.00 |
|
|
69
|
+
| Urban | 0.00 (no erosion model) |
|
|
70
|
+
|
|
71
|
+
## P Factor — Support Practices
|
|
72
|
+
|
|
73
|
+
| Practice | P factor |
|
|
74
|
+
|---------|---------|
|
|
75
|
+
| No practice (default) | 1.00 |
|
|
76
|
+
| Contour farming | 0.50–0.75 |
|
|
77
|
+
| Terracing | 0.10–0.50 |
|
|
78
|
+
| Strip cropping | 0.35–0.70 |
|
|
79
|
+
|
|
80
|
+
Default P = 1.0 for natural landscapes (no agricultural support practices).
|
|
81
|
+
|
|
82
|
+
## Avoided Soil Loss (ES Indicator)
|
|
83
|
+
|
|
84
|
+
Erosion control service = A_bare − A_vegetated
|
|
85
|
+
|
|
86
|
+
where A_bare = soil loss if bare soil (C = 1, P = 1) and A_vegetated = actual soil loss.
|
|
87
|
+
|
|
88
|
+
This difference represents the erosion that the current vegetation is preventing.
|