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,331 @@
|
|
|
1
|
+
# Global Predictor Sources for Ecological Modelling
|
|
2
|
+
|
|
3
|
+
Reference guide for downloading environmental predictor layers used in Species Distribution Models (SDMs) and other ecological analyses. Each source includes access method, spatial resolution, temporal coverage, and recommended use cases.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Summary Table
|
|
8
|
+
|
|
9
|
+
| Dataset | Type | Resolution | Coverage | Access | SDM Use |
|
|
10
|
+
|---------|------|-----------|----------|--------|---------|
|
|
11
|
+
| WorldClim v2.1 | Climate | 30s–10m | Global | Free | Bioclimatic variables (19 BIO) |
|
|
12
|
+
| CHELSA v2.1 | Climate | 30s | Global | Free | High-res bioclimatic variables |
|
|
13
|
+
| TerraClimate | Climate | ~4km | Global | Free | Monthly climate + water balance |
|
|
14
|
+
| ERA5-Land | Climate | ~9km | Global | Free (CDS) | Hourly/monthly reanalysis |
|
|
15
|
+
| MODIS | Remote sensing | 250m–1km | Global | Free (NASA) | NDVI, land cover, LST |
|
|
16
|
+
| Copernicus LC | Land cover | 100m | Global | Free | Land use / land cover |
|
|
17
|
+
| SoilGrids v2 | Soil | 250m | Global | Free | Soil properties (pH, SOC, clay) |
|
|
18
|
+
| MERIT DEM | Topography | ~90m | Global | Free | Elevation, slope, aspect |
|
|
19
|
+
| HydroSHEDS | Hydrology | 90m | Global | Free | River networks, catchments |
|
|
20
|
+
| GFW | Forest cover | 30m | Global | Free | Hansen tree cover change |
|
|
21
|
+
| ESA CCI LC | Land cover | 300m | Global | Free | Annual land cover 1992–2020 |
|
|
22
|
+
| Human Footprint | Anthropogenic | ~1km | Global | Free | Human pressure index |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## WorldClim v2.1
|
|
27
|
+
|
|
28
|
+
**URL**: https://worldclim.org/data/worldclim21.html
|
|
29
|
+
**DOI**: https://doi.org/10.1002/joc.5086
|
|
30
|
+
**Type**: Bioclimatic variables derived from temperature and precipitation
|
|
31
|
+
**Resolution**: 30 arc-seconds (~1 km), 2.5, 5, 10 arc-minutes
|
|
32
|
+
**Temporal coverage**: 1970–2000 (current); future SSP scenarios (CMIP6)
|
|
33
|
+
**Format**: GeoTIFF (.tif)
|
|
34
|
+
|
|
35
|
+
### Download (R — geodata package)
|
|
36
|
+
```r
|
|
37
|
+
library(geodata)
|
|
38
|
+
# 19 bioclimatic variables, 2.5 arc-minute resolution
|
|
39
|
+
bio <- worldclim_global(var = "bio", res = 2.5, path = "data/predictors/worldclim")
|
|
40
|
+
# Single variable: tmin, tmax, prec, srad, wind, vapr
|
|
41
|
+
tmax <- worldclim_global(var = "tmax", res = 2.5, path = "data/predictors/worldclim")
|
|
42
|
+
# Future scenario (CMIP6)
|
|
43
|
+
bio_fut <- cmip6_world(model = "MPI-ESM1-2-HR", ssp = "585", time = "2061-2080",
|
|
44
|
+
var = "bioc", res = 2.5, path = "data/predictors/worldclim")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Download (Python — requests)
|
|
48
|
+
```python
|
|
49
|
+
import requests
|
|
50
|
+
from pathlib import Path
|
|
51
|
+
url = "https://biogeo.ucdavis.edu/data/worldclim/v2.1/base/wc2.1_2.5m_bio.zip"
|
|
52
|
+
Path("data/predictors/worldclim").mkdir(parents=True, exist_ok=True)
|
|
53
|
+
r = requests.get(url, stream=True, timeout=300)
|
|
54
|
+
with open("data/predictors/worldclim/wc2.1_2.5m_bio.zip", "wb") as f:
|
|
55
|
+
for chunk in r.iter_content(chunk_size=65536):
|
|
56
|
+
f.write(chunk)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**SDM guidance**: Use all 19 BIO variables, then apply collinearity screening (|r| > 0.7) to select non-redundant predictors. BIO1, BIO4, BIO12, BIO15 are often retained.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## CHELSA v2.1
|
|
64
|
+
|
|
65
|
+
**URL**: https://chelsa-climate.org/
|
|
66
|
+
**DOI**: https://doi.org/10.1038/s41597-021-01084-7
|
|
67
|
+
**Type**: High-resolution bioclimatic variables (superior to WorldClim in complex terrain)
|
|
68
|
+
**Resolution**: 30 arc-seconds (~1 km)
|
|
69
|
+
**Temporal coverage**: 1981–2010 (current); CMIP6 future scenarios
|
|
70
|
+
**Format**: NetCDF / GeoTIFF
|
|
71
|
+
|
|
72
|
+
### Download (R — direct URL)
|
|
73
|
+
```r
|
|
74
|
+
library(terra)
|
|
75
|
+
# CHELSA BIO1 (mean annual temperature)
|
|
76
|
+
url_bio1 <- "https://os.zhdk.cloud.switch.ch/envicloud/chelsa/chelsa_V2/GLOBAL/climatologies/1981-2010/bio/CHELSA_bio1_1981-2010_V.2.1.tif"
|
|
77
|
+
dir.create("data/predictors/chelsa", recursive = TRUE, showWarnings = FALSE)
|
|
78
|
+
download.file(url_bio1, destfile = "data/predictors/chelsa/CHELSA_bio1.tif",
|
|
79
|
+
mode = "wb", quiet = FALSE)
|
|
80
|
+
r <- terra::rast("data/predictors/chelsa/CHELSA_bio1.tif")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Download (Python)
|
|
84
|
+
```python
|
|
85
|
+
import requests
|
|
86
|
+
from pathlib import Path
|
|
87
|
+
base = "https://os.zhdk.cloud.switch.ch/envicloud/chelsa/chelsa_V2/GLOBAL/climatologies/1981-2010/bio"
|
|
88
|
+
out = Path("data/predictors/chelsa")
|
|
89
|
+
out.mkdir(parents=True, exist_ok=True)
|
|
90
|
+
for i in range(1, 20):
|
|
91
|
+
fname = f"CHELSA_bio{i}_1981-2010_V.2.1.tif"
|
|
92
|
+
r = requests.get(f"{base}/{fname}", stream=True, timeout=600)
|
|
93
|
+
r.raise_for_status()
|
|
94
|
+
(out / f"CHELSA_bio{i}.tif").write_bytes(r.content)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**SDM guidance**: Prefer CHELSA over WorldClim in mountains, coastal areas, and tropical regions where topographic correction matters. CHELSA and WorldClim BIO variables are on the same scale and can substitute directly.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## TerraClimate
|
|
102
|
+
|
|
103
|
+
**URL**: https://www.climatologylab.org/terraclimate.html
|
|
104
|
+
**DOI**: https://doi.org/10.1038/sdata.2017.191
|
|
105
|
+
**Type**: Monthly climate and water balance (1958–present)
|
|
106
|
+
**Resolution**: ~4 km (1/24 degree)
|
|
107
|
+
**Format**: NetCDF
|
|
108
|
+
|
|
109
|
+
### Download (R)
|
|
110
|
+
```r
|
|
111
|
+
library(terra)
|
|
112
|
+
# Download monthly PDSI (Palmer Drought Severity Index), 2010
|
|
113
|
+
url <- "https://climate.northwestknowledge.net/TERRACLIMATE-DATA/TerraClimate_PDSI_2010.nc"
|
|
114
|
+
download.file(url, "data/predictors/terraclimate_PDSI_2010.nc", mode = "wb")
|
|
115
|
+
r <- terra::rast("data/predictors/terraclimate_PDSI_2010.nc")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Variables**: ppt (precip), tmax, tmin, aet, def, pdsi, pet, q, soil, srad, swe, vap, vpd, ws
|
|
119
|
+
**SDM guidance**: Useful for water-balance related species responses. Combine with WorldClim for multi-temporal analyses.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## ERA5-Land (Copernicus CDS)
|
|
124
|
+
|
|
125
|
+
**URL**: https://cds.climate.copernicus.eu/datasets/reanalysis-era5-land
|
|
126
|
+
**DOI**: https://doi.org/10.24381/cds.68d2bb30
|
|
127
|
+
**Type**: Monthly/hourly land surface reanalysis
|
|
128
|
+
**Resolution**: ~9 km (0.1 degree)
|
|
129
|
+
**Temporal coverage**: 1950–present
|
|
130
|
+
**Format**: NetCDF / GRIB
|
|
131
|
+
|
|
132
|
+
### Download (Python — cdsapi)
|
|
133
|
+
```python
|
|
134
|
+
import cdsapi
|
|
135
|
+
c = cdsapi.Client() # requires ~/.cdsapirc with key
|
|
136
|
+
c.retrieve(
|
|
137
|
+
"reanalysis-era5-land-monthly-means",
|
|
138
|
+
{
|
|
139
|
+
"variable": ["2m_temperature", "total_precipitation"],
|
|
140
|
+
"product_type": "monthly_averaged_reanalysis",
|
|
141
|
+
"year": [str(y) for y in range(1990, 2021)],
|
|
142
|
+
"month": [f"{m:02d}" for m in range(1, 13)],
|
|
143
|
+
"time": "00:00",
|
|
144
|
+
"format": "netcdf",
|
|
145
|
+
},
|
|
146
|
+
"data/predictors/era5_land_temp_precip.nc"
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**SDM guidance**: Best for recent time periods and when high temporal resolution is needed. Requires free Copernicus CDS account and cdsapi configuration.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## MODIS (NASA)
|
|
155
|
+
|
|
156
|
+
**URL**: https://lpdaac.usgs.gov/
|
|
157
|
+
**Type**: Remote sensing products (NDVI, EVI, land cover, LST, etc.)
|
|
158
|
+
**Resolution**: 250 m (NDVI/EVI), 500 m, 1 km (LST, land cover)
|
|
159
|
+
**Temporal coverage**: 2000–present (16-day composites)
|
|
160
|
+
**Format**: HDF / GeoTIFF
|
|
161
|
+
|
|
162
|
+
### Download (R — MODIStsp / terra)
|
|
163
|
+
```r
|
|
164
|
+
# MODIStsp for bulk MODIS download (requires NASA EarthData account)
|
|
165
|
+
# library(MODIStsp)
|
|
166
|
+
# MODIStsp() # interactive GUI
|
|
167
|
+
|
|
168
|
+
# Alternative: direct download via APPEEARS or terra/STAC
|
|
169
|
+
library(terra)
|
|
170
|
+
# MODIS NDVI via STAC (Microsoft Planetary Computer)
|
|
171
|
+
# See: https://planetarycomputer.microsoft.com/dataset/modis-13A1-061
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Download (Python — pystac)
|
|
175
|
+
```python
|
|
176
|
+
import planetary_computer
|
|
177
|
+
import pystac_client
|
|
178
|
+
import stackstac
|
|
179
|
+
catalog = pystac_client.Client.open(
|
|
180
|
+
"https://planetarycomputer.microsoft.com/api/stac/v1",
|
|
181
|
+
modifier=planetary_computer.sign_inplace,
|
|
182
|
+
)
|
|
183
|
+
items = catalog.search(
|
|
184
|
+
collections=["modis-13A1-061"], # NDVI 500m 16-day
|
|
185
|
+
bbox=[-80, -15, -34, 5],
|
|
186
|
+
datetime="2020-01-01/2020-12-31",
|
|
187
|
+
).item_collection()
|
|
188
|
+
stack = stackstac.stack(items, assets=["500m_16_days_NDVI"])
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**SDM guidance**: NDVI as a proxy for vegetation productivity. Use annual maximum NDVI or seasonal composites. Apply cloud-masking (QA layers) before use.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Copernicus Global Land Cover
|
|
196
|
+
|
|
197
|
+
**URL**: https://lcviewer.vito.be/2019
|
|
198
|
+
**DOI**: https://doi.org/10.3390/rs12061044
|
|
199
|
+
**Type**: Annual global land cover
|
|
200
|
+
**Resolution**: 100 m
|
|
201
|
+
**Temporal coverage**: 2015–2019
|
|
202
|
+
**Format**: GeoTIFF
|
|
203
|
+
|
|
204
|
+
### Download (Python)
|
|
205
|
+
```python
|
|
206
|
+
# Available via Copernicus Land Service: https://land.copernicus.eu/global/products/lc
|
|
207
|
+
# Access requires free account; download per tile (20°x20°)
|
|
208
|
+
# Fractional cover layers: forest, shrub, grassland, cropland, urban, bare, water, permanent snow
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**SDM guidance**: Use fractional cover layers (0–100%) as continuous predictors rather than discrete class rasters. This retains more variation and improves model performance.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## SoilGrids v2.0
|
|
216
|
+
|
|
217
|
+
**URL**: https://soilgrids.org/
|
|
218
|
+
**DOI**: https://doi.org/10.1371/journal.pone.0169748
|
|
219
|
+
**Type**: Global soil property predictions at 6 standard depths
|
|
220
|
+
**Resolution**: 250 m
|
|
221
|
+
**Format**: GeoTIFF (Cloud-Optimised GeoTIFF via WCS/STAC)
|
|
222
|
+
|
|
223
|
+
### Download (R — terra + WCS)
|
|
224
|
+
```r
|
|
225
|
+
library(terra)
|
|
226
|
+
# pH at 0-5 cm depth (mean)
|
|
227
|
+
url_ph <- "https://maps.isric.org/mapserv?map=/map/phh2o.map&SERVICE=WCS&VERSION=2.0.1&REQUEST=GetCoverage&COVERAGEID=phh2o_0-5cm_mean&FORMAT=image/tiff&SUBSET=X(-8237000,-7196000)&SUBSET=Y(-1308000,-40000)&SUBSETTINGCRS=http://www.opengis.net/def/crs/EPSG/0/152160"
|
|
228
|
+
download.file(url_ph, "data/predictors/soilgrids_ph_0-5cm.tif", mode = "wb")
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Variables**: clay, sand, silt content; soil organic carbon (SOC); pH (H₂O); bulk density; cation exchange capacity (CEC); available water content
|
|
232
|
+
**Depths**: 0–5, 5–15, 15–30, 30–60, 60–100, 100–200 cm
|
|
233
|
+
**SDM guidance**: Use surface horizon (0–5 cm) for most terrestrial SDMs. SOC and pH are the most ecologically meaningful for plant and invertebrate distributions.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## MERIT DEM
|
|
238
|
+
|
|
239
|
+
**URL**: http://hydro.iis.u-tokyo.ac.jp/~yamadai/MERIT_DEM/
|
|
240
|
+
**DOI**: https://doi.org/10.1029/2017WR021187
|
|
241
|
+
**Type**: Multi-Error-Removed Improved-Terrain DEM
|
|
242
|
+
**Resolution**: 3 arc-seconds (~90 m)
|
|
243
|
+
**Format**: GeoTIFF
|
|
244
|
+
|
|
245
|
+
### Derived topographic variables (R)
|
|
246
|
+
```r
|
|
247
|
+
library(terra)
|
|
248
|
+
dem <- terra::rast("data/predictors/merit_dem.tif")
|
|
249
|
+
slope <- terra::terrain(dem, v = "slope", unit = "degrees")
|
|
250
|
+
aspect <- terra::terrain(dem, v = "aspect", unit = "degrees")
|
|
251
|
+
tpi <- terra::terrain(dem, v = "TPI") # Topographic Position Index
|
|
252
|
+
tri <- terra::terrain(dem, v = "TRI") # Terrain Ruggedness Index
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**SDM guidance**: Elevation, slope, and aspect are key predictors for montane species. Topographic wetness index (TWI) can be derived using the `RSAGA` or `whitebox` packages.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## HydroSHEDS
|
|
260
|
+
|
|
261
|
+
**URL**: https://www.hydrosheds.org/
|
|
262
|
+
**DOI**: https://doi.org/10.1002/hyp.9936
|
|
263
|
+
**Type**: Hydrological datasets derived from SRTM
|
|
264
|
+
**Resolution**: 90 m (river network), 3 arc-min (basins)
|
|
265
|
+
**Format**: GeoTIFF / Shapefile
|
|
266
|
+
|
|
267
|
+
**Layers**: flow accumulation, flow direction, river network, sub-basins, catchments
|
|
268
|
+
**SDM guidance**: Essential for freshwater species SDMs. Use flow accumulation as a proxy for river size, and sub-basin polygons for spatial blocks in cross-validation.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Global Forest Watch (Hansen)
|
|
273
|
+
|
|
274
|
+
**URL**: https://www.globalforestwatch.org/
|
|
275
|
+
**DOI**: https://doi.org/10.1126/science.1244693
|
|
276
|
+
**Type**: Annual forest cover change (2000–present)
|
|
277
|
+
**Resolution**: 30 m
|
|
278
|
+
**Format**: GeoTIFF (tiles)
|
|
279
|
+
|
|
280
|
+
### Download (R — gfwr or direct tiles)
|
|
281
|
+
```r
|
|
282
|
+
library(terra)
|
|
283
|
+
# Download canopy cover tile (e.g., 00N_070W)
|
|
284
|
+
url <- "https://storage.googleapis.com/earthenginepartners-hansen/GFC-2023-v1.11/Hansen_GFC-2023-v1.11_treecover2000_00N_070W.tif"
|
|
285
|
+
download.file(url, "data/predictors/hansen_treecover_00N_070W.tif", mode = "wb")
|
|
286
|
+
tc <- terra::rast("data/predictors/hansen_treecover_00N_070W.tif")
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**SDM guidance**: Use tree cover (%) as a continuous predictor. For change analyses, compute forest loss as cumulative annual loss to a given year. Threshold at 30% canopy cover for closed-canopy forest definition.
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## ESA CCI Land Cover
|
|
294
|
+
|
|
295
|
+
**URL**: https://climate.esa.int/en/projects/land-cover/
|
|
296
|
+
**DOI**: https://doi.org/10.1016/j.rse.2017.07.028
|
|
297
|
+
**Type**: Annual global land cover classification
|
|
298
|
+
**Resolution**: 300 m
|
|
299
|
+
**Temporal coverage**: 1992–2020
|
|
300
|
+
**Format**: NetCDF
|
|
301
|
+
|
|
302
|
+
**SDM guidance**: Use for long time-series land cover change analyses. Reclassify the 37-class legend to broader categories meaningful for the taxon group. Consider using temporal stack for detectability analyses.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Human Footprint Index
|
|
307
|
+
|
|
308
|
+
**URL**: https://wcshumanfootprint.org/
|
|
309
|
+
**DOI**: https://doi.org/10.1038/s41467-020-18509-4
|
|
310
|
+
**Type**: Cumulative human pressure index
|
|
311
|
+
**Resolution**: ~1 km
|
|
312
|
+
**Temporal coverage**: 2009, 2017
|
|
313
|
+
**Format**: GeoTIFF
|
|
314
|
+
|
|
315
|
+
**SDM guidance**: Strong predictor for threatened species with habitat sensitivity. Include in models for species with documented human disturbance responses. Standardise to [0,1] before use.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Notes for SDM Use
|
|
320
|
+
|
|
321
|
+
1. **Resolution matching**: Resample all layers to the same resolution (usually the coarsest) before stacking. Use bilinear interpolation for continuous variables, nearest-neighbour for categorical.
|
|
322
|
+
|
|
323
|
+
2. **Collinearity**: Always run collinearity screening before modelling. Remove one variable from each pair with |r| > 0.7 (Spearman). Prefer variables with stronger ecological justification.
|
|
324
|
+
|
|
325
|
+
3. **Extent**: Clip all layers to a consistent modelling extent before extraction. A buffer of 200–500 km around occurrence points is typical for regional SDMs.
|
|
326
|
+
|
|
327
|
+
4. **Projection**: Reproject to a geographic CRS (WGS84 / EPSG:4326) for SDM unless the study area is small and a projected CRS is more appropriate.
|
|
328
|
+
|
|
329
|
+
5. **Future projections**: Match the time period and SSP scenario of future climate layers to the same GCM used for baseline calibration. Use ensembles of ≥5 GCMs to quantify projection uncertainty.
|
|
330
|
+
|
|
331
|
+
6. **Citation**: Always cite the specific dataset version and access date. Most datasets use DOI-based citation.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Resampling Methods Reference
|
|
2
|
+
|
|
3
|
+
## Method Descriptions
|
|
4
|
+
|
|
5
|
+
### Nearest Neighbour (`near`)
|
|
6
|
+
- Assigns the value of the nearest source pixel
|
|
7
|
+
- **Use for:** Categorical data (land cover, soil type, administrative zones)
|
|
8
|
+
- **Avoid for:** Continuous data (creates blocky artefacts)
|
|
9
|
+
- GDAL flag: `-r near`
|
|
10
|
+
|
|
11
|
+
### Bilinear (`bilinear`)
|
|
12
|
+
- Weighted average of the 4 nearest source pixels
|
|
13
|
+
- **Use for:** Continuous data (elevation, temperature, precipitation, NDVI)
|
|
14
|
+
- Avoids blocky artefacts; slightly smooths the data
|
|
15
|
+
- GDAL flag: `-r bilinear`
|
|
16
|
+
|
|
17
|
+
### Cubic (`cubic`)
|
|
18
|
+
- Weighted average of the 16 nearest source pixels (bicubic spline)
|
|
19
|
+
- **Use for:** High-quality DEM processing, fine-resolution resampling
|
|
20
|
+
- Smoother than bilinear; may introduce slight ringing at edges
|
|
21
|
+
- GDAL flag: `-r cubic`
|
|
22
|
+
|
|
23
|
+
### Average (`average`)
|
|
24
|
+
- Average of all source pixels overlapping the target pixel
|
|
25
|
+
- **Use for:** Downsampling (coarsening resolution); preserves mean values
|
|
26
|
+
- GDAL flag: `-r average`
|
|
27
|
+
|
|
28
|
+
### Mode (`mode`)
|
|
29
|
+
- Most frequent value among source pixels
|
|
30
|
+
- **Use for:** Downsampling categorical data (land cover aggregation)
|
|
31
|
+
- GDAL flag: `-r mode`
|
|
32
|
+
|
|
33
|
+
### Sum (`sum`)
|
|
34
|
+
- Sum of all source pixels overlapping the target pixel
|
|
35
|
+
- **Use for:** Count data aggregation (fire frequency, species count per cell)
|
|
36
|
+
- GDAL flag: `-r sum`
|
|
37
|
+
|
|
38
|
+
## Decision Guide
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
Is the data categorical?
|
|
42
|
+
YES → Use: nearest (upsampling) | mode (downsampling)
|
|
43
|
+
NO → Is high spatial precision critical?
|
|
44
|
+
YES → Use: cubic
|
|
45
|
+
NO → Are you downsampling (coarsening)?
|
|
46
|
+
YES → Use: average
|
|
47
|
+
NO → Use: bilinear
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Common Mistakes
|
|
51
|
+
|
|
52
|
+
| Mistake | Consequence | Fix |
|
|
53
|
+
|---------|-------------|-----|
|
|
54
|
+
| Bilinear on land cover | Creates fractional class values | Use nearest |
|
|
55
|
+
| Nearest on elevation | Blocky DEM, poor slope/aspect | Use bilinear or cubic |
|
|
56
|
+
| No resampling specified | GDAL defaults to nearest | Always specify `-r` |
|
|
57
|
+
| Mixing resolutions in stack | Spatial misalignment | Resample all to common grid first |
|
package/skills/geoprocessing-for-ecology/scripts/__pycache__/download_predictors.cpython-311.pyc
ADDED
|
Binary file
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# ecological-agent-skills / Copyright (C) 2026 Francisco Diego Barros Barata
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
# Usage: Rscript download_predictors.R <output_dir> [resolution] [extent_wkt] [source]
|
|
5
|
+
|
|
6
|
+
# ── Inline logger ─────────────────────────────────────────────────────────────
|
|
7
|
+
SKILL_NAME <- "geoprocessing-for-ecology"
|
|
8
|
+
.log_ts <- function() format(Sys.time(), "[%Y-%m-%d %H:%M:%S]")
|
|
9
|
+
log_info <- function(...) message(.log_ts(), " [INFO] ", sprintf(...))
|
|
10
|
+
log_warn <- function(...) message(.log_ts(), " [WARN] ", sprintf(...))
|
|
11
|
+
log_error<- function(...) message(.log_ts(), " [ERROR] ", sprintf(...))
|
|
12
|
+
log_step <- function(n, d) log_info("-- STEP %d: %s", n, d)
|
|
13
|
+
log_decision <- function(v, val, why) log_info("DECISION | %s = %s | %s", v, val, why)
|
|
14
|
+
dir.create("logs", recursive=TRUE, showWarnings=FALSE)
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Arguments:
|
|
18
|
+
# output_dir : Directory to write predictor rasters (created if absent)
|
|
19
|
+
# resolution : WorldClim resolution: 2.5, 5, or 10 (arc-minutes, default: 2.5)
|
|
20
|
+
# extent_wkt : WKT bounding box to clip outputs — e.g., "POLYGON((-80 -30,-80 10,-30 10,-30 -30,-80 -30))"
|
|
21
|
+
# If not provided, global layers are saved without clipping.
|
|
22
|
+
# source : Comma-separated list of sources to download: worldclim,chelsa,modis
|
|
23
|
+
# Default: "worldclim"
|
|
24
|
+
#
|
|
25
|
+
# Outputs:
|
|
26
|
+
# output_dir/worldclim/wc2.1_{res}m_bio_{1..19}.tif — WorldClim bioclimatic variables
|
|
27
|
+
# output_dir/chelsa/CHELSA_bio{1..19}.tif — CHELSA bioclimatic variables
|
|
28
|
+
# output_dir/predictor_metadata.csv — layer provenance and checksums
|
|
29
|
+
#
|
|
30
|
+
# References:
|
|
31
|
+
# WorldClim: Fick & Hijmans (2017) doi:10.1002/joc.5086
|
|
32
|
+
# CHELSA: Karger et al. (2021) doi:10.1038/s41597-021-01084-7
|
|
33
|
+
|
|
34
|
+
suppressPackageStartupMessages(library(terra))
|
|
35
|
+
suppressPackageStartupMessages(library(geodata))
|
|
36
|
+
|
|
37
|
+
# ── 1. Parse arguments ───────────────────────────────────────────────────────
|
|
38
|
+
log_step(1, "Analisar argumentos da linha de comando")
|
|
39
|
+
args <- commandArgs(trailingOnly = TRUE)
|
|
40
|
+
|
|
41
|
+
if (length(args) < 1) {
|
|
42
|
+
output_dir <- "data/predictors"
|
|
43
|
+
resolution <- 2.5
|
|
44
|
+
extent_wkt <- NULL
|
|
45
|
+
sources <- "worldclim"
|
|
46
|
+
log_warn("Nenhum argumento fornecido. Usando valores padrao.")
|
|
47
|
+
} else {
|
|
48
|
+
output_dir <- args[1]
|
|
49
|
+
resolution <- if (length(args) >= 2) as.numeric(args[2]) else 2.5
|
|
50
|
+
extent_wkt <- if (length(args) >= 3 && args[3] != "") args[3] else NULL
|
|
51
|
+
sources <- if (length(args) >= 4) args[4] else "worldclim"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
sources_list <- trimws(strsplit(sources, ",")[[1]])
|
|
55
|
+
|
|
56
|
+
log_info("Script: download_predictors.R | Skill: %s", SKILL_NAME)
|
|
57
|
+
log_info("Output dir : %s", output_dir)
|
|
58
|
+
log_info("Resolution : %g arc-minutes", resolution)
|
|
59
|
+
log_info("Extent WKT : %s", ifelse(is.null(extent_wkt), "global (sem corte)", extent_wkt))
|
|
60
|
+
log_info("Sources : %s", paste(sources_list, collapse = ", "))
|
|
61
|
+
|
|
62
|
+
log_decision("resolution", resolution,
|
|
63
|
+
"2.5 arc-min (~4.5 km) e o equilibrio padrao entre detalhe e tamanho de arquivo")
|
|
64
|
+
|
|
65
|
+
if (!resolution %in% c(0.5, 2.5, 5, 10)) {
|
|
66
|
+
log_warn("Resolucao %g nao e um valor padrao do WorldClim (0.5, 2.5, 5, 10). Pode causar erro no download.", resolution)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# ── 2. Create output directory ───────────────────────────────────────────────
|
|
70
|
+
log_step(2, "Criar diretorio de saida")
|
|
71
|
+
dir.create(output_dir, recursive = TRUE, showWarnings = FALSE)
|
|
72
|
+
|
|
73
|
+
# ── 3. Parse extent ──────────────────────────────────────────────────────────
|
|
74
|
+
clip_extent <- NULL
|
|
75
|
+
if (!is.null(extent_wkt)) {
|
|
76
|
+
log_step(3, "Interpretar extensao WKT para corte de camadas")
|
|
77
|
+
tryCatch({
|
|
78
|
+
clip_extent <- terra::vect(extent_wkt, crs = "EPSG:4326")
|
|
79
|
+
log_info("Extensao de corte: %s", paste(as.vector(terra::ext(clip_extent)), collapse = ", "))
|
|
80
|
+
}, error = function(e) {
|
|
81
|
+
log_error(
|
|
82
|
+
"Falha ao interpretar extent_wkt: %s\nCausa provavel: WKT invalido.\nExemplo valido: POLYGON((-80 -30,-80 10,-30 10,-30 -30,-80 -30))\nSkill anterior: geoprocessing-for-ecology",
|
|
83
|
+
conditionMessage(e)
|
|
84
|
+
)
|
|
85
|
+
stop(e)
|
|
86
|
+
})
|
|
87
|
+
} else {
|
|
88
|
+
log_step(3, "Sem extensao de corte — camadas globais serao salvas integralmente")
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
# ── Helper: clip and save raster ─────────────────────────────────────────────
|
|
92
|
+
clip_and_save <- function(r, out_path, clip_ext) {
|
|
93
|
+
if (!is.null(clip_ext)) {
|
|
94
|
+
r <- tryCatch(
|
|
95
|
+
terra::crop(r, clip_ext),
|
|
96
|
+
error = function(e) {
|
|
97
|
+
log_warn("Falha ao cortar camada para extensao: %s. Salvando versao global.", conditionMessage(e))
|
|
98
|
+
r
|
|
99
|
+
}
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
dir.create(dirname(out_path), recursive = TRUE, showWarnings = FALSE)
|
|
103
|
+
terra::writeRaster(r, out_path, overwrite = TRUE)
|
|
104
|
+
log_info("Salvo: %s", out_path)
|
|
105
|
+
return(invisible(out_path))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# ── Helper: compute SHA256 checksum ──────────────────────────────────────────
|
|
109
|
+
sha256_file <- function(path) {
|
|
110
|
+
tryCatch({
|
|
111
|
+
digest::digest(file = path, algo = "sha256")
|
|
112
|
+
}, error = function(e) {
|
|
113
|
+
"N/A"
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
# ── Metadata accumulator ─────────────────────────────────────────────────────
|
|
118
|
+
meta_rows <- list()
|
|
119
|
+
|
|
120
|
+
# ── 4. Download WorldClim ────────────────────────────────────────────────────
|
|
121
|
+
if ("worldclim" %in% sources_list) {
|
|
122
|
+
log_step(4, "Baixar WorldClim v2.1 — variaveis bioclimaticas")
|
|
123
|
+
wc_dir <- file.path(output_dir, "worldclim")
|
|
124
|
+
dir.create(wc_dir, recursive = TRUE, showWarnings = FALSE)
|
|
125
|
+
|
|
126
|
+
log_decision("worldclim_var", "bio",
|
|
127
|
+
"19 variaveis bioclimaticas cobrem todos os aspectos de temperatura e precipitacao")
|
|
128
|
+
|
|
129
|
+
bio_stack <- tryCatch({
|
|
130
|
+
geodata::worldclim_global(var = "bio", res = resolution, path = wc_dir)
|
|
131
|
+
}, error = function(e) {
|
|
132
|
+
log_error(
|
|
133
|
+
"Falha ao baixar WorldClim: %s\nCausa provavel: sem conexao com a internet ou servidor WorldClim indisponivel.\nVerifique: https://worldclim.org/\nSkill anterior: geoprocessing-for-ecology",
|
|
134
|
+
conditionMessage(e)
|
|
135
|
+
)
|
|
136
|
+
stop(e)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
log_info("WorldClim baixado: %d camadas", terra::nlyr(bio_stack))
|
|
140
|
+
|
|
141
|
+
# Save individual BIO layers
|
|
142
|
+
for (i in seq_len(terra::nlyr(bio_stack))) {
|
|
143
|
+
layer_name <- paste0("BIO", i)
|
|
144
|
+
out_path <- file.path(wc_dir, sprintf("wc2.1_%gm_bio_%d.tif", resolution, i))
|
|
145
|
+
r <- bio_stack[[i]]
|
|
146
|
+
clip_and_save(r, out_path, clip_extent)
|
|
147
|
+
meta_rows[[length(meta_rows) + 1]] <- list(
|
|
148
|
+
source = "WorldClim_v2.1",
|
|
149
|
+
variable = layer_name,
|
|
150
|
+
resolution = paste0(resolution, " arc-min"),
|
|
151
|
+
file = out_path,
|
|
152
|
+
citation = "Fick & Hijmans (2017) doi:10.1002/joc.5086",
|
|
153
|
+
licence = "CC BY 4.0",
|
|
154
|
+
download_date = format(Sys.Date(), "%Y-%m-%d")
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
log_info("WorldClim: todos os 19 BIO salvo em %s", wc_dir)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
# ── 5. Download CHELSA ───────────────────────────────────────────────────────
|
|
161
|
+
if ("chelsa" %in% sources_list) {
|
|
162
|
+
log_step(5, "Baixar CHELSA v2.1 — variaveis bioclimaticas")
|
|
163
|
+
ch_dir <- file.path(output_dir, "chelsa")
|
|
164
|
+
dir.create(ch_dir, recursive = TRUE, showWarnings = FALSE)
|
|
165
|
+
|
|
166
|
+
chelsa_base <- "https://os.zhdk.cloud.switch.ch/envicloud/chelsa/chelsa_V2/GLOBAL/climatologies/1981-2010/bio"
|
|
167
|
+
|
|
168
|
+
for (i in 1:19) {
|
|
169
|
+
fname <- sprintf("CHELSA_bio%d_1981-2010_V.2.1.tif", i)
|
|
170
|
+
url <- paste0(chelsa_base, "/", fname)
|
|
171
|
+
out_path <- file.path(ch_dir, sprintf("CHELSA_bio%d.tif", i))
|
|
172
|
+
|
|
173
|
+
log_info("Baixando CHELSA BIO%d de: %s", i, url)
|
|
174
|
+
dl_ok <- tryCatch({
|
|
175
|
+
download.file(url, out_path, mode = "wb", quiet = TRUE)
|
|
176
|
+
TRUE
|
|
177
|
+
}, error = function(e) {
|
|
178
|
+
log_error(
|
|
179
|
+
"Falha ao baixar CHELSA BIO%d: %s\nCausa provavel: servidor CHELSA indisponivel ou sem conexao.\nVerifique: https://chelsa-climate.org/\nSkill anterior: geoprocessing-for-ecology",
|
|
180
|
+
i, conditionMessage(e)
|
|
181
|
+
)
|
|
182
|
+
FALSE
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
if (!dl_ok) next
|
|
186
|
+
|
|
187
|
+
# Apply clip if requested
|
|
188
|
+
if (!is.null(clip_extent)) {
|
|
189
|
+
tryCatch({
|
|
190
|
+
r <- terra::rast(out_path)
|
|
191
|
+
r <- terra::crop(r, clip_extent)
|
|
192
|
+
terra::writeRaster(r, out_path, overwrite = TRUE)
|
|
193
|
+
log_info("CHELSA BIO%d cortado para extensao de estudo.", i)
|
|
194
|
+
}, error = function(e) {
|
|
195
|
+
log_warn("Falha ao cortar CHELSA BIO%d: %s. Mantendo versao global.", i, conditionMessage(e))
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
log_info("CHELSA BIO%d salvo: %s", i, out_path)
|
|
200
|
+
meta_rows[[length(meta_rows) + 1]] <- list(
|
|
201
|
+
source = "CHELSA_v2.1",
|
|
202
|
+
variable = paste0("BIO", i),
|
|
203
|
+
resolution = "30 arc-sec (~1 km)",
|
|
204
|
+
file = out_path,
|
|
205
|
+
citation = "Karger et al. (2021) doi:10.1038/s41597-021-01084-7",
|
|
206
|
+
licence = "CC BY 4.0",
|
|
207
|
+
download_date = format(Sys.Date(), "%Y-%m-%d")
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
log_info("CHELSA: todos os 19 BIO processados em %s", ch_dir)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
# ── 6. MODIS placeholder ─────────────────────────────────────────────────────
|
|
214
|
+
if ("modis" %in% sources_list) {
|
|
215
|
+
log_step(6, "MODIS: download requer conta NASA EarthData (nao automatizado)")
|
|
216
|
+
log_warn(
|
|
217
|
+
"Download automatizado de MODIS requer conta em https://urs.earthdata.nasa.gov/\n Use MODIStsp (R) ou AppEEARS (https://appeears.earthdatacloud.nasa.gov/) para downloads em lote.\n Alternativa Python: pystac com Microsoft Planetary Computer (nao requer conta).\n Consulte: skills/geoprocessing-for-ecology/resources/global-predictor-sources.md"
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
# ── 7. Save predictor metadata CSV ──────────────────────────────────────────
|
|
222
|
+
log_step(7, "Gravar metadata de preditores")
|
|
223
|
+
if (length(meta_rows) > 0) {
|
|
224
|
+
meta_df <- do.call(rbind, lapply(meta_rows, as.data.frame, stringsAsFactors = FALSE))
|
|
225
|
+
meta_path <- file.path(output_dir, "predictor_metadata.csv")
|
|
226
|
+
tryCatch({
|
|
227
|
+
write.csv(meta_df, meta_path, row.names = FALSE)
|
|
228
|
+
log_info("Metadata gravado: %s (%d camadas)", meta_path, nrow(meta_df))
|
|
229
|
+
}, error = function(e) {
|
|
230
|
+
log_error(
|
|
231
|
+
"Falha ao gravar metadata: %s\nSkill anterior: geoprocessing-for-ecology",
|
|
232
|
+
conditionMessage(e)
|
|
233
|
+
)
|
|
234
|
+
})
|
|
235
|
+
} else {
|
|
236
|
+
log_warn("Nenhuma camada baixada com sucesso. Arquivo de metadata nao criado.")
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
log_info("Download de preditores concluido. Verifique: %s", output_dir)
|