ocetrac.SurfTrack.SurfTracker#

class ocetrac.SurfTrack.SurfTracker(da: DataArray, mask: DataArray, *, radius: int = 2, min_size_quartile: float = 0.25, min_area_cells: int = 100, timedim: str = 'time', xdim: str = 'nlon', ydim: str = 'nlat', positive: bool = True, method: str = '3d', contain_thresh: float = 0.0)[source]#

End-to-end surface marine heatwave tracker.

Operates on 3-D data (time, ydim, xdim). Each step stores its output as an attribute so intermediate results can be inspected.

Pipeline#

clean → filter_area → track → postprocess

param da:

Anomaly or thresholded feature field.

type da:

DataArray (time, ydim, xdim)

param mask:

Binary ocean mask — 1 = valid ocean cell, 0 = land/ignored.

type mask:

DataArray (ydim, xdim)

param radius:

Disk radius for morphological close→open. radius=1 is a no-op. Larger values fill wider gaps but risk bridging separate events. Default 2.

type radius:

int

param min_size_quartile:

Relative area percentile threshold (0–1). Combined with min_area_cells via max(). Default 0.25.

type min_size_quartile:

float

param min_area_cells:

Absolute minimum object area in grid cells. Objects smaller than this are always removed regardless of the percentile. Default 100.

type min_area_cells:

int

param timedim:

Name of the time dimension. Default "time".

type timedim:

str

param xdim:

Name of the x (longitude) dimension. Default "nlon".

type xdim:

str

param ydim:

Name of the y (latitude) dimension. Default "nlat".

type ydim:

str

param positive:

True → track warm anomalies (>0). False → track cold anomalies (<0). Default True.

type positive:

bool

param method:

Labelling method. "3d" (default) runs connected-component labelling on the full (time, lat, lon) volume. "temporal_neighbor" labels each 2-D frame independently and only links blobs between adjacent frames if they spatially overlap. A gap of even one timestep starts a new event.

type method:

str

param contain_thresh:

Only used when method="temporal_neighbor". Containment threshold for merging two blobs using max(|A∩B|/|A|, |A∩B|/|B|) >= contain_thresh. 0.0 means any spatial overlap is sufficient. Default 0.0.

type contain_thresh:

float

__init__(da: DataArray, mask: DataArray, *, radius: int = 2, min_size_quartile: float = 0.25, min_area_cells: int = 100, timedim: str = 'time', xdim: str = 'nlon', ydim: str = 'nlat', positive: bool = True, method: str = '3d', contain_thresh: float = 0.0) None[source]#

Methods

__init__(da, mask, *[, radius, ...])

clean()

Binarise the input field, apply morphological close→open per (lat, lon) slice, then apply the ocean mask.

event_duration()

Return {event_id: n_timesteps_present} from the final result.

filter()

Label 2-D slices, make IDs consecutive across time, wrap across the date line, then filter by area using:

n_events()

Number of unique tracked events in the final result.

postprocess()

Wrap the tracked array as an xr.DataArray with NaN background and attach tracking diagnostics as attributes.

run()

Execute the full pipeline: clean → filter → track → postprocess

summary()

Print event count, duration distribution, and parameters.

track()

Label connected objects and wrap across the date line.