Data Utilities¶
samudra.utils.data
¶
Masks(prognostic, boundary)
dataclass
¶
Read-only mask metadata used to expose the ocean and mask land.
Tensor contents are shared between canonical views for efficiency and must be treated as immutable by callers.
CanonicalReadRequest(time_indices, channels)
dataclass
¶
A storage-independent request for canonical ocean-data planes.
The shape of time_indices defines the leading dimensions of the returned
planes. Keeping this core request to NumPy makes it usable by Python and native
readers without importing xarray concepts into the boundary.
ChannelStatistics(mean, std)
dataclass
¶
Normalization statistics aligned one-for-one with canonical channels.
CanonicalReader
¶
Bases: Protocol
Narrow storage seam implemented by xarray now and native readers later.
CanonicalSource(name, _reader, masks, data_layout)
dataclass
¶
A structurally immutable, read-capable view of canonical ocean data.
Physical xarray layout is private to the reader. In particular, callers see the same ordered channels for flat and compact OM4 stores. Channel selection and time slicing return new views and never mutate the source. Tensor-valued masks are shared, read-only metadata; mutating their contents is unsupported.
reader
property
¶
Return the storage reader so backends can decorate its read behavior.
with_reader(reader)
¶
Return an equivalent source backed by a replacement reader.
Source code in src/samudra/utils/data.py
from_canonical_datasets(name, data, means, stds, masks, data_layout)
classmethod
¶
Construct from datasets that are already in canonical channel form.
Raw OM4 callers should use :meth:from_datasets. This factory remains
useful for focused in-memory tests and named preprocessing stages.
Source code in src/samudra/utils/data.py
slice_time(time)
¶
Slice the data source to only include the specified time slice.
Source code in src/samudra/utils/data.py
read(time_indices, channels)
¶
Read canonical channels at integer time indices.
to_xarray_dataset()
¶
Return the backing xarray dataset when the reader supports it.
Source code in src/samudra/utils/data.py
from_datasets(data, means, stds, *, data_layout, prognostic_var_names, boundary_var_names, name='CanonicalSource')
classmethod
¶
Build a canonical reader from already-canonicalized xarray datasets.
Source code in src/samudra/utils/data.py
BatchPreprocessor(source, prognostic_var_names, boundary_var_names, *, normalize_before_mask=True, masked_fill_value=0.0)
¶
Prepare canonical host tensors for models and restore physical values.
Source code in src/samudra/utils/data.py
normalize_tensor_prognostic(data, fill_nan=True, fill_value=0.0)
¶
Normalize a prognostic tensor without masking or flattening.
Source code in src/samudra/utils/data.py
unnormalize_tensor_prognostic(data, fill_value=float('nan'))
¶
Unnormalize prognostic tensor and apply fill value to land cells.
Source code in src/samudra/utils/data.py
unnormalize_tensor_boundary(data, fill_value=float('nan'))
¶
Unnormalize boundary tensor.
Source code in src/samudra/utils/data.py
LoadStats(load_time_seconds)
dataclass
¶
Captures stats about loading a single ModelBatch object.
accumulated(stats)
classmethod
¶
Accumulate the stats across multiple LoadStats objects in a batch.
extract_wet_mask(data, prognostic_var_names, boundary_var_names)
¶
A mask for where the oceans are. Water is wet.
Source code in src/samudra/utils/data.py
flatten_masks(data)
¶
Adds level-wise mask variables from the stacked wet mask.
Source code in src/samudra/utils/data.py
unflatten_masks(data, num_levels)
¶
Adds a stacked wet mask xarray.DataArray from level-wise mask variables.
Source code in src/samudra/utils/data.py
spherical_area(data)
¶
Compute real grid cell areas on a spherical Earth.
Uses the spherical geometry formula: A = R² × Δλ × (sin(φ₂) - sin(φ₁))
where: - R is Earth's radius (6371 km) - Δλ is the longitude spacing in radians - φ₁, φ₂ are the latitude bounds of the cell in radians
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Dataset
|
Dataset containing lat/lon coordinates |
required |
Returns:
| Type | Description |
|---|---|
Grid
|
Grid cell areas in m² |
Source code in src/samudra/utils/data.py
get_inference_steps(data_source, input_steps, output_steps)
¶
Get the number of inference/rollout steps for the given time configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_source
|
CanonicalSource
|
The data source sliced to the inference time range |
required |
input_steps
|
int
|
Raw timesteps consumed by each model call. |
required |
output_steps
|
int
|
Future raw timesteps emitted by each model call. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
num_steps |
Total number of rolled-out inferences which fit into the time range |
Source code in src/samudra/utils/data.py
get_anomalies_vars(var_names)
¶
Get the variables that need to be computed for anomalies.
compute_anomalies(data, means, stds, anomalies_vars)
¶
Compute anomalies for the given variables.
Source code in src/samudra/utils/data.py
with_level_index_vars(data, depth_levels)
¶
Ensure variable names use a depth level index, not depth level value.
Source code in src/samudra/utils/data.py
with_depth_value_vars(data, data_layout)
¶
Inverse of with_level_index_vars: name 3D variables by depth value.
Renames the depth-resolved prognostic variables (<var>_<level_index>)
back to the OM4 <var>_lev_<depth> form (e.g. thetao_0 ->
thetao_lev_2_5). Which variables to rename is read directly off
data_layout.prognostic_var_names rather than inferred from the data, so
per-level masks (mask_<i>) and level-free prognostics (e.g. zos) are
never mistaken for depth-resolved variables by name alone.
Source code in src/samudra/utils/data.py
with_lat_lon_coords(data)
¶
Standardize dataset coordinates; prefer "lat"/"lon" over "y"/"x".
Source code in src/samudra/utils/data.py
stack_levels(data, data_layout)
¶
Reassemble a flattened OM4 dataset into analysis-ready, depth-stacked form.
Inverts the preprocessing flattening so downstream analysis does not have to:
per-level prognostic channels (thetao_0 ...) become thetao(lev, ...)
and the per-level mask_i become a single stacked wetmask. Grid
coordinates are preserved. This is the dataset-level counterpart to the eval
writer's reassembly, for putting ground-truth inputs on the same footing as
predictions.
Implemented as the inverse of with_level_index_vars followed by the existing
compact_dataset (stacks the _lev_ form) and unflatten_masks.