heatwave3
The Goal of this package is to make life easier when working with the Hobday et al. marine heatwave definition on large datasets.
https://github.com/robwschlegel/heatwave3
Category: Hydrosphere
Sub Category: Ocean Carbon and Temperature
Last synced: about 5 hours ago
JSON representation
Repository metadata
Apply the Hobday et al. (2016, 2018) marine heatwave definition directly to NetCDF files.
- Host: GitHub
- URL: https://github.com/robwschlegel/heatwave3
- Owner: robwschlegel
- License: other
- Created: 2023-07-29T12:45:06.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2026-06-05T11:42:07.000Z (8 days ago)
- Last Synced: 2026-06-06T00:05:32.164Z (7 days ago)
- Language: C++
- Homepage: https://robwschlegel.github.io/heatwave3/
- Size: 6.81 MB
- Stars: 9
- Watchers: 5
- Forks: 0
- Open Issues: 0
- Releases: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
README.md
heatwave3
heatwave3 detects marine heatwaves (MHWs) and cold-spells directly on gridded NetCDF data using the Hobday et al. (2016, 2018) definition. It is a ground-up C++ reimplementation of heatwaveR, designed for gridded datasets rather than individual time series.
Why heatwave3?
Working with large gridded SST datasets (such as OSTIA, OISST, ERA5, CMIP6) using heatwaveR requires looping over each pixel individually in R. For a 400 × 200 grid with 40 years of daily data, this takes over an hour. heatwave3 addresses this with:
- C++17 implementation of all core algorithms (climatology, event detection, categorisation, block averages)
- OpenMP parallelism across pixels, since each pixel is independent
- Direct NetCDF I/O via libnetcdf, with no R NetCDF packages needed at runtime
Performance
Benchmarked on the OSTIA South-West Indian Ocean reanalysis (400 × 200 grid, ca. 50,000 ocean pixels, 14,276 daily time steps), Apple M5 Max:
| Method | Time | Speedup |
|---|---|---|
| heatwaveR (serial) | ca. 69 min | 1× |
| heatwave3 (1 thread) | 4.3 min | 16× |
| heatwave3 (12 threads) | 1.9 min | 36× |
For larger grids using daily files (Benguela region, 260 × 360 pixels, 16,049 daily OSTIA files, 12 threads): 3.4 minutes end-to-end.
Features
- Climatology (
ts2clm3). Sliding-window percentile with Type-7 quantile, circular-padded rolling mean smoothing, and optional linear detrending (Jacox et al. 2020). - Event detection (
detect_event3). Threshold exceedance, run-length encoding, gap joining, and 19 event metrics. Cold-spell support. Optional inline Hobday et al. (2018) severity categories. - All-in-one pipeline (
detect3). Climatology, detection, and optional categories in a single call from onenamestem; read results back withhw3_export(). - Spatial blob detection (
detect_blob3). 3D connected-component labelling with voxel-level footprint output. - Event categorisation (
category3). Hobday et al. (2018) Moderate/Strong/Severe/Extreme categories, for both heatwaves and cold-spells. - Yearly aggregation (
block_average3) and static threshold exceedance (exceedance3). - Plotting.
event_line3,geom_flame3,geom_lolli3, andplot_metric3(C++-backed spatial aggregation). - Flexible input. Single multi-timestep NetCDF, directory of daily files, or explicit file vector.
- Automatic dimension detection. Identifies lon/lat/time/SST from CF attributes, standard names, and units (works with GHRSST, OISST, OSTIA, ERA5, CMIP6, NEMO).
- Progress reporting. Percentage-complete updates during long climatology and detection runs.
- NetCDF-native output, exported on demand. The compute functions always write gridded NetCDF;
hw3_export()reads any product back into R or converts it to CSV, RDS, or Parquet, with optional variable and lon/lat/time subsetting. - Numerical equivalence. Climatology and event metrics match heatwaveR to rounding precision, validated pixel-by-pixel.
Installation
Development version (recommended)
The dev branch contains the new C++ implementation:
# install.packages("remotes")
remotes::install_github("robwschlegel/heatwave3")
System requirements
heatwave3 requires the netCDF C library (version 4.0+). The configure script finds it automatically via nc-config or pkg-config.
macOS:
brew install netcdf
Ubuntu / Debian:
sudo apt install libnetcdf-dev
Fedora / RHEL:
sudo dnf install netcdf-devel
OpenMP parallelism
On Linux, OpenMP works without extra setup. On macOS, the configure script probes for a working OpenMP runtime (Apple Clang with R's own bundled libomp, Homebrew libomp, or user-supplied flags) using a compile-link-run test. If none is found, heatwave3 falls back to single-threaded mode.
To install Homebrew's libomp (may help on some macOS configurations):
brew install libomp
Thread management
heatwave3 defaults to 50% of available cores (overridable via R_HEATWAVE3_NUM_THREADS). Control threads at the session level or per function call:
library(heatwave3)
getHW3threads() # check current default
setHW3threads(8) # use 8 threads for all subsequent calls
setHW3threads(0) # reset to default (50% of cores)
# Or override per call:
detect_event3(..., n_threads = 12)
heatwave3 never calls omp_set_num_threads(), so it does not change thread counts for other OpenMP-using packages. It is also safe under parallel::mclapply() (fork-safe via pthread_atfork).
Quick start
library(heatwave3)
sst_file <- "path/to/sst.nc" # or a directory of daily files
# All-in-one: climatology + event detection + categories. A single 'name' stem
# writes benguela_clim.nc and benguela_events.nc.
detect3(
file_in = sst_file,
name = "benguela",
climatologyPeriod = c("1991-01-01", "2020-12-31"),
lon_range = c(15, 35),
lat_range = c(-38, -28),
category = TRUE,
hemisphere = "south",
n_threads = 4
)
# Read the events back as a data.frame (or a quick preview with n =)
events <- hw3_export("benguela_events.nc")
head(events)
table(events$category)
Cold-spell detection
# Use pctile = 10 for the cold tail
detect3(
file_in = sst_file,
name = "benguela_cold",
climatologyPeriod = c("1991-01-01", "2020-12-31"),
pctile = 10,
coldSpells = TRUE,
category = TRUE,
hemisphere = "south",
n_threads = 12
)
table(hw3_export("benguela_cold_events.nc")$category)
Per-pixel time series plot
event_line3(sst_file, "benguela_clim.nc", lon = 25.0, lat = -34.0,
start_date = "2018-01-01", end_date = "2019-12-31")
Spatial map of peak intensity
# C++-backed per-pixel aggregation, efficient even for millions of events
plot_metric3("benguela_events.nc", metric = "intensity_max", summary = "mean")
Event categories (standalone)
# Reads pre-computed categories from event file (no clim_file needed)
cats <- category3("benguela_events.nc")
table(cats$category)
# Or compute from scratch for older event files
cats <- category3("benguela_events.nc", "benguela_clim.nc", hemisphere = "south")
Using daily files
# Pass a directory. All .nc/.nc4 files are read, sorted, and merged
ts2clm3(
file_in = "/path/to/daily_ostia/",
name = "ostia",
climatologyPeriod = c("1991-01-01", "2020-12-31"),
n_threads = 12
)
Spatial blob detection
blobs <- detect_blob3(
sst_file = sst_file,
clim_file = "benguela_clim.nc",
minVoxels = 200,
topN = 6,
return = c("event", "daily", "voxel")
)
# blobs$event: summary per blob (duration, peak area, cumulative intensity)
# blobs$daily: daily progression (area, centroid, bounding box)
# blobs$voxel: full 3D footprint (for spatial maps)
Detrended climatology
# Remove linear warming trend before computing climatology
# (Jacox et al. 2020 approach)
ts2clm3(sst_file, name = "benguela_detrended",
climatologyPeriod = c("1991-01-01", "2020-12-31"),
detrend = TRUE)
API overview
All functions are suffixed with 3 to avoid namespace conflicts with heatwaveR:
| Function | Purpose |
|---|---|
detect3() |
Primary entry point. Climatology, detection, and optional categories |
ts2clm3() |
Compute climatology (NetCDF → NetCDF) |
detect_event3() |
Detect per-pixel events (with optional inline categories) |
detect_blob3() |
3D spatial blob detection |
category3() |
Hobday et al. (2018) event categories (reads or computes) |
block_average3() |
Yearly aggregation of event metrics |
exceedance3() |
Static threshold exceedance |
event_line3() |
Per-pixel time series plot |
geom_flame3() |
ggplot2 flame polygon geom |
geom_lolli3() |
ggplot2 lollipop geom |
plot_metric3() |
Spatial map of event metrics (C++-backed aggregation) |
hw3_export() |
Read any product into a data.frame, or export to CSV/RDS/Parquet |
Vignettes
- Getting started. Full pipeline walkthrough with spatial blob figures.
- NetCDF output internals. Output file structure, CF compliance, and reading in R/Python/CDO.
- Performance benchmark. heatwaveR versus heatwave3 timing comparison.
- Parallel performance. OpenMP threads versus R-side parallelism, with per-platform setup.
Citation
If you use heatwave3 in published research, please cite both:
- Hobday, A.J., et al. (2016). A hierarchical approach to defining marine heatwaves. Progress in Oceanography, 141, 227–238.
- Hobday, A.J., et al. (2018). Categorizing and naming marine heatwaves. Oceanography, 31(2), 162–173.
Code of Conduct
Please note that the heatwave3 project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.
Owner metadata
- Name: Robert William Schlegel
- Login: robwschlegel
- Email:
- Kind: user
- Description: Data scientist for FACE-IT. What are the key drivers of change in Arctic fjord systems, and what is humanities role?
- Website: https://theoceancode.netlify.com/
- Location: Villefranche, France
- Twitter: robwschlegel
- Company: Institut de la mer de Villefranche
- Icon url: https://avatars.githubusercontent.com/u/7559399?u=95859736f0af87fb84c542a191062b56a6e977fa&v=4
- Repositories: 31
- Last ynced at: 2024-06-11T16:00:21.026Z
- Profile URL: https://github.com/robwschlegel
GitHub Events
Total
- Watch event: 2
- Push event: 7
Last Year
- Push event: 7
Committers metadata
Last synced: 3 days ago
Total Commits: 63
Total Committers: 5
Avg Commits per committer: 12.6
Development Distribution Score (DDS): 0.429
Commits in past year: 19
Committers in past year: 2
Avg Commits per committer in past year: 9.5
Development Distribution Score (DDS) in past year: 0.053
| Name | Commits | |
|---|---|---|
| Robert William Schlegel | r****l@g****m | 36 |
| AJ Smit | a****t@u****a | 18 |
| GuiSPinto | k****e@g****m | 6 |
| Robert | r****l@i****r | 2 |
| Lily Genevier | 6****n | 1 |
Committer domains:
- imev-mer.fr: 1
- uwc.ac.za: 1
Issue and Pull Request metadata
Last synced: 3 months ago
Total issues: 2
Total pull requests: 0
Average time to close issues: 3 months
Average time to close pull requests: N/A
Total issue authors: 2
Total pull request authors: 0
Average comments per issue: 9.0
Average comments per pull request: 0
Merged pull request: 0
Bot issues: 0
Bot pull requests: 0
Past year issues: 0
Past year pull requests: 0
Past year average time to close issues: N/A
Past year average time to close pull requests: N/A
Past year issue authors: 0
Past year pull request authors: 0
Past year average comments per issue: 0
Past year average comments per pull request: 0
Past year merged pull request: 0
Past year bot issues: 0
Past year bot pull requests: 0
Top Issue Authors
- geografif (1)
- aonojeghuo (1)
Top Pull Request Authors
Top Issue Labels
Top Pull Request Labels
Dependencies
- actions/checkout v3 composite
- r-lib/actions/check-r-package v2 composite
- r-lib/actions/setup-pandoc v2 composite
- r-lib/actions/setup-r v2 composite
- r-lib/actions/setup-r-dependencies v2 composite
- R >= 2.10 depends
- heatwaveR * imports
- terra * imports
- testthat >= 3.0.0 suggests
Score: 3.8066624897703196