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.
Files changed (217) hide show
  1. package/AGENT_CONTEXT.md +191 -0
  2. package/CATALOG.md +329 -0
  3. package/LICENSE +692 -0
  4. package/README.md +347 -0
  5. package/bin/install.mjs +168 -0
  6. package/docs/comparison-with-alternatives.md +38 -0
  7. package/docs/global-examples-index.md +103 -0
  8. package/docs/repository-statistics.md +101 -0
  9. package/docs/theoretical-foundations.md +188 -0
  10. package/environment.yaml +106 -0
  11. package/examples/community/arctic_tundra_vegetation_example.md +247 -0
  12. package/examples/community/bird_landuse_example.md +63 -0
  13. package/examples/community/phytoplankton_reservoir_example.md +60 -0
  14. package/examples/community/reef_fish_indopacific_example.md +221 -0
  15. package/examples/impact/baci_road_example.md +57 -0
  16. package/examples/impact/ecosystem_services_atlantic_forest.md +83 -0
  17. package/examples/impact/forest_loss_borneo_timeseries_example.md +225 -0
  18. package/examples/occupancy/puma_camera_example.md +61 -0
  19. package/examples/occupancy/snow_leopard_himalayas_example.md +204 -0
  20. package/examples/reproducible/whittaker_biome_sdm_example.md +406 -0
  21. package/examples/sdm/anteater_cerrado_example.md +69 -0
  22. package/examples/sdm/jaguar_amazon_example.md +80 -0
  23. package/examples/sdm/koala_climate_change_example.md +170 -0
  24. package/examples/sdm/wolf_recolonization_europe_example.md +193 -0
  25. package/package.json +43 -0
  26. package/renv.lock +194 -0
  27. package/skills/SKILL_INDEX.json +1020 -0
  28. package/skills/acoustic-monitoring/SKILL.md +163 -0
  29. package/skills/acoustic-monitoring/examples/example-prompts.md +100 -0
  30. package/skills/acoustic-monitoring/examples/temperate_forest_birds_example.md +285 -0
  31. package/skills/acoustic-monitoring/resources/acoustic-indices-reference.md +93 -0
  32. package/skills/acoustic-monitoring/resources/soundscape-ecology-guide.md +90 -0
  33. package/skills/acoustic-monitoring/resources/species-id-tools-comparison.md +89 -0
  34. package/skills/acoustic-monitoring/scripts/batch_species_detection.py +360 -0
  35. package/skills/acoustic-monitoring/scripts/compute_acoustic_indices.R +235 -0
  36. package/skills/acoustic-monitoring/scripts/compute_acoustic_indices.py +374 -0
  37. package/skills/biostatistics-workbench/SKILL.md +140 -0
  38. package/skills/biostatistics-workbench/examples/example-prompts.md +39 -0
  39. package/skills/biostatistics-workbench/resources/effect-size-reference.md +81 -0
  40. package/skills/biostatistics-workbench/resources/glm-family-link-reference.md +47 -0
  41. package/skills/biostatistics-workbench/resources/test-selection-guide.md +93 -0
  42. package/skills/biostatistics-workbench/scripts/glm_pipeline.R +78 -0
  43. package/skills/biostatistics-workbench/scripts/glm_pipeline.py +210 -0
  44. package/skills/camera-trap-processing/SKILL.md +159 -0
  45. package/skills/camera-trap-processing/examples/example-prompts.md +103 -0
  46. package/skills/camera-trap-processing/examples/leopard_serengeti_example.md +231 -0
  47. package/skills/camera-trap-processing/resources/activity-patterns-reference.md +113 -0
  48. package/skills/camera-trap-processing/resources/camtrapR-workflow-guide.md +130 -0
  49. package/skills/camera-trap-processing/resources/detection-event-definition-guide.md +89 -0
  50. package/skills/camera-trap-processing/scripts/estimate_activity.R +169 -0
  51. package/skills/camera-trap-processing/scripts/process_camtrap_data.R +179 -0
  52. package/skills/camera-trap-processing/scripts/process_camtrap_data.py +192 -0
  53. package/skills/community-ecology-ordination/SKILL.md +133 -0
  54. package/skills/community-ecology-ordination/examples/example-prompts.md +35 -0
  55. package/skills/community-ecology-ordination/resources/dissimilarity-metric-guide.md +53 -0
  56. package/skills/community-ecology-ordination/resources/nmds-interpretation-guide.md +104 -0
  57. package/skills/community-ecology-ordination/scripts/__pycache__/community_analysis.cpython-311.pyc +0 -0
  58. package/skills/community-ecology-ordination/scripts/community_analysis.R +143 -0
  59. package/skills/community-ecology-ordination/scripts/community_analysis.py +231 -0
  60. package/skills/ecological-data-foundation/SKILL.md +129 -0
  61. package/skills/ecological-data-foundation/examples/example-prompts.md +40 -0
  62. package/skills/ecological-data-foundation/resources/coordinate-cleaning-flags.md +66 -0
  63. package/skills/ecological-data-foundation/resources/darwin-core-glossary.md +91 -0
  64. package/skills/ecological-data-foundation/resources/data-citation-guide.md +265 -0
  65. package/skills/ecological-data-foundation/resources/gbif-data-citation-guide.md +193 -0
  66. package/skills/ecological-data-foundation/resources/qa-checklist.md +83 -0
  67. package/skills/ecological-data-foundation/scripts/__pycache__/clean_occurrences.cpython-311.pyc +0 -0
  68. package/skills/ecological-data-foundation/scripts/__pycache__/download_from_ebird.cpython-311.pyc +0 -0
  69. package/skills/ecological-data-foundation/scripts/__pycache__/download_from_inat.cpython-311.pyc +0 -0
  70. package/skills/ecological-data-foundation/scripts/__pycache__/download_from_iucn.cpython-311.pyc +0 -0
  71. package/skills/ecological-data-foundation/scripts/__pycache__/download_from_obis.cpython-311.pyc +0 -0
  72. package/skills/ecological-data-foundation/scripts/clean_occurrences.R +230 -0
  73. package/skills/ecological-data-foundation/scripts/clean_occurrences.py +268 -0
  74. package/skills/ecological-data-foundation/scripts/download_from_ebird.R +251 -0
  75. package/skills/ecological-data-foundation/scripts/download_from_ebird.py +364 -0
  76. package/skills/ecological-data-foundation/scripts/download_from_gbif.R +315 -0
  77. package/skills/ecological-data-foundation/scripts/download_from_gbif.py +407 -0
  78. package/skills/ecological-data-foundation/scripts/download_from_inat.R +238 -0
  79. package/skills/ecological-data-foundation/scripts/download_from_inat.py +304 -0
  80. package/skills/ecological-data-foundation/scripts/download_from_iucn.R +273 -0
  81. package/skills/ecological-data-foundation/scripts/download_from_iucn.py +344 -0
  82. package/skills/ecological-data-foundation/scripts/download_from_obis.R +248 -0
  83. package/skills/ecological-data-foundation/scripts/download_from_obis.py +318 -0
  84. package/skills/ecological-impact-assessment/SKILL.md +123 -0
  85. package/skills/ecological-impact-assessment/examples/example-prompts.md +32 -0
  86. package/skills/ecological-impact-assessment/resources/baci-design-guide.md +55 -0
  87. package/skills/ecological-impact-assessment/resources/fragmentation-metrics-reference.md +86 -0
  88. package/skills/ecological-impact-assessment/resources/pressure-index-template.md +78 -0
  89. package/skills/ecological-impact-assessment/resources/study-design-guide.md +168 -0
  90. package/skills/ecological-impact-assessment/scripts/baci_analysis.R +161 -0
  91. package/skills/ecological-impact-assessment/scripts/fragmentation_analysis.py +141 -0
  92. package/skills/ecological-impact-assessment/scripts/power_analysis_baci.R +274 -0
  93. package/skills/ecosystem-services-assessment/SKILL.md +125 -0
  94. package/skills/ecosystem-services-assessment/examples/example-prompts.md +24 -0
  95. package/skills/ecosystem-services-assessment/resources/es-indicator-reference.md +45 -0
  96. package/skills/ecosystem-services-assessment/resources/invest-parameter-guide.md +86 -0
  97. package/skills/ecosystem-services-assessment/resources/rusle-coefficients.md +88 -0
  98. package/skills/ecosystem-services-assessment/scripts/__pycache__/compute_es.cpython-311.pyc +0 -0
  99. package/skills/ecosystem-services-assessment/scripts/compute_es.py +189 -0
  100. package/skills/ecosystem-services-assessment/scripts/tradeoff_analysis.R +161 -0
  101. package/skills/environmental-time-series/SKILL.md +125 -0
  102. package/skills/environmental-time-series/examples/example-prompts.md +33 -0
  103. package/skills/environmental-time-series/resources/anomaly-indices-reference.md +88 -0
  104. package/skills/environmental-time-series/resources/bfast-parameter-guide.md +69 -0
  105. package/skills/environmental-time-series/scripts/__pycache__/recovery_trajectory.cpython-311.pyc +0 -0
  106. package/skills/environmental-time-series/scripts/__pycache__/trend_analysis.cpython-311.pyc +0 -0
  107. package/skills/environmental-time-series/scripts/recovery_trajectory.R +305 -0
  108. package/skills/environmental-time-series/scripts/recovery_trajectory.py +178 -0
  109. package/skills/environmental-time-series/scripts/trend_analysis.R +192 -0
  110. package/skills/environmental-time-series/scripts/trend_analysis.py +184 -0
  111. package/skills/geoprocessing-for-ecology/SKILL.md +123 -0
  112. package/skills/geoprocessing-for-ecology/examples/example-prompts.md +32 -0
  113. package/skills/geoprocessing-for-ecology/resources/crs-reference.md +62 -0
  114. package/skills/geoprocessing-for-ecology/resources/global-predictor-sources.md +331 -0
  115. package/skills/geoprocessing-for-ecology/resources/resampling-methods.md +57 -0
  116. package/skills/geoprocessing-for-ecology/scripts/__pycache__/download_predictors.cpython-311.pyc +0 -0
  117. package/skills/geoprocessing-for-ecology/scripts/download_predictors.R +239 -0
  118. package/skills/geoprocessing-for-ecology/scripts/download_predictors.py +379 -0
  119. package/skills/geoprocessing-for-ecology/scripts/stack_and_extract.R +224 -0
  120. package/skills/geoprocessing-for-ecology/scripts/stack_and_extract.py +172 -0
  121. package/skills/landscape-connectivity/SKILL.md +170 -0
  122. package/skills/landscape-connectivity/examples/example-prompts.md +96 -0
  123. package/skills/landscape-connectivity/examples/jaguar_mesoamerica_corridor_example.md +271 -0
  124. package/skills/landscape-connectivity/resources/circuitscape-parameter-guide.md +155 -0
  125. package/skills/landscape-connectivity/resources/graph-theory-for-ecology.md +134 -0
  126. package/skills/landscape-connectivity/resources/resistance-surface-guide.md +141 -0
  127. package/skills/landscape-connectivity/scripts/connectivity_analysis.py +387 -0
  128. package/skills/landscape-connectivity/scripts/connectivity_metrics.R +274 -0
  129. package/skills/landscape-connectivity/scripts/resistance_surface.R +239 -0
  130. package/skills/model-validation-and-uncertainty/SKILL.md +131 -0
  131. package/skills/model-validation-and-uncertainty/examples/example-prompts.md +30 -0
  132. package/skills/model-validation-and-uncertainty/resources/extrapolation-risk-guide.md +236 -0
  133. package/skills/model-validation-and-uncertainty/resources/metric-selection-guide.md +52 -0
  134. package/skills/model-validation-and-uncertainty/resources/threshold-selection-guide.md +64 -0
  135. package/skills/model-validation-and-uncertainty/scripts/__pycache__/validate_model.cpython-311.pyc +0 -0
  136. package/skills/model-validation-and-uncertainty/scripts/extrapolation_risk.R +315 -0
  137. package/skills/model-validation-and-uncertainty/scripts/validate_model.py +226 -0
  138. package/skills/model-validation-and-uncertainty/scripts/validate_sdm.R +162 -0
  139. package/skills/occupancy-and-detection/SKILL.md +126 -0
  140. package/skills/occupancy-and-detection/examples/example-prompts.md +33 -0
  141. package/skills/occupancy-and-detection/resources/detection-history-format.md +100 -0
  142. package/skills/occupancy-and-detection/resources/occupancy-study-design.md +47 -0
  143. package/skills/occupancy-and-detection/scripts/__pycache__/occupancy_analysis.cpython-311.pyc +0 -0
  144. package/skills/occupancy-and-detection/scripts/occupancy_analysis.R +160 -0
  145. package/skills/occupancy-and-detection/scripts/occupancy_analysis.py +159 -0
  146. package/skills/population-viability-analysis/SKILL.md +161 -0
  147. package/skills/population-viability-analysis/examples/african_elephant_pva_example.md +266 -0
  148. package/skills/population-viability-analysis/examples/example-prompts.md +95 -0
  149. package/skills/population-viability-analysis/resources/extinction-risk-thresholds.md +128 -0
  150. package/skills/population-viability-analysis/resources/matrix-model-guide.md +139 -0
  151. package/skills/population-viability-analysis/resources/sensitivity-elasticity-reference.md +182 -0
  152. package/skills/population-viability-analysis/scripts/matrix_pva.R +258 -0
  153. package/skills/population-viability-analysis/scripts/pva_analysis.py +442 -0
  154. package/skills/population-viability-analysis/scripts/stochastic_pva.R +353 -0
  155. package/skills/predictive-modeling-best-practices/SKILL.md +136 -0
  156. package/skills/predictive-modeling-best-practices/examples/example-prompts.md +58 -0
  157. package/skills/predictive-modeling-best-practices/resources/collinearity-decision-tree.md +65 -0
  158. package/skills/predictive-modeling-best-practices/resources/sampling-bias-correction.md +267 -0
  159. package/skills/predictive-modeling-best-practices/resources/spatial-cv-guide.md +73 -0
  160. package/skills/predictive-modeling-best-practices/scripts/__pycache__/spatial_cv.cpython-311.pyc +0 -0
  161. package/skills/predictive-modeling-best-practices/scripts/collinearity_check.R +112 -0
  162. package/skills/predictive-modeling-best-practices/scripts/spatial_cv.py +182 -0
  163. package/skills/reproducible-ecology-pipeline/SKILL.md +139 -0
  164. package/skills/reproducible-ecology-pipeline/examples/example-prompts.md +35 -0
  165. package/skills/reproducible-ecology-pipeline/resources/directory-structure-template.md +94 -0
  166. package/skills/reproducible-ecology-pipeline/resources/params-yaml-template.yaml +84 -0
  167. package/skills/reproducible-ecology-pipeline/resources/reproducibility-checklist-template.md +66 -0
  168. package/skills/reproducible-ecology-pipeline/scripts/generate_file_manifest.py +110 -0
  169. package/skills/reproducible-ecology-pipeline/scripts/init_project.sh +53 -0
  170. package/skills/spatial-prioritization/SKILL.md +162 -0
  171. package/skills/spatial-prioritization/examples/biodiversity_hotspot_prioritization_example.md +289 -0
  172. package/skills/spatial-prioritization/examples/example-prompts.md +93 -0
  173. package/skills/spatial-prioritization/resources/cost-surface-reference.md +130 -0
  174. package/skills/spatial-prioritization/resources/marxan-vs-prioritizr-comparison.md +125 -0
  175. package/skills/spatial-prioritization/resources/prioritizr-formulation-guide.md +188 -0
  176. package/skills/spatial-prioritization/resources/representation-targets-guide.md +186 -0
  177. package/skills/spatial-prioritization/scripts/prioritization_sensitivity.R +320 -0
  178. package/skills/spatial-prioritization/scripts/run_prioritization.R +336 -0
  179. package/skills/species-distribution-modeling/SKILL.md +139 -0
  180. package/skills/species-distribution-modeling/examples/example-prompts.md +36 -0
  181. package/skills/species-distribution-modeling/resources/algorithm-comparison.md +25 -0
  182. package/skills/species-distribution-modeling/resources/calibration-area-guide.md +71 -0
  183. package/skills/species-distribution-modeling/resources/climate-scenario-preparation.md +170 -0
  184. package/skills/species-distribution-modeling/resources/maxent-calibration-guide.md +211 -0
  185. package/skills/species-distribution-modeling/resources/sdm-checklist.md +37 -0
  186. package/skills/species-distribution-modeling/scripts/predict_distribution.R +236 -0
  187. package/skills/species-distribution-modeling/scripts/predict_distribution.py +286 -0
  188. package/skills/species-distribution-modeling/scripts/prepare_future_layers.R +351 -0
  189. package/skills/species-distribution-modeling/scripts/project_scenarios.R +220 -0
  190. package/skills/species-distribution-modeling/scripts/run_ensemble_sdm.R +99 -0
  191. package/skills/species-distribution-modeling/scripts/sdm_pipeline.py +318 -0
  192. package/skills/species-distribution-modeling/scripts/tune_maxnet.R +344 -0
  193. package/templates/SKILL_TEMPLATE.md +225 -0
  194. package/templates/checklists/data-submission-checklist.md +38 -0
  195. package/templates/checklists/post-analysis-checklist.md +55 -0
  196. package/templates/checklists/pre-analysis-checklist.md +31 -0
  197. package/templates/prompts/debug-skill.md +47 -0
  198. package/templates/prompts/invoke-skill.md +34 -0
  199. package/templates/prompts/invoke-workflow.md +45 -0
  200. package/templates/reports/technical-report-template.md +80 -0
  201. package/templates/scripts/logger_setup.R +79 -0
  202. package/templates/scripts/logger_setup.py +119 -0
  203. package/templates/scripts/params_loader.R +28 -0
  204. package/templates/scripts/params_loader.py +38 -0
  205. package/workflows/analyze-community-structure/WORKFLOW.md +72 -0
  206. package/workflows/analyze-environmental-change/WORKFLOW.md +73 -0
  207. package/workflows/assess-ecological-impact/WORKFLOW.md +75 -0
  208. package/workflows/assess-ecosystem-services/WORKFLOW.md +68 -0
  209. package/workflows/assess-landscape-connectivity/WORKFLOW.md +84 -0
  210. package/workflows/build-fire-risk-map/WORKFLOW.md +79 -0
  211. package/workflows/produce-technical-report/WORKFLOW.md +113 -0
  212. package/workflows/run-camera-trap-occupancy/WORKFLOW.md +87 -0
  213. package/workflows/run-conservation-prioritization/WORKFLOW.md +89 -0
  214. package/workflows/run-multispecies-screening/WORKFLOW.md +197 -0
  215. package/workflows/run-occupancy-analysis/WORKFLOW.md +74 -0
  216. package/workflows/run-population-viability/WORKFLOW.md +90 -0
  217. 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.