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,119 @@
|
|
|
1
|
+
"""logger_setup.py — Structured logging template for ecological-agent-skills.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import sys
|
|
6
|
+
sys.path.insert(0, str(Path(__file__).parents[2] / "templates" / "scripts"))
|
|
7
|
+
from logger_setup import setup_logger, log_step, log_decision, log_actionable_error
|
|
8
|
+
|
|
9
|
+
logger = setup_logger("skill-name")
|
|
10
|
+
|
|
11
|
+
Log format : [TIMESTAMP] [LEVEL] [SKILL] message
|
|
12
|
+
Log file : logs/skill_{name}_{timestamp}.log (relative to cwd)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import logging
|
|
16
|
+
import sys
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
_SKILL_NAME = "eco-skill"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def setup_logger(
|
|
24
|
+
skill_name: str = "eco-skill",
|
|
25
|
+
log_dir: str = "logs",
|
|
26
|
+
level: int = logging.INFO,
|
|
27
|
+
) -> logging.Logger:
|
|
28
|
+
"""Initialise a logger that writes to console AND a dated log file.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
skill_name : str
|
|
33
|
+
Short identifier used in the log filename and every log record.
|
|
34
|
+
log_dir : str
|
|
35
|
+
Directory where log files are written (created if absent).
|
|
36
|
+
level : int
|
|
37
|
+
Logging level (logging.DEBUG / INFO / WARNING / ERROR).
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
logging.Logger
|
|
42
|
+
Configured logger instance.
|
|
43
|
+
"""
|
|
44
|
+
global _SKILL_NAME
|
|
45
|
+
_SKILL_NAME = skill_name
|
|
46
|
+
|
|
47
|
+
Path(log_dir).mkdir(parents=True, exist_ok=True)
|
|
48
|
+
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
49
|
+
log_file = Path(log_dir) / f"skill_{skill_name}_{ts}.log"
|
|
50
|
+
|
|
51
|
+
fmt = f"[%(asctime)s] [%(levelname)s] [{skill_name}] %(message)s"
|
|
52
|
+
datefmt = "%Y-%m-%d %H:%M:%S"
|
|
53
|
+
formatter = logging.Formatter(fmt, datefmt=datefmt)
|
|
54
|
+
|
|
55
|
+
logger = logging.getLogger(skill_name)
|
|
56
|
+
logger.setLevel(level)
|
|
57
|
+
logger.handlers.clear()
|
|
58
|
+
|
|
59
|
+
# Console handler
|
|
60
|
+
ch = logging.StreamHandler(sys.stdout)
|
|
61
|
+
ch.setFormatter(formatter)
|
|
62
|
+
logger.addHandler(ch)
|
|
63
|
+
|
|
64
|
+
# File handler
|
|
65
|
+
fh = logging.FileHandler(log_file, encoding="utf-8")
|
|
66
|
+
fh.setFormatter(formatter)
|
|
67
|
+
logger.addHandler(fh)
|
|
68
|
+
|
|
69
|
+
logger.info("Logger initialised | skill=%s | log_file=%s", skill_name, log_file)
|
|
70
|
+
return logger
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# ── Convenience wrappers ─────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
def log_step(logger: logging.Logger, step_number: int, description: str) -> None:
|
|
76
|
+
"""Mark the start of a numbered processing step."""
|
|
77
|
+
logger.info("── STEP %d: %s", step_number, description)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def log_decision(
|
|
81
|
+
logger: logging.Logger, variable: str, value, rationale: str
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Record an analytical decision with justification."""
|
|
84
|
+
logger.info("DECISION | %s = %s | rationale: %s", variable, value, rationale)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def log_actionable_error(
|
|
88
|
+
logger: logging.Logger,
|
|
89
|
+
step: str,
|
|
90
|
+
error_msg: str,
|
|
91
|
+
probable_cause: str,
|
|
92
|
+
check_this: str,
|
|
93
|
+
prior_skill: str | None = None,
|
|
94
|
+
) -> None:
|
|
95
|
+
"""Log a structured, actionable error message.
|
|
96
|
+
|
|
97
|
+
Parameters
|
|
98
|
+
----------
|
|
99
|
+
step : Name of the failing processing step.
|
|
100
|
+
error_msg : The exception message.
|
|
101
|
+
probable_cause : One-sentence explanation of likely cause.
|
|
102
|
+
check_this : What the user should inspect to diagnose.
|
|
103
|
+
prior_skill : Upstream skill that should have produced the missing input.
|
|
104
|
+
"""
|
|
105
|
+
prior_line = (
|
|
106
|
+
f"\n Skill anterior que deveria ter produzido este input: {prior_skill}"
|
|
107
|
+
if prior_skill
|
|
108
|
+
else ""
|
|
109
|
+
)
|
|
110
|
+
logger.error(
|
|
111
|
+
"[ERROR] Falha em %s: %s\n"
|
|
112
|
+
" Causa provável: %s\n"
|
|
113
|
+
" Verifique: %s%s",
|
|
114
|
+
step,
|
|
115
|
+
error_msg,
|
|
116
|
+
probable_cause,
|
|
117
|
+
check_this,
|
|
118
|
+
prior_line,
|
|
119
|
+
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# params_loader.R
|
|
2
|
+
# Load project parameters from params.yaml into R environment
|
|
3
|
+
# Source this at the top of every analysis script:
|
|
4
|
+
# source("scripts/params_loader.R")
|
|
5
|
+
# Requires: yaml
|
|
6
|
+
|
|
7
|
+
if (!requireNamespace("yaml", quietly = TRUE)) install.packages("yaml")
|
|
8
|
+
library(yaml)
|
|
9
|
+
|
|
10
|
+
PARAMS_FILE <- "params.yaml"
|
|
11
|
+
if (!file.exists(PARAMS_FILE)) stop("params.yaml not found in working directory: ", getwd())
|
|
12
|
+
|
|
13
|
+
p <- yaml::read_yaml(PARAMS_FILE)
|
|
14
|
+
cat("params.yaml loaded. Project:", p$project$name, "| Version:", p$project$version, "\n")
|
|
15
|
+
|
|
16
|
+
# Set random seeds
|
|
17
|
+
set.seed(p$random_seeds$global)
|
|
18
|
+
cat("Global random seed set to:", p$random_seeds$global, "\n")
|
|
19
|
+
|
|
20
|
+
# Convenience aliases
|
|
21
|
+
PROJECT_CRS <- p$spatial$project_crs
|
|
22
|
+
ANALYSIS_CRS <- p$spatial$analysis_crs
|
|
23
|
+
OUTPUT_RES <- p$spatial$raster_resolution_m
|
|
24
|
+
CV_FOLDS <- p$modeling$cv_folds
|
|
25
|
+
N_BACKGROUND <- p$modeling$background_n
|
|
26
|
+
VIF_THRESH <- p$modeling$collinearity_vif_threshold
|
|
27
|
+
|
|
28
|
+
cat("CRS:", PROJECT_CRS, "| CV folds:", CV_FOLDS, "| Background n:", N_BACKGROUND, "\n")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# params_loader.py
|
|
2
|
+
# Load project parameters from params.yaml into Python namespace
|
|
3
|
+
# Usage: from scripts.params_loader import p, set_seeds
|
|
4
|
+
# Requires: pyyaml, numpy, random
|
|
5
|
+
|
|
6
|
+
import yaml
|
|
7
|
+
import random
|
|
8
|
+
import os
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
PARAMS_FILE = "params.yaml"
|
|
12
|
+
|
|
13
|
+
def load_params(path: str = PARAMS_FILE) -> dict:
|
|
14
|
+
if not os.path.exists(path):
|
|
15
|
+
raise FileNotFoundError(f"params.yaml not found at: {os.path.abspath(path)}")
|
|
16
|
+
with open(path, "r") as f:
|
|
17
|
+
params = yaml.safe_load(f)
|
|
18
|
+
print(f"params.yaml loaded. Project: {params['project']['name']} | Version: {params['project']['version']}")
|
|
19
|
+
return params
|
|
20
|
+
|
|
21
|
+
def set_seeds(params: dict) -> None:
|
|
22
|
+
seed = params["random_seeds"]["global"]
|
|
23
|
+
random.seed(seed)
|
|
24
|
+
np.random.seed(seed)
|
|
25
|
+
try:
|
|
26
|
+
import torch
|
|
27
|
+
torch.manual_seed(seed)
|
|
28
|
+
except ImportError:
|
|
29
|
+
pass
|
|
30
|
+
print(f"Random seeds set to: {seed}")
|
|
31
|
+
|
|
32
|
+
p = load_params()
|
|
33
|
+
set_seeds(p)
|
|
34
|
+
|
|
35
|
+
PROJECT_CRS = p["spatial"]["project_crs"]
|
|
36
|
+
ANALYSIS_CRS = p["spatial"]["analysis_crs"]
|
|
37
|
+
CV_FOLDS = p["modeling"]["cv_folds"]
|
|
38
|
+
N_BACKGROUND = p["modeling"]["background_n"]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Workflow: analyze-community-structure
|
|
2
|
+
|
|
3
|
+
**Purpose:** Multivariate analysis of species community composition and diversity
|
|
4
|
+
**Skills:** ecological-data-foundation → biostatistics-workbench → community-ecology-ordination → model-validation-and-uncertainty → reproducible-ecology-pipeline
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Trigger
|
|
9
|
+
|
|
10
|
+
Invoke when the user wants to describe or compare species assemblages across sites, treatments, or gradients.
|
|
11
|
+
|
|
12
|
+
**Example prompts:**
|
|
13
|
+
- "Compare bird community composition between forest and pasture sites"
|
|
14
|
+
- "Ordinate plant communities along an elevational gradient"
|
|
15
|
+
- "Identify indicator species for each land use type"
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Steps
|
|
20
|
+
|
|
21
|
+
### Step 1 — ecological-data-foundation
|
|
22
|
+
- Validate species × site matrix (check species names, abundance values, site IDs)
|
|
23
|
+
- QA environmental metadata
|
|
24
|
+
- Output: `data_clean.csv`, `species_site_matrix.csv`
|
|
25
|
+
|
|
26
|
+
### Step 2 — biostatistics-workbench
|
|
27
|
+
- Test assumptions for parametric diversity comparisons (normality, homogeneity)
|
|
28
|
+
- Fit GLM/LMM for alpha diversity response to environmental gradients
|
|
29
|
+
- Output: `diversity_model_results.csv`, `assumption_diagnostics/`
|
|
30
|
+
|
|
31
|
+
### Step 3 — community-ecology-ordination
|
|
32
|
+
- Compute alpha diversity metrics (S, H', 1−D); rarefaction curves
|
|
33
|
+
- Compute beta diversity; partition into turnover and nestedness
|
|
34
|
+
- Run NMDS ordination; report stress
|
|
35
|
+
- PERMANOVA + PERMDISP for group comparisons
|
|
36
|
+
- SIMPER for species contributions
|
|
37
|
+
- Hierarchical clustering
|
|
38
|
+
- Output: `ordination_plot.png`, `diversity_metrics.csv`, `permanova_results.txt`
|
|
39
|
+
|
|
40
|
+
### Step 4 — model-validation-and-uncertainty
|
|
41
|
+
- Assess NMDS stress and convergence
|
|
42
|
+
- Validate PERMANOVA assumptions (PERMDISP)
|
|
43
|
+
- Report sensitivity to rare species inclusion/exclusion
|
|
44
|
+
- Output: `validation_report.md`
|
|
45
|
+
|
|
46
|
+
### Step 5 — reproducible-ecology-pipeline
|
|
47
|
+
- Document ordination parameters, seed, and dissimilarity metric
|
|
48
|
+
- Output: `parameter_manifest.yaml`, `decision_log.md`
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Expected Deliverables
|
|
53
|
+
|
|
54
|
+
- NMDS ordination biplot
|
|
55
|
+
- Alpha diversity summary per group
|
|
56
|
+
- PERMANOVA results table
|
|
57
|
+
- Indicator species list
|
|
58
|
+
- Cluster dendrogram
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Decision Points
|
|
63
|
+
|
|
64
|
+
| Condition | Diagnosis | Recommended Action |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| NMDS stress > 0.20 | Poor ordination fit in 2D | Increase to 3D; alternatively use PCoA (metric) or PCA after Hellinger transformation |
|
|
67
|
+
| PERMANOVA significant but R² < 0.05 | Statistically significant but ecologically trivial effect | Report R² (effect size) prominently alongside p-value; contextualise effect magnitude |
|
|
68
|
+
| Species with > 80% zeros in matrix dominating ordination | Rare species creating artefacts | Apply Hellinger transformation; remove singletons or use Bray-Curtis on untransformed data |
|
|
69
|
+
| Groups fully overlap in ordination space | Environmental gradient is weak or wrong variables tested | Test additional environmental covariates; check if grouping factor is ecologically meaningful |
|
|
70
|
+
| SIMPER output does not match ecological expectations | Potential data entry error or taxonomic issues | Verify species identity and abundance values; check for transposed rows/columns |
|
|
71
|
+
| PERMANOVA significant but PERMDISP also significant | Cannot distinguish composition vs. dispersion differences | Report both; use betadisper plot; consider within-group diversity analysis |
|
|
72
|
+
| Rarefaction curves not asymptoting | Insufficient sampling effort | Report sampling completeness (Chao1 completeness); caveat diversity comparisons |
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Workflow: analyze-environmental-change
|
|
2
|
+
|
|
3
|
+
**Purpose:** Detect and characterise long-term environmental change from remote sensing or monitoring data
|
|
4
|
+
**Skills:** ecological-data-foundation → geoprocessing-for-ecology → environmental-time-series → ecological-impact-assessment → reproducible-ecology-pipeline
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Trigger
|
|
9
|
+
|
|
10
|
+
Invoke when the user wants to analyse temporal trends in environmental conditions (NDVI, land cover, temperature, rainfall, deforestation) over years to decades.
|
|
11
|
+
|
|
12
|
+
**Example prompts:**
|
|
13
|
+
- "Analyse NDVI trends in the Pantanal over the last 20 years"
|
|
14
|
+
- "Detect breakpoints in forest cover loss in the Brazilian Amazon"
|
|
15
|
+
- "Characterise vegetation recovery after the 2019-2020 fires"
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Steps
|
|
20
|
+
|
|
21
|
+
### Step 1 — ecological-data-foundation
|
|
22
|
+
- Ingest time series data (satellite-derived or monitoring station)
|
|
23
|
+
- Validate temporal consistency, units, and metadata
|
|
24
|
+
- Output: `timeseries_clean.csv` or raster stack
|
|
25
|
+
|
|
26
|
+
### Step 2 — geoprocessing-for-ecology
|
|
27
|
+
- Reproject and align raster time stack
|
|
28
|
+
- Extract series for specific zones or polygons
|
|
29
|
+
- Create cloud-masked composites (if satellite data)
|
|
30
|
+
- Output: `timeseries_stack.tif`, `zone_extracts.csv`
|
|
31
|
+
|
|
32
|
+
### Step 3 — environmental-time-series
|
|
33
|
+
- STL decomposition (trend + seasonal + remainder)
|
|
34
|
+
- Mann-Kendall trend test + Sen's slope (pixel-wise or site-wise)
|
|
35
|
+
- BFAST breakpoint detection
|
|
36
|
+
- Standardised anomaly computation
|
|
37
|
+
- Recovery trajectory (if post-disturbance)
|
|
38
|
+
- Output: `trend_results.csv`, `breakpoints.csv`, `anomaly_series.csv`, `recovery_metrics.csv`
|
|
39
|
+
|
|
40
|
+
### Step 4 — ecological-impact-assessment
|
|
41
|
+
- Classify trend magnitude: significant improvement / stable / significant degradation
|
|
42
|
+
- Identify spatial hotspots of change
|
|
43
|
+
- Overlay with land cover, protected areas, and pressure layers
|
|
44
|
+
- Synthesise drivers of observed change
|
|
45
|
+
- Output: `change_classification.tif`, `impact_synthesis.md`
|
|
46
|
+
|
|
47
|
+
### Step 5 — reproducible-ecology-pipeline
|
|
48
|
+
- Document baseline period, decomposition parameters, breakpoint thresholds
|
|
49
|
+
- Output: `parameter_manifest.yaml`, `decision_log.md`
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Expected Deliverables
|
|
54
|
+
|
|
55
|
+
- Trend map (slope and significance per pixel)
|
|
56
|
+
- Breakpoint map (date and magnitude)
|
|
57
|
+
- Anomaly time series
|
|
58
|
+
- Change classification map
|
|
59
|
+
- Recovery metrics (if applicable)
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Decision Points
|
|
64
|
+
|
|
65
|
+
| Condition | Diagnosis | Recommended Action |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| Mann-Kendall tau < 0.1 despite visual trend | Trend masked by high inter-annual variance | Apply pre-whitening (remove autocorrelation before MK test); report Sen's slope with 95% CI instead of tau alone |
|
|
68
|
+
| BFAST detects > 5 breakpoints | Oversegmentation of time series | Increase `h` parameter (minimum segment length as fraction of series); inspect breakpoints for plausibility |
|
|
69
|
+
| Time series < 10 years | Insufficient length for reliable trend detection | Report descriptive statistics (mean, SD, range) only; state limitation; do not report Mann-Kendall as significant |
|
|
70
|
+
| Missing data > 20% in any season | Seasonal decomposition unreliable | Impute with STL or linear interpolation before decomposition; document imputation in methods |
|
|
71
|
+
| Breakpoint coincides with sensor change or data gap | Artefact, not ecological signal | Verify against independent data source (e.g., Landsat vs MODIS comparison); exclude artefact breakpoints |
|
|
72
|
+
| STL trend component shows oscillation at period equal to satellite revisit | Orbital artefact leaking into trend | Apply Fourier pre-filtering; use MODIS 16-day composites instead of 8-day |
|
|
73
|
+
| Recovery rate > 100% (NDVI exceeds pre-disturbance level) | Regrowth exceeds baseline; possible change in land use | Verify with high-resolution imagery; investigate if secondary vegetation is replacing degraded pasture |
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Workflow: assess-ecological-impact
|
|
2
|
+
|
|
3
|
+
**Purpose:** Quantify the ecological effect of a disturbance or land-use change
|
|
4
|
+
**Skills:** ecological-data-foundation → geoprocessing-for-ecology → ecological-impact-assessment → biostatistics-workbench → model-validation-and-uncertainty → reproducible-ecology-pipeline
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Trigger
|
|
9
|
+
|
|
10
|
+
Invoke when the user wants to evaluate the impact of a disturbance (deforestation, fire, infrastructure, agriculture) on ecological indicators.
|
|
11
|
+
|
|
12
|
+
**Example prompts:**
|
|
13
|
+
- "Assess the impact of the road construction on bird richness using BACI"
|
|
14
|
+
- "Quantify habitat loss and fragmentation from sugarcane expansion"
|
|
15
|
+
- "Evaluate the effect of the 2020 fire on forest carbon stocks"
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Steps
|
|
20
|
+
|
|
21
|
+
### Step 1 — ecological-data-foundation
|
|
22
|
+
- Validate ecological indicator data (species richness, abundance, biomass, NDVI)
|
|
23
|
+
- Confirm site-level metadata (control/impact designation, pre/post dates)
|
|
24
|
+
- Output: `data_clean.csv`, `qa_report.md`
|
|
25
|
+
|
|
26
|
+
### Step 2 — geoprocessing-for-ecology
|
|
27
|
+
- Clip land cover and pressure layers to study area
|
|
28
|
+
- Compute distance from disturbance for gradient analysis
|
|
29
|
+
- Extract spatial covariates at site locations
|
|
30
|
+
- Output: `points_with_env.csv`, `pressure_layers/`
|
|
31
|
+
|
|
32
|
+
### Step 3 — ecological-impact-assessment
|
|
33
|
+
- Run BACI mixed model
|
|
34
|
+
- Compute landscape fragmentation metrics (pre/post)
|
|
35
|
+
- Build composite pressure index
|
|
36
|
+
- Output: `baci_results.csv`, `fragmentation_metrics.csv`, `pressure_index.tif`
|
|
37
|
+
|
|
38
|
+
### Step 4 — biostatistics-workbench
|
|
39
|
+
- Validate BACI model assumptions (residual diagnostics)
|
|
40
|
+
- Compute effect sizes and CIs for the BACI interaction
|
|
41
|
+
- Perform post-hoc tests if multiple indicators
|
|
42
|
+
- Output: `assumption_diagnostics/`, `effect_sizes.csv`
|
|
43
|
+
|
|
44
|
+
### Step 5 — model-validation-and-uncertainty
|
|
45
|
+
- Report performance of BACI model (R², calibration)
|
|
46
|
+
- Assess sensitivity to control site selection
|
|
47
|
+
- Output: `validation_report.md`, `sensitivity_report.md`
|
|
48
|
+
|
|
49
|
+
### Step 6 — reproducible-ecology-pipeline
|
|
50
|
+
- Log all decisions and parameters
|
|
51
|
+
- Complete reproducibility checklist
|
|
52
|
+
- Output: `parameter_manifest.yaml`, `decision_log.md`
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Expected Deliverables
|
|
57
|
+
|
|
58
|
+
- BACI interaction estimate with 95% CI
|
|
59
|
+
- Landscape fragmentation change metrics
|
|
60
|
+
- Pressure map
|
|
61
|
+
- Impact classification (none / minor / moderate / major / critical)
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Decision Points
|
|
66
|
+
|
|
67
|
+
| Condition | Diagnosis | Recommended Action |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| PERMDISP significant beyond PERMANOVA | Difference in group dispersion, not just centroid | Report both tests; do not interpret PERMANOVA alone as evidence of composition difference |
|
|
70
|
+
| BACI interaction p > 0.10 | Effect not detected at current statistical power | Calculate post-hoc power; recommend minimum additional n in report |
|
|
71
|
+
| Pseudo-replication detected (sites not independent) | Type I error inflation | Use random effects (LMM/GLMM) or aggregate to independent units |
|
|
72
|
+
| Pre-impact period < 2 years | Insufficient baseline for trend estimation | Flag limitation explicitly; conduct sensitivity analysis with different baseline lengths |
|
|
73
|
+
| Control sites show same trend as impact sites pre-impact | BACI parallel-trend assumption violated | Use synthetic control, difference-in-differences with covariate adjustment, or interrupted time series instead |
|
|
74
|
+
| Effect size very small but p < 0.05 | Statistically significant but ecologically negligible | Report effect size (Cohen's d or partial η²) alongside p; contextualise against minimum ecologically meaningful difference |
|
|
75
|
+
| BACI model fails to converge | Model too complex for available data | Reduce random effects structure; use simpler fixed-effects ANOVA-style BACI if n per group is small |
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Workflow: assess-ecosystem-services
|
|
2
|
+
|
|
3
|
+
**Purpose:** Quantify and map ecosystem services across a landscape
|
|
4
|
+
**Skills:** ecological-data-foundation → geoprocessing-for-ecology → ecosystem-services-assessment → biostatistics-workbench → reproducible-ecology-pipeline
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Trigger
|
|
9
|
+
|
|
10
|
+
Invoke when the user wants to quantify, map, or compare ecosystem services across a study area.
|
|
11
|
+
|
|
12
|
+
**Example prompts:**
|
|
13
|
+
- "Map carbon storage, water regulation, and erosion control for the Atlantic Forest"
|
|
14
|
+
- "Assess trade-offs between timber production and carbon sequestration in [region]"
|
|
15
|
+
- "Quantify ecosystem service co-benefits of restoring [X ha] of native vegetation"
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Steps
|
|
20
|
+
|
|
21
|
+
### Step 1 — ecological-data-foundation
|
|
22
|
+
- Ingest land cover map, biomass data, soil data, and DEM
|
|
23
|
+
- Validate attribute tables and temporal alignment
|
|
24
|
+
- Output: `landcover_validated.tif`, `qa_report.md`
|
|
25
|
+
|
|
26
|
+
### Step 2 — geoprocessing-for-ecology
|
|
27
|
+
- Reproject and align all input layers to common CRS and resolution
|
|
28
|
+
- Clip to study area; compute watershed delineation if needed
|
|
29
|
+
- Output: `inputs_aligned/`, `watershed.gpkg`
|
|
30
|
+
|
|
31
|
+
### Step 3 — ecosystem-services-assessment
|
|
32
|
+
- Select ES portfolio relevant to the study context
|
|
33
|
+
- Compute biophysical indicators per service
|
|
34
|
+
- Aggregate by land cover class
|
|
35
|
+
- Run trade-off analysis (pairwise correlations)
|
|
36
|
+
- Output: `es_indicator_maps/`, `es_summary_table.csv`, `tradeoff_matrix.csv`
|
|
37
|
+
|
|
38
|
+
### Step 4 — biostatistics-workbench
|
|
39
|
+
- Test for significant differences in ES values between land cover classes
|
|
40
|
+
- Report effect sizes for pairwise comparisons
|
|
41
|
+
- Output: `es_stats_results.csv`, `effect_sizes.csv`
|
|
42
|
+
|
|
43
|
+
### Step 5 — reproducible-ecology-pipeline
|
|
44
|
+
- Document ES method choices and parameter sources
|
|
45
|
+
- Output: `parameter_manifest.yaml`, `es_report.md`
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Expected Deliverables
|
|
50
|
+
|
|
51
|
+
- ES indicator maps (one per service)
|
|
52
|
+
- ES summary table by land cover class
|
|
53
|
+
- Trade-off matrix and visualisation
|
|
54
|
+
- Statistical comparison of ES across classes
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Decision Points
|
|
59
|
+
|
|
60
|
+
| Condition | Diagnosis | Recommended Action |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| Land cover classification accuracy < 85% | Propagated classification error in ES estimates | Conduct uncertainty analysis using accuracy matrix; report ES ranges, not point estimates |
|
|
63
|
+
| ES trade-off correlation > 0.8 between two services | Possible confounding by same land cover class driving both | Partial out land cover effect; test whether trade-off holds within land cover classes |
|
|
64
|
+
| InVEST model output contains NoData in > 30% of area | Input layer misalignment (CRS, extent, or resolution mismatch) | Recheck CRS and extent of all inputs; use `terra::compareGeom()` to verify alignment |
|
|
65
|
+
| Monetary valuation requested but local market data unavailable | Benefit transfer required; high uncertainty | Apply benefit transfer with explicit unit value uncertainty (±50% range); flag limitation prominently |
|
|
66
|
+
| Provisioning and regulating services conflict across scenarios | Synergy/trade-off analysis needed | Use Pareto frontier visualisation; do not rank services without considering trade-offs |
|
|
67
|
+
| ES values identical across all land cover classes | Model insensitive to land cover differences | Check if land cover classes are aggregated too broadly; inspect model parameters for land-cover-specific values |
|
|
68
|
+
| Water yield model shows negative values | Model misconfiguration or negative ET correction | Verify PET inputs and calibration; check if precipitation minus AET is negative in any pixel |
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Workflow: assess-landscape-connectivity
|
|
2
|
+
|
|
3
|
+
**Purpose:** Assess habitat connectivity for a focal species using resistance surfaces and graph-theoretic metrics
|
|
4
|
+
**Skills:** ecological-data-foundation → geoprocessing-for-ecology → landscape-connectivity → model-validation-and-uncertainty → reproducible-ecology-pipeline
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Trigger
|
|
9
|
+
|
|
10
|
+
Invoke when the user wants to evaluate landscape connectivity, identify wildlife corridors, rank habitat patches by importance, or detect connectivity pinchpoints.
|
|
11
|
+
|
|
12
|
+
**Example prompts:**
|
|
13
|
+
- "Assess connectivity for jaguars across the Mesoamerican Biological Corridor"
|
|
14
|
+
- "Build a resistance surface and identify corridor pinchpoints for [species]"
|
|
15
|
+
- "Rank habitat patches by connectivity importance using IIC and dPC"
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Steps
|
|
20
|
+
|
|
21
|
+
### Step 1 — ecological-data-foundation
|
|
22
|
+
- Validate habitat patch layer (polygon or raster)
|
|
23
|
+
- Verify land cover classification and reclassification table
|
|
24
|
+
- Check dispersal distance estimate (literature or telemetry-based)
|
|
25
|
+
- Output: `patches_clean.shp`, `landcover_validated.tif`, `dispersal_params.csv`
|
|
26
|
+
|
|
27
|
+
### Step 2 — geoprocessing-for-ecology
|
|
28
|
+
- Reproject all layers to equal-area CRS
|
|
29
|
+
- Clip land cover and ancillary layers (slope, roads, rivers) to study area
|
|
30
|
+
- Compute patch area, centroid coordinates, and pairwise Euclidean distances
|
|
31
|
+
- Output: `patches_projected.shp`, `landcover_clipped.tif`, `patch_distances.csv`
|
|
32
|
+
|
|
33
|
+
### Step 3 — landscape-connectivity
|
|
34
|
+
- Build resistance surface from land cover reclassification (+ optional slope, road proximity)
|
|
35
|
+
- Compute pairwise least-cost distances between patches
|
|
36
|
+
- Calculate graph-theoretic metrics: IIC, PC, dIIC, dPC, betweenness centrality
|
|
37
|
+
- Rank patches by contribution to overall connectivity
|
|
38
|
+
- Run Circuitscape (if available) for current flow and pinchpoint detection
|
|
39
|
+
- Output: `resistance_surface.tif`, `connectivity_metrics.csv`, `patch_importance.csv`, `pinchpoint_map.tif`
|
|
40
|
+
|
|
41
|
+
### Step 4 — model-validation-and-uncertainty
|
|
42
|
+
- Sensitivity analysis: vary resistance values +/- 50% for top 3 land cover classes
|
|
43
|
+
- Compare patch rankings across resistance scenarios
|
|
44
|
+
- Assess sensitivity to dispersal distance threshold
|
|
45
|
+
- Output: `sensitivity_report.md`, `scenario_comparison.csv`
|
|
46
|
+
|
|
47
|
+
### Step 5 — reproducible-ecology-pipeline
|
|
48
|
+
- Document resistance value sources and justification
|
|
49
|
+
- Log dispersal distance estimate and source
|
|
50
|
+
- Record Circuitscape parameters and software versions
|
|
51
|
+
- Output: `parameter_manifest.yaml`, `decision_log.md`, `reproducibility_checklist.md`
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Expected Deliverables
|
|
56
|
+
|
|
57
|
+
- Resistance surface map
|
|
58
|
+
- Patch importance ranking (IIC, dPC, betweenness)
|
|
59
|
+
- Connectivity graph visualisation
|
|
60
|
+
- Pinchpoint map (current flow)
|
|
61
|
+
- Sensitivity analysis across resistance scenarios
|
|
62
|
+
- Reproducibility package
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Minimum Data Requirements
|
|
67
|
+
|
|
68
|
+
- Habitat patch layer with >= 5 patches
|
|
69
|
+
- Land cover raster covering study area
|
|
70
|
+
- Resistance reclassification table (land cover class -> resistance value)
|
|
71
|
+
- Dispersal distance estimate for focal species (meters)
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Decision Points
|
|
76
|
+
|
|
77
|
+
| Condition | Diagnosis | Recommended Action |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| IIC or PC = 0 | All patches are isolated beyond dispersal threshold | Increase dispersal threshold or verify it against telemetry data; report fragmentation severity |
|
|
80
|
+
| Single patch dominates dPC (> 80%) | Connectivity depends on one critical patch | Flag as conservation priority; run removal scenario to quantify impact |
|
|
81
|
+
| Resistance values lack empirical basis | Expert opinion only, no telemetry validation | Report as expert-based; run sensitivity analysis across plausible ranges |
|
|
82
|
+
| Circuitscape fails to converge | Grid too large or resistance contrast too high | Reduce resolution or aggregate land cover classes; check for zero-resistance barriers |
|
|
83
|
+
| Patch ranking changes > 30% across scenarios | High sensitivity to resistance parameterisation | Report full scenario range; do not present single-scenario ranking as definitive |
|
|
84
|
+
| Dispersal distance estimate varies > 2x in literature | Uncertain movement capacity | Run analysis at low, medium, and high estimates; report range of connectivity outcomes |
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Workflow: build-fire-risk-map
|
|
2
|
+
|
|
3
|
+
**Purpose:** Produce a spatial fire risk map integrating historical fire data, vegetation, climate, and terrain
|
|
4
|
+
**Skills:** ecological-data-foundation → geoprocessing-for-ecology → environmental-time-series → predictive-modeling-best-practices → model-validation-and-uncertainty → ecological-impact-assessment
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Trigger
|
|
9
|
+
|
|
10
|
+
Invoke when the user wants to map fire risk or fire susceptibility for a landscape.
|
|
11
|
+
|
|
12
|
+
**Example prompts:**
|
|
13
|
+
- "Build a fire risk map for the Cerrado"
|
|
14
|
+
- "Map fire susceptibility integrating NDVI trends, rainfall anomalies, and land use"
|
|
15
|
+
- "Predict which areas are most likely to burn in the next dry season"
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Steps
|
|
20
|
+
|
|
21
|
+
### Step 1 — ecological-data-foundation
|
|
22
|
+
- Ingest fire occurrence data (INPE BDQueimadas, MODIS burned area, VIIRS)
|
|
23
|
+
- Validate dates, coordinates, and confidence levels
|
|
24
|
+
- Filter to high-confidence fire pixels
|
|
25
|
+
- Output: `fire_records_clean.csv`, `qa_report.md`
|
|
26
|
+
|
|
27
|
+
### Step 2 — geoprocessing-for-ecology
|
|
28
|
+
- Reproject all layers to project CRS (UTM)
|
|
29
|
+
- Align terrain (DEM, slope, aspect), land cover, and climate rasters to common grid
|
|
30
|
+
- Compute distance to roads, edge density, and proximity to fire ignitions
|
|
31
|
+
- Output: `predictors_stack.tif`, `spatial_qa_report.md`
|
|
32
|
+
|
|
33
|
+
### Step 3 — environmental-time-series
|
|
34
|
+
- Compute NDVI trend and anomalies (vegetation dryness proxy)
|
|
35
|
+
- Compute rainfall SPI (drought index)
|
|
36
|
+
- Detect fire frequency per pixel from historical MODIS record
|
|
37
|
+
- Output: `ndvi_trend.tif`, `spi_anomaly.tif`, `fire_frequency.tif`
|
|
38
|
+
|
|
39
|
+
### Step 4 — predictive-modeling-best-practices
|
|
40
|
+
- Assess collinearity of all predictor candidates
|
|
41
|
+
- Define spatial CV strategy (buffered k-fold)
|
|
42
|
+
- Tune BRT and Random Forest hyperparameters
|
|
43
|
+
- Output: `cv_strategy.md`, `selected_predictors.txt`, `tuning_results.csv`
|
|
44
|
+
|
|
45
|
+
### Step 5 — model-validation-and-uncertainty
|
|
46
|
+
- Compute AUC-ROC, TSS, and Brier score on spatial CV folds
|
|
47
|
+
- Calibrate predicted probabilities
|
|
48
|
+
- Map ensemble uncertainty (SD across algorithms)
|
|
49
|
+
- Output: `performance_metrics.csv`, `fire_risk_uncertainty.tif`, `validation_report.md`
|
|
50
|
+
|
|
51
|
+
### Step 6 — ecological-impact-assessment
|
|
52
|
+
- Classify risk zones: low / moderate / high / very high
|
|
53
|
+
- Compute area and proportion in each risk class per land cover type
|
|
54
|
+
- Overlay with infrastructure and protected area boundaries
|
|
55
|
+
- Output: `fire_risk_map.tif`, `risk_by_landcover.csv`, `impact_synthesis.md`
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Expected Deliverables
|
|
60
|
+
|
|
61
|
+
- Continuous fire risk probability map
|
|
62
|
+
- Classified risk zone map (4 classes)
|
|
63
|
+
- Model performance table
|
|
64
|
+
- Risk summary by land cover class
|
|
65
|
+
- Uncertainty map
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Decision Points
|
|
70
|
+
|
|
71
|
+
| Condition | Diagnosis | Recommended Action |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| VIF > 10 among predictors | Severe multicollinearity | Remove the redundant layer with highest VIF; recalculate VIF after each removal |
|
|
74
|
+
| Fire history data < 10 years | Insufficient temporal coverage for reliable frequency estimates | Flag in metadata; use longer MODIS record if available; weight recent years more heavily |
|
|
75
|
+
| Block CV AUC < 0.65 | Spatial autocorrelation inflating naive AUC; model has limited spatial transferability | Report block CV AUC as primary; investigate whether training area is too small |
|
|
76
|
+
| Risk map shows hotspots near data gaps | Edge effects or extrapolation artefacts at raster boundaries | Apply focal mean smoothing (3×3 or 5×5 window); mask no-data buffer zones |
|
|
77
|
+
| Temporal mismatch between predictor layers (different years) | Predictors reflect different time periods; potential confounding | Standardise all layers to same time period; document year of each layer in metadata |
|
|
78
|
+
| BRT and Random Forest disagree strongly in high-risk areas | Model uncertainty is high where it matters most | Report ensemble mean AND standard deviation; flag high-disagreement areas in maps |
|
|
79
|
+
| Fire risk map shows uniform high risk across entire area | Model underfits or predictors lack spatial contrast | Increase model complexity; check if predictors have sufficient spatial variation in study area |
|