Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion prepare_species/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
"full_habitat_code",
"scientific_name",
"family_name",
"order_name",
"class_name",
"phylum_name",
"kingdom_name",
"threats",
"category",
"category_weight",
Expand Down Expand Up @@ -225,7 +228,7 @@ def tidy_reproject_save(
elevation_seperation=ELEVATION_SPREAD,
)
os.makedirs(output_directory_path, exist_ok=True)
output_path = output_directory_path / f"{grow.id_no}.geojson"
output_path = output_directory_path / f"range_T{grow.id_no}A{grow.assessment_id}_{grow.season}.geojson"
res = gpd.GeoDataFrame(grow.to_frame().transpose(), crs=src_crs, geometry="geometry")

# Ensure proper dtypes for JSON serialization
Expand Down
9 changes: 8 additions & 1 deletion prepare_species/extract_species_data_psql.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
(assessment_supplementary_infos.supplementary_fields->>'ElevationUpper.limit')::numeric AS elevation_upper,
taxons.scientific_name,
taxons.family_name,
taxons.order_name,
taxons.phylum_name,
taxons.kingdom_name,
red_list_category_lookup.code
FROM
assessments
Expand Down Expand Up @@ -133,7 +136,8 @@ def process_row(
cursor = connection.cursor()

id_no, assessment_id, assessment_year, possibly_extinct, possibly_extinct_in_the_wild, \
elevation_lower, elevation_upper, scientific_name, family_name, category = row
elevation_lower, elevation_upper, scientific_name, family_name, \
order_name, phylum_name, kingom_name, category = row

report = SpeciesReport(id_no, assessment_id, scientific_name)
report.has_api_data = True
Expand Down Expand Up @@ -212,7 +216,10 @@ def process_row(
'|'.join(habitats_list),
scientific_name,
family_name,
order_name,
class_name,
phylum_name,
kingom_name,
json_ready_threats,
category,
category_weight,
Expand Down
6 changes: 6 additions & 0 deletions prepare_species/extract_species_data_redlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ def process_species(
assessment_year = assessment_dict['assessment_date'].year
category = assessment_dict['red_list_category']
family_name = assessment_dict['family_name']
order_name = assessment_dict['order_name']
phylum_name = assessment_dict['phylum_name']
kingdom_name = assessment_dict['kingdom_name']
possibly_extinct = assessment_dict['possibly_extinct']
possibly_extinct_in_the_wild = assessment_dict['possibly_extinct_in_the_wild']
infrarank = assessment_dict['infrarank']
Expand Down Expand Up @@ -261,7 +264,10 @@ def process_species(
'|'.join(habitats_list),
scientific_name,
family_name,
order_name,
class_name,
phylum_name,
kingdom_name,
json_ready_threats,
category,
CATEGORY_WEIGHTS[category],
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ scikit-image
redlistapi
boto3
yirgacheffe>=1.12,<2.0
aoh[validation]>=2.0.3,<3.0
aoh[validation]>=2.1.0,<3.0

# Snakemake workflow management
snakemake>=8.0
Expand Down
3 changes: 2 additions & 1 deletion threats/threat_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def threat_processing_per_species(
os.makedirs(output_directory_path, exist_ok=True)

taxon_id = data.id_no[0]
assessment_id = data.assessment_id[0]

# Due to validation we generate AOHs for many more species than
# is needed for STAR, but we need to ensure those don't slip into
Expand Down Expand Up @@ -54,7 +55,7 @@ def threat_processing_per_species(

threat_dir_path = output_directory_path / str(threat_id)
os.makedirs(threat_dir_path, exist_ok=True)
output_path = threat_dir_path / f"{taxon_id}.tif"
output_path = threat_dir_path / f"threat_T{taxon_id}A{assessment_id}.tif"
per_threat_per_species_score.to_geotiff(output_path)

# This script generates a bunch of rasters, but snakemake needs one
Expand Down
10 changes: 5 additions & 5 deletions workflow/rules/aoh.smk
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def aoh_species_inputs(wildcards):
/ "species-info"
/ wildcards.taxa
/ SCENARIO
/ f"{wildcards.species_id}.geojson",
/ f"range_{wildcards.species_id}.geojson",
# Base layers (precious - won't trigger rebuilds)
"habitat_sentinel": ancient(
DATADIR / "habitat_layers" / SCENARIO / ".habitat_complete"
Expand Down Expand Up @@ -88,11 +88,11 @@ rule generate_aoh:
unpack(aoh_species_inputs),
output:
# Only declare JSON as output - TIF is optional (not created for empty AOHs)
metadata=DATADIR / "aohs" / SCENARIO / "{taxa}" / "{species_id}_all.json",
metadata=DATADIR / "aohs" / SCENARIO / "{taxa}" / "aoh_{species_id}.json",
params:
habitat_dir=DATADIR / "habitat_layers" / SCENARIO,
log:
DATADIR / "logs" / "aoh" / "{taxa}" / "{species_id}_all.log",
DATADIR / "logs" / "aoh" / "{taxa}" / "{species_id}.log",
resources:
# Limit concurrent AOH jobs if needed (e.g., for memory)
aoh_slots=1,
Expand Down Expand Up @@ -126,7 +126,7 @@ def get_species_ids_for_taxa(wildcards):
taxa=wildcards.taxa
).output[0]
geojson_dir = Path(checkpoint_output).parent
return [p.stem for p in geojson_dir.glob("*.geojson")]
return [p.stem[6:] for p in geojson_dir.glob("range_*.geojson")]


def get_all_aoh_metadata_for_taxa(wildcards):
Expand All @@ -135,7 +135,7 @@ def get_all_aoh_metadata_for_taxa(wildcards):
"""
species_ids = get_species_ids_for_taxa(wildcards)
return [
DATADIR / "aohs" / SCENARIO / wildcards.taxa / f"{sid}_all.json"
DATADIR / "aohs" / SCENARIO / wildcards.taxa / f"aoh_{sid}.json"
for sid in species_ids
]

Expand Down
8 changes: 4 additions & 4 deletions workflow/rules/threats.smk
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def get_star_species_for_taxa(wildcards):

star_species = []
for geojson_path in geojson_dir.glob("*.geojson"):
species_id = geojson_path.stem
species_id = geojson_path.stem[6:]
aoh_path = (
DATADIR / "aohs" / SCENARIO / wildcards.taxa / f"{species_id}_all.tif"
DATADIR / "aohs" / SCENARIO / wildcards.taxa / f"aoh_{species_id}.tif"
)

# Check if species should be in STAR and has an AOH
Expand Down Expand Up @@ -88,8 +88,8 @@ rule generate_threat_rasters:
/ "species-info"
/ "{taxa}"
/ SCENARIO
/ "{species_id}.geojson",
aoh=DATADIR / "aohs" / SCENARIO / "{taxa}" / "{species_id}_all.tif",
/ "range_{species_id}.geojson",
aoh=DATADIR / "aohs" / SCENARIO / "{taxa}" / "aoh_{species_id}.tif",
output:
# Sentinel file since actual outputs depend on species' threats
sentinel=DATADIR / "threat_rasters" / "{taxa}" / ".{species_id}_complete",
Expand Down
5 changes: 3 additions & 2 deletions workflow/rules/validation.smk
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ rule validate_gbif_occurrences:
gbif_data=lambda wildcards: DATADIR
/ "validation"
/ "occurrences"
/ wildcards.taxa,
/ wildcards.taxa
/ "points.csv",
species_data=lambda wildcards: DATADIR
/ "species-info"
/ wildcards.taxa
Expand All @@ -106,7 +107,7 @@ rule validate_gbif_occurrences:
DATADIR / "logs" / "validate_gbif_{taxa}.log",
shell:
"""
aoh-validate-occurrences \
aoh-validate-occurences \
--gbif_data_path {params.gbif_data} \
--species_data {params.species_data} \
--aoh_results {params.aoh_results} \
Expand Down
Loading