Ingest USFWS species ranges → global 0.05° cells (v7-matched + marine-relevance)

Published

2026-07-13 19:37:03

USFWS complete-species current ranges onto the global 0.05° cell grid. FWS is a terrestrial-heavy agency (2,205 species: bats, bears, plants…), so only the coastal/marine species belong in a marine-sensitivity model. Handled in two phases:

  1. Exact v7-species match — ingest exactly the 106 FWS species v7 kept (its ocean mask’s marine-relevant subset), for v7↔︎v8 comparability (data/v7_rng_fws_spcodes.csv).
  2. Marine-relevance analysis — compute pct_marine (area-weighted ocean fraction) for all FWS species; compare the v7 species’ distribution (esp. min) against the non-v7 species to surface any marine-relevant species v7 missed. Reported for review (not auto-ingested), so expanding the set is a deliberate, documented choice.

Value = extinction-risk score via msens::compute_er_score("FWS:{code}") (never hard-coded): EN = 100, TN = 50, LC = 1, from the species’ most-protective (precautionary) ESA status. Whole range, no land mask (pct_marine is the metric).

1 Design

Figure 1: USFWS ranges: ingest the v7-matched species; report pct_marine candidates v7 may have missed

2 Setup

Code
librarian::shelf(
  arrow, DBI, dplyr, duckdb, exactextractr, fs, glue, here, janitor, jsonlite,
  logger, readr, sf, terra, tibble, MarineSensitivity/msens, quiet = T)
source(here("libs/paths.R"))   # dir_raw, dir_big_v, cellid_tif, bio_oracle_tif, ver
source(here("libs/vars.R"))    # redo_ingest
options(readr.show_col_types = F)
sf_use_s2(FALSE)               # FWS range polygons are planar-valid, s2-invalid
Spherical geometry (s2) switched off
Code
ds_key   <- "rng_fws"
dir_rng  <- glue("{dir_raw}/fws.gov/usfws_complete_species_current_range")
rng_shp  <- glue("{dir_rng}/usfws_complete_species_current_range_{1:2}.shp")
dir_dist <- glue("{dir_big_v}/marine-atlas/dist/dataset={ds_key}")
manifest <- here("data/manifests/ingest_rng_fws.json")
pctm_csv <- here("data/ingest_rng_fws_pct_marine.csv")
dir_create(c(dir_dist, path_dir(manifest)))
stopifnot("run build_cell_grid.qmd first" = file_exists(cellid_tif), all(file_exists(rng_shp)))

v7_spcodes <- read_csv(here("data/v7_rng_fws_spcodes.csv"))$spcode   # 106 v7 FWS species

# FWS STATUS_ABB -> ESA code (the v7 mapping); val via compute_er_score (never hard-coded)
esa_from_status <- function(status_abb) dplyr::case_when(
  status_abb %in% c("Endangered", "Experimental Population, Non-Essential",
                    "Proposed Endangered") ~ "EN",
  status_abb %in% c("Threatened", "Proposed Threatened",
                    "Similarity of Appearance (Threatened)",
                    "Proposed Similarity of Appearance (Threatened)") ~ "TN",
  TRUE ~ "LC")   # Not Listed / Recovery / Species of Concern / Under Review / etc.

3 Read all FWS ranges + per-species ESA status + er_score

Code
rng <- bind_rows(lapply(rng_shp, st_read, quiet = TRUE)) |>
  clean_names() |>
  filter(status_abb != "Extinction") |>            # drop extinct
  mutate(esa_code = ordered(esa_from_status(status_abb), c("LC", "TN", "EN")))

# one model per species (spcode); most-protective (precautionary) status
sp <- rng |>
  st_drop_geometry() |>
  group_by(spcode, sciname, comname, family) |>
  summarise(n_features = n(), esa_code = max(esa_code), .groups = "drop") |>
  mutate(
    er_code  = paste0("FWS:", as.character(esa_code)),
    er_score = compute_er_score(er_code),
    is_v7    = spcode %in% v7_spcodes,
    mdl_key  = mdl_key_raw(ds_key, spcode)) |>
  arrange(sciname)
write_csv(sp, glue("{dir_dist}/../model_{ds_key}.csv"))
glue("{nrow(sp)} FWS species | {sum(sp$is_v7)} in v7 | ER: {sum(sp$esa_code=='EN')} EN / {sum(sp$esa_code=='TN')} TN / {sum(sp$esa_code=='LC')} LC")
2196 FWS species | 106 in v7 | ER: 1238 EN / 379 TN / 579 LC

4 Phase 2 — marine-relevance analysis (pct_marine)

pct_marine = area-weighted ocean fraction of each range (exactextractr over the Bio-Oracle ocean mask). Heavy (all species); cached to pctm_csv.

Code
if (redo_ingest || !file_exists(pctm_csv)) {
  r_ocean <- !is.na(rast(bio_oracle_tif, lyrs = "depth_mean"))   # 1 ocean, 0 land
  log_info("computing pct_marine for {nrow(sp)} FWS species ...")
  pm <- exact_extract(r_ocean, rng, "mean", append_cols = "spcode", progress = FALSE) |>
    group_by(spcode) |> summarise(pct_marine = round(100 * max(mean, na.rm = TRUE), 1), .groups = "drop")
  sp <- sp |> left_join(pm, by = "spcode")
  write_csv(sp, pctm_csv)
} else {
  sp <- read_csv(pctm_csv)
}
Warning in .local(x, y, ...): Polygons transformed to raster CRS (EPSG: 4326) .
To avoid on-the-fly coordinate transformation, ensure that st_crs() returns the
same result for both raster and polygon inputs.
Code
# v7 threshold vs non-v7 candidates v7 may have missed
thr    <- min(sp$pct_marine[sp$is_v7], na.rm = TRUE)
missed <- sp |> filter(!is_v7, pct_marine >= thr) |> arrange(desc(pct_marine))
log_info("v7 pct_marine: min={thr}% median={median(sp$pct_marine[sp$is_v7],na.rm=T)}%; ",
         "{nrow(missed)} non-v7 species >= v7-min threshold (candidates v7 missed)")
knitr::kable(t(summary(sp$pct_marine[sp$is_v7])))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0 3.3 13.2 26.5434 32.95 100
Code
knitr::kable(head(missed |> select(spcode, sciname, comname, esa_code, pct_marine), 20))
spcode sciname comname esa_code pct_marine
Q01G Amaranthus brownii No common name EN 100.0
Q0D1 Castilleja mollis Soft-leaved paintbrush EN 100.0
B0DH Ducula oceanica ratakensis Radak Micronesian pigeon LC 100.0
Q1VT Dudleya traskiae Santa Barbara Island liveforever EN 100.0
A0I9 Emballonura semicaudata rotensis Pacific sheath-tailed Bat EN 100.0
I0HT Hylaeus hilaris Hilaris yellow-faced bee EN 100.0
G0AI Partula langfordi Langford’s tree snail EN 100.0
Q1JS Pritchardia remota loulu EN 100.0
Q1N3 Schiedea verticillata No common name EN 100.0
C038 Sphaerodactylus micropithecus Monito gecko LC 100.0
Q0OF Dudleya nesiotica Santa Cruz Island dudleya LC 99.9
A0J8 Odobenus rosmarus ssp. divergens Pacific walrus LC 98.7
C01P Ameiva polops St. Croix ground lizard EN 97.8
Q2G8 Pittosporum halophilum Hoawa EN 94.2
A003 Odocoileus virginianus clavium Key deer EN 92.9
A08Y Peromyscus polionotus ammobates Alabama beach mouse EN 92.9
C040 Diadophis punctatus acricus Key ring-necked snake EN 89.7
A083 Oryzomys palustris natator Silver rice rat EN 88.6
A0AA Sylvilagus palustris hefneri Lower Keys marsh rabbit EN 88.6
Q1JO Pritchardia hillebrandii loulu lelo LC 87.8

5 Phase 1 — ingest the v7-matched species → one Parquet each

Ingest exactly the v7 species (comparability). To expand to the Phase-2 candidates, add them to to_ingest after review.

Code
if (redo_ingest && dir_exists(dir_dist)) { dir_delete(dir_dist); dir_create(dir_dist) }
to_ingest <- sp |> filter(is_v7)                       # v7 exact match (deliberate)
done <- path_ext_remove(path_file(dir_ls(dir_dist, glob = "*.parquet")))
todo <- to_ingest |> filter(!spcode %in% done)
log_info("{ds_key}: {length(done)} done; rasterizing {nrow(todo)} of {nrow(to_ingest)} v7-matched ranges ...")

for (i in seq_len(nrow(todo))) {
  r      <- todo[i, ]
  ply_sp <- rng |> filter(spcode == r$spcode) |> summarise(.groups = "drop")
  d <- cells_from_ranges(ply_sp, cellid_tif, value = r$er_score)   # whole range, ER-scored
  if (nrow(d) == 0) { log_warn("  {r$spcode} ({r$sciname}): no cells"); next }
  msens::write_atlas_parquet(tibble(mdl_key = r$mdl_key, cell_id = d$cell_id, val = d$val),
                fs::path(dir_dist, r$spcode, ext = "parquet"))
}
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
Warning in st_is_longlat(x): bounding box has potentially an invalid value
range for longlat data
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
Warning: bounding box has potentially an invalid value range for longlat data
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
Warning: bounding box has potentially an invalid value range for longlat data
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
although coordinates are longitude/latitude, st_union assumes that they are
planar
Warning: [extract] transforming vector data to the CRS of the raster
Code
log_info("{ds_key}: done")

6 Verify + manifest

Code
pq  <- dir_ls(dir_dist, glob = "*.parquet")
con <- dbConnect(duckdb())
smry <- dbGetQuery(con, glue(
  "SELECT count(DISTINCT mdl_key) n_models, count(*) n_cells, min(val) v_min, max(val) v_max
     FROM read_parquet('{dir_dist}/*.parquet')"))
# order-independent content fingerprint of the on-disk surface (not the ingest run)
h <- msens::hash_parquet(glue("{dir_dist}/*.parquet"), con)
dbDisconnect(con, shutdown = TRUE)
msens::report_table(smry, caption = "rng_fws model_cell surface")
rng_fws model_cell surface
n_models n_cells v_min v_max
106 2053026 1 100
Code
# content-addressed manifest: deterministic, no wall-clock, no machine paths ->
# downstream targets re-run only when this surface's content actually changes
msens::write_manifest(
  manifest, target = "ingest_rng_fws", content_hash = h,
  stats = list(ds_key = ds_key, ver = ver, n_species_all = nrow(sp),
               n_v7 = sum(sp$is_v7), n_cells = smry$n_cells,
               v_min = smry$v_min, v_max = smry$v_max, n_parquet = length(pq)),
  force = msens::force_target("ingest_rng_fws"))