Skip to content

michelle-meyou/Script_Pyrenees_Python

Repository files navigation

ANTICI'PYR — Pipeline SDM Pyrénées

Pipeline Python de modélisation de niche bioclimatique (SDM) pour les espèces endémiques pyrénéennes, migré depuis un script R monolithique et adapté à l'exécution parallèle puis HPC.

Python 3.12 License: MIT

Contexte

ANTICI'PYR étudie l'évolution de la niche bioclimatique de 59 espèces végétales endémiques des Pyrénées sous quatre scénarios de changement climatique (SSP 126/245/370/585), à quatre horizons temporels (2030/2050/2070/2090), à partir de 11 modèles climatiques globaux (GCM) CMIP6.

Ce dépôt est la traduction Python du script R original "Projecting spatiotemporal bioclimatic niche dynamics of endemic Pyrenean plant species under climate change: how many will we lose?" (N. Collette, S. Pinel, V. Delorme-Hinoux, J.A.M. Bertrand). La migration a été réalisée dans le cadre d'un stage (Master CHPS / Espace-Dev, UMR 228), avec pour objectif secondaire de faire passer le pipeline du séquentiel au parallèle puis au HPC (SLURM) sans changer la logique métier.

Pour chaque espèce, le pipeline enchaîne : acquisition des occurrences (GBIF + iNaturalist) → sélection de variables bioclimatiques → ajustement de 5 algorithmes SDM (GLM, GAM, RF, GBM, MaxEnt) avec validation croisée spatiale, répété sur n_loops itérations → filtrage par Boyce Index → ensemble médian → projections futures → post-traitement (cartes, courbes de réponse, surfaces favorables).

Architecture

Le pipeline est organisé en 8 modules sous src/ :

Module Rôle
utils.py Configuration (config.yaml), logger par espèce, résolution des chemins, timer
data_occurrences.py Téléchargement GBIF/iNaturalist, nettoyage, fusion des sources, carte des occurrences
data_environment.py Téléchargement/découpage WorldClim (actuel + futur), sélection de variables par corrélation
sdm_modeling.py Table de modélisation, blocs spatiaux, ajustement + grid-search des 5 algorithmes, orchestrateur run_sdm_for_species
sdm_metrics.py Métriques maison sans équivalent Python direct : favorabilité (Real et al. 2006), Boyce Index, seuil maxSSS, AUC-PR
ensemble.py Filtrage des modèles par Boyce Index, ensemble médian, résumé des métriques retenues
projections.py MESS (Multivariate Environmental Similarity Surface), surface favorable, projection sur les climats futurs
postprocessing.py Courbes de réponse, binarisation + surfaces favorables, PDF de projections

figures.py (figures multi-espèces agrégées, ex. hotspots, recouvrement spatial) est un squelette documenté mais non implémenté — prévu en fin de stage une fois toutes les espèces traitées.

Les écarts méthodologiques volontaires entre le R et le Python (AUC-PR, découpage spatial, importance des variables, mapping GAM) sont documentés dans docs/migration_notes.md.

Installation

git clone <url-du-depot>
cd Script_Pyrenees_Python

conda create -n anticipyr python=3.12
conda activate anticipyr

# Bibliothèques géospatiales : toujours via conda-forge (jamais pip seul)
conda install -c conda-forge geopandas rasterio shapely numpy pandas scipy \
    scikit-learn statsmodels matplotlib pyyaml requests

# Bibliothèques SDM spécifiques : via pip
pip install pygbif pyinaturalist pygam elapid joblib

# Vérification
python3 -c "import rasterio, geopandas, sklearn, pygam, elapid; print('OK')"

Données à placer avant le premier lancement (voir LISEZMOI.txt) :

  • data/polygon_PYRENEES.shp (+ .shx, .dbf, .prj, .cpg) — zone d'étude
  • data/ATLAS_OF_PYRENEAN_FLORA_-_ENDEMIC.xlsx
  • outputs/layers_cut_current_1km.tif et outputs/future_median_layers_1km/ si déjà disponibles (évite un téléchargement WorldClim de ~3,5 Go)

Exécution

Le pipeline s'exécute à trois échelles, sans changement de logique métier entre elles.

1. Une espèce (séquentiel)

python3 run_species.py "Ramonda myconi"
python3 run_species.py "Delphinium montanum" --config config/config.yaml

Unité de travail indivisible : occurrences → modélisation → ensemble → post-traitement. Gère SIGTERM proprement (arrêt entre étapes, pas de fichier partiel).

2. Plusieurs espèces (parallèle local)

python3 run_parallel.py                          # toutes les espèces (mode config)
python3 run_parallel.py --n_jobs 8                # 8 espèces en parallèle
python3 run_parallel.py --n_jobs 4 --subset 10    # 4 en parallèle, 10 premières
python3 run_parallel.py --species "Esp1,Esp2"     # espèces ciblées
python3 run_parallel.py --dry-run                 # afficher la liste sans lancer
python3 run_parallel.py --resume                  # reprendre après coupure
python3 run_parallel.py --lpt --force --species "Esp1,Esp2" --report rapport.md
Option Effet
--config FILE Chemin de config.yaml (défaut : config/config.yaml)
--n_jobs N Workers parallèles (défaut adaptatif : 8 sur Apple Silicon, nproc - 1 sinon)
--subset N Limiter aux N premières espèces
--species "A,B" Espèces ciblées, séparées par virgules
--force Recalculer les espèces ciblées même si déjà OK
--lpt Logger l'ordonnancement LPT (Longest Processing Time first)
--report FILE Générer un rapport Markdown avant/après
--dry-run Afficher la liste des espèces sans lancer
--resume Ignorer les espèces déjà traitées (status=OK)

Chaque espèce tourne dans un processus isolé (multiprocessing, contexte spawn), OMP/OPENBLAS/MKL/NUMEXPR_NUM_THREADS=1 pour éviter la sur-souscription.

3. Cluster HPC (SLURM, job array)

sbatch --array=1-59 run_slurm.sh                      # 59 espèces
sbatch --array=1-59%16 run_slurm.sh                    # 59 espèces, 16 simultanées max
sbatch --array=53 run_slurm.sh                         # une seule espèce
sbatch --array=1-2682 run_slurm.sh species_all.csv     # flore complète (CSV en argument)

Chaque tâche du job array traite une espèce indépendamment. Variables à définir dans l'environnement : PROJECT_DIR (chemin du dépôt cloné, obligatoire), CONDA_ENV (nom de l'environnement conda), CONFIG (chemin de config.yaml).

Performances

Analyse et optimisation détaillées dans rapport/Rapport_Stage_M1chps_Michelle_Meyou.pdf.

Réduction de la grille GBM. Le grid-search GBM représentait ~80 % du temps de calcul par loop (18 min sur 27). La grille exhaustive (3 valeurs × 5 hyperparamètres = 243 combinaisons) a été réduite à 2 valeurs par paramètre (bornes extrêmes uniquement), soit 32 combinaisons — un gain de ×5 sur le temps GBM (18 min → 3 min 51 s par loop), pour un impact négligeable sur le score de performance (< 0,005).

Ordonnancement parallèle. Sur la base des temps mesurés sur des espèces de validation (de 15 à 985 occurrences), une simulation d'ordonnancement sur les 59 espèces endémiques avec tri par coût décroissant (nombre d'occurrences) et distribution dynamique (imap_unordered) donne, sur 8 cœurs :

Métrique Valeur
Temps séquentiel total 75 h
Temps parallèle (8 cœurs) 9,7 h
Speedup ×7,7 (maximum théorique : ×8)
Efficacité 96 %
Écart de charge max/min < 10 %

Un run réel des 59 espèces ((Intel® Core™ i9-10900, 10 cœurs physiques, 20 threads, Ubuntu Linux),8 workers) a confirmé cet ordre de grandeur : ~10-11 h, 55/59 espèces OK au premier passage, les 4 échecs restants (rate-limit GBIF, taxon key GBIF trop large) corrigés en session suivante pour atteindre 59/59 (voir docs/RAPPORT_FIX.md).

Reproductibilité

  • Seed fixée : modeling.seed (config.yaml, valeur 123) propagée à la génération des pseudo-absences (seed + loop_index), à l'assignation des blocs spatiaux et aux algorithmes stochastiques (Random Forest, GBM). La variabilité inter-loops provient uniquement du tirage des pseudo-absences.
  • Idempotence : une loop est ignorée si ses 5 modèles .pkl existent déjà ; les rasters coûteux (WorldClim actuel/futur, élévation) sont réutilisés s'ils sont déjà présents dans outputs/. Aucun recalcul inutile en cas de relance.
  • Reprise après coupure : les agrégats CSV (raw_evaluation_all_loop.csv, parameters_best_model_all_loop.csv, variable_importance_all_loop.csv) sont réécrits après chaque loop, pas seulement en fin de run. run_parallel.py --resume relit pipeline_results.csv et ne retraite que les espèces qui ne sont pas encore OK. run_species.py intercepte SIGTERM pour s'arrêter proprement entre deux étapes plutôt qu'en cours d'écriture.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages