The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

oystermapR

Predict and map oyster growth suitability from environmental survey data

oystermapR takes tabular sensor data — from ADCPs, CTDs, bathymetric sonar, or standard CSV files — applies species-specific AHP-weighted scoring rules, and returns per-location suitability scores alongside a five-band GeoTIFF heatmap ready to load in QGIS.


Supported species

Key Species Common name Region
ostrea_edulis Ostrea edulis European Flat Oyster NE Atlantic / Mediterranean
magallana_gigas Magallana gigas Pacific Oyster Global aquaculture
crassostrea_angulata Crassostrea angulata Portuguese Oyster Iberian Peninsula
ostrea_stentina Ostrea stentina Denticulate Flat Oyster Mediterranean / W Africa
ostrea_lurida Ostrea lurida Olympia Oyster Pacific NW (N America)
crassostrea_virginica Crassostrea virginica Eastern Oyster NW Atlantic
saccostrea_glomerata Saccostrea glomerata Sydney Rock Oyster E Australia
magallana_sikamea Magallana sikamea Kumamoto Oyster Japan / Pacific NW
magallana_ariakensis Magallana ariakensis Suminoe Oyster E Asia
crassostrea_hongkongensis Crassostrea hongkongensis Hong Kong Oyster S China Sea
crassostrea_nippona Crassostrea nippona Iwagaki Oyster Japan / Korea
crassostrea_belcheri Crassostrea belcheri Tropical Rock Oyster SE Asia
ostrea_chilensis Ostrea chilensis Chilean Oyster S Chile / New Zealand
ostrea_denselamellosa Ostrea denselamellosa Korean Flat Oyster E Asia
ostrea_angasi Ostrea angasi Angasi Oyster S Australia
saccostrea_cucullata Saccostrea cucullata Rock Oyster Indian Ocean / W Pacific
crassostrea_iredalei Crassostrea iredalei Slipper Oyster SE Asia (brackish)

Installation

# From CRAN (once accepted)
install.packages("oystermapR")

# Development version from GitHub
devtools::install_github("trissyboats/oystermapR")

Requires R >= 4.1.0. Core dependencies: dplyr, terra, sf, cli, rlang.


Quick start

library(oystermapR)

# Load your survey data
df <- read.csv("my_survey.csv")

# Run the prediction
result <- predict_oyster(
  data           = df,
  species        = "ostrea_edulis",
  output_geotiff = "oyster_suitability.tif",
  verbose        = TRUE
)

# Inspect high-suitability sites
subset(result, suitability_class == "High")

# Export matching QGIS colour ramp style
export_qml_style("oyster_suitability.tif")

The output dataframe contains suitability (0–1), suitability_class (High / Moderate / Low / Very Low / Excluded), data_completeness (fraction of variables scored), n_layers_scored (integer count of variables that contributed at each point), and per-variable component scores (score_depth, score_temperature, etc.).


Input data

Your CSV needs at minimum lat, lon, and date. Any environmental columns present are scored automatically — missing variables are skipped and their weights redistributed. Column names are matched case-insensitively against the aliases below.

Variable Recognised column names
Temperature (°C) temperature, temp, temp_c
Salinity (PSU) salinity, sal, salinity_psu, psu, sal_psu
Dissolved oxygen (mg/L) dissolved_oxygen, do, do_mgl, oxygen, dissolved_o2, do_mg_l
pH ph, ph_nbs, ph_total, seawater_ph
Total alkalinity (µmol/kg) alkalinity, total_alkalinity, ta, talk, alk_umol_kg
Aragonite saturation (Ω) omega_aragonite, omega_arag, aragonite_saturation, arag_sat, omega
Depth (m) depth, depth_m
Current velocity (m/s) current_velocity, velocity, current
Shear stress (N/m²) shear_stress, tau, bed_shear
Chlorophyll-a (µg/L) chlorophyll_a, chla, chlorophyll
Turbidity (NTU) turbidity, ntu, turb
Slope (degrees) slope, slope_deg
Substrate hardness substrate_hardness, hardness

A sample dataset is included at inst/extdata/sample_survey.csv.


Ocean acidification scoring

pH and aragonite saturation state (Ω_arag) are scored for all 17 species. If your data contains ph and alkalinity columns, predict_oyster() automatically computes omega_aragonite before scoring — no preprocessing required.

# Aragonite auto-calculated from pH + alkalinity columns
result <- predict_oyster(df, "ostrea_edulis")

# Manual calculation (no external packages)
df$omega_aragonite <- calculate_aragonite(
  pH          = df$ph,
  alkalinity  = df$alkalinity,    # µmol/kg
  temperature = df$temperature,   # °C
  salinity    = df$salinity       # PSU
)

calculate_aragonite() implements the full carbonate chemistry using Lueker et al. (2000) K1/K2, Dickson (1990) KB, Millero (1995) KW, Mucci (1983) Ksp_arag, Uppstrom (1974) [B_T], and Riley & Tongudai (1967) [Ca²⁺]. No external package dependencies.


Diagnostics and QA

Variable impact

variable_impact() returns a ranked table showing which environmental variables contribute most to the suitability score across a dataset. Use it to identify limiting factors and data gaps.

impact <- variable_impact(result, "ostrea_edulis")
#>   variable          rank  norm_weight_pct  mean_score  mean_contribution  n_points  pct_coverage
#>   temperature          1            24.1        0.82               0.198       842          99.5
#>   depth                2            18.7        0.91               0.170       842         100.0
#>   dissolved_oxygen     5            12.4        0.68               0.084       511          60.7
#>   ...

Sort by "mean_score" to find bottlenecks (variables scoring poorly across the dataset), or by "pct_coverage" to find sparsely observed layers.

Data layer coverage

n_layers_scored in the result dataframe records how many variables contributed to the suitability score at each location. Low values indicate points where the score rests on few observations. GeoTIFF band 5 maps this spatially in QGIS.


Fine-scale area analysis

area_summary() converts point-based scores into habitat area estimates at sub-hectare resolution — designed for restoration ecology where the difference between 200 m² and 800 m² matters.

s <- area_summary(result, cell_size_m = 10, viable_area_m2 = 100)

# Per-class breakdown in m²
s$class_summary

# Total suitable area
s$total["suitable_area_m2"]
s$total["pct_suitable"]

# Contiguous patches — flag those meeting OSPAR minimum viable area
s$patches[s$patches$viable, ]

Cell size is auto-estimated from median nearest-neighbour point spacing when cell_size_m = NULL. The viable_area_m2 threshold (default 100 m² = 0.01 ha) aligns with OSPAR oyster reef restoration guidance.


Tolerance visualisation

plot_tolerance() draws the mathematical scoring curve for any species/variable combination directly from the tolerance specification — no dataset needed. Useful for QA, stakeholder communication, and report figures.

# Scoring curve with colour-coded zones (optimal = green, excluded = red)
plot_tolerance("ostrea_edulis", "temperature")

# All four seasons overlaid
plot_tolerance("ostrea_edulis", "temperature", season = "all")

# Ocean acidification variables
plot_tolerance("ostrea_edulis", "ph")
plot_tolerance("magallana_gigas", "omega_aragonite")

# Compare DO tolerance: European flat vs brackish slipper oyster
plot_tolerance("ostrea_edulis",       "dissolved_oxygen")
plot_tolerance("crassostrea_iredalei","dissolved_oxygen")

For data-driven partial dependence curves from an actual survey, use sensitivity_analysis() instead.


Sensor readers

# Nortek Signature 500 ADCP
adcp <- read_nortek_adcp("adcp_export.csv")

# Nortek Aquadopp (moored or vessel-mounted)
adcp2 <- read_nortek_aquadopp("aquadopp_export.csv")

# Teledyne RDI binary PD0 (requires oce)
adcp3 <- read_rdi_adcp("transect.pd0")

# Ping 3DSS / BioBase bathymetric raster
bathy <- read_sonar_tif("bathymetry.tif")

# Bathymetric sounding XYZ point cloud
bathy2 <- read_soundings_xyz("soundings.xyz")

# Any standard CSV export (auto column matching)
ctd <- read_generic_csv("ctd_cast.csv")

# Merge multiple sensor sources onto a common spatial grid
survey <- merge_sensor_data(adcp = adcp, bathy = bathy2, ctd = ctd)

Validation and diagnostics

# Validate against known presence/absence records
val <- validate_against_records(result, records)
val$auc      # ROC-AUC
val$tss      # True Skill Statistic
val$f1       # F1 score
val$brier    # Brier score

# Spatial block cross-validation (avoids inflated AUC from autocorrelation)
cv <- spatial_block_cv(result, records, n_blocks = 5)

# Permutation variable importance (AUC drop per variable)
imp <- permutation_importance(result, records)

# Partial dependence curve for a single variable (data-driven)
sensitivity_analysis(result, records, variable = "temperature")

# Dataset-level weighted contribution summary (no records needed)
variable_impact(result, "ostrea_edulis")

# Multi-species comparison at the same grid
compare_species(survey_clean, species = c("ostrea_edulis", "magallana_gigas"))

Bayesian tolerance updating

Update species tolerance parameters from your own field observations:

fit <- update_species_tolerances(
  records     = field_data,
  species     = "ostrea_edulis",
  update_vars = c("temperature", "salinity", "depth")
)

# Subsequent predict_oyster() calls use the updated parameters automatically
result2 <- predict_oyster(df, "ostrea_edulis")

# Persist across sessions
save_tolerance_update("ostrea_edulis")

Additional modules

Function Purpose
variable_impact() Ranked variable contribution table for QA and survey planning
area_summary() Fine-scale area estimates in m² with contiguous patch analysis
plot_tolerance() Tolerance scoring curve from species parameters (no data required)
calculate_aragonite() In-house aragonite saturation (Ω_arag) from pH and alkalinity
score_wave_exposure() JONSWAP wave height from fetch and wind speed
score_sediment_stability() Shields parameter sediment mobility analysis
score_larval_connectivity() Hybrid Gaussian kernel + OpenDrift connectivity matrix
score_predation_risk() Starfish, crab, and snail predation pressure
score_hab_risk() Harmful algal bloom risk (PSP/ASP/DSP/AZP)
score_anthropogenic_disturbance() Bottom trawling, anchor damage, dredging
add_shellfish_classification() UK/EU harvesting area classification (A/B/C)
compare_species() Side-by-side suitability across multiple species
composite_seasonal() Merge summer/winter surveys into a composite score
generate_report() Export a formatted PDF or HTML report

QGIS workflow

# Export five-band GeoTIFF + contour lines
predict_oyster(df, "ostrea_edulis", output_geotiff = "suitability.tif")

# Export matching colour ramp style file
export_qml_style("suitability.tif")

Load suitability.tif in QGIS, then drag the .qml file onto the layer to apply the standard oystermapR colour scheme instantly.

GeoTIFF bands:

Band Name Description
1 suitability Continuous suitability score [0, 1]
2 excluded_mask 1 = hard-excluded (failed exclusion threshold)
3 n_observations Number of survey points per raster cell
4 dist_to_nearest_m Distance to nearest survey point (m)
5 n_layers_scored Number of environmental variables that contributed to the score

Citation

If you use oystermapR in published work, please cite:

Tucker T. (2026). oystermapR: Predict and Map Oyster Growth Suitability from Environmental Data. R package version 1.5.0. https://github.com/trissyboats/oystermapR


License

GPL-3 © T Tucker

Free for research, education, and non-commercial use. Commercial entities wishing to embed oystermapR in a proprietary product should contact tristantucker48@gmail.com to discuss a commercial licence.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.