nwb
sleap_io.io.nwb
¶
Harmonization layer for NWB I/O operations.
This module provides a unified interface for reading and writing SLEAP data to/from NWB files, automatically detecting and routing to the appropriate backend based on the data format (annotations vs predictions).
Classes:
Name | Description |
---|---|
NwbFormat |
NWB format types for SLEAP data. |
Functions:
Name | Description |
---|---|
load_nwb |
Load an NWB dataset as a SLEAP Labels object. |
save_nwb |
Save a SLEAP dataset to NWB format. |
NwbFormat
¶
load_nwb(filename)
¶
Load an NWB dataset as a SLEAP Labels object.
Automatically detects whether the file contains PoseTraining (annotations) or PoseEstimation (predictions) data and uses the appropriate backend.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
filename
|
Union[str, Path]
|
Path to an NWB file (.nwb). |
required |
Returns:
Type | Description |
---|---|
Labels
|
The dataset as a Labels object. |
Raises:
Type | Description |
---|---|
ValueError
|
If the NWB file doesn't contain recognized pose data. |
Source code in sleap_io/io/nwb.py
def load_nwb(filename: Union[str, Path]) -> Labels:
"""Load an NWB dataset as a SLEAP Labels object.
Automatically detects whether the file contains PoseTraining (annotations)
or PoseEstimation (predictions) data and uses the appropriate backend.
Args:
filename: Path to an NWB file (.nwb).
Returns:
The dataset as a Labels object.
Raises:
ValueError: If the NWB file doesn't contain recognized pose data.
"""
from sleap_io.io import nwb_annotations, nwb_predictions
filename = Path(filename)
# Check what type of data is in the file
with h5py.File(filename, "r") as f:
# Check for behavior processing module with PoseTraining (annotations)
if "processing" in f and "behavior" in f["processing"]:
behavior = f["processing"]["behavior"]
# Check for PoseTraining (annotations)
if "PoseTraining" in behavior:
return nwb_annotations.load_labels(filename)
# Check for PoseEstimation in behavior module (old format)
for key in behavior.keys():
if key not in ["PoseTraining", "Skeletons"]:
if "neurodata_type" in behavior[key].attrs:
if behavior[key].attrs["neurodata_type"] == "PoseEstimation":
return nwb_predictions.read_nwb(filename)
# Check for PoseEstimation in separate processing modules (predictions)
if "processing" in f:
for module_name in f["processing"].keys():
if module_name != "behavior": # Skip behavior module (already checked)
module = f["processing"][module_name]
# Look for PoseEstimation containers
for key in module.keys():
if "neurodata_type" in module[key].attrs:
if module[key].attrs["neurodata_type"] == "PoseEstimation":
return nwb_predictions.read_nwb(filename)
raise ValueError(
f"NWB file '{filename}' does not contain recognized pose data "
"(neither PoseTraining nor PoseEstimation found in behavior module)"
)
save_nwb(labels, filename, nwb_format=NwbFormat.AUTO)
¶
Save a SLEAP dataset to NWB format.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
labels
|
Labels
|
A SLEAP Labels object to save. |
required |
filename
|
Union[str, Path]
|
Path to NWB file to save to. Must end in '.nwb'. |
required |
nwb_format
|
Union[NwbFormat, str]
|
Format to use for saving. Options are: - "auto" (default): Automatically detect based on data - "annotations": Save training annotations (PoseTraining) - "annotations_export": Export annotations with video frames - "predictions": Save predictions (PoseEstimation) |
AUTO
|
Raises:
Type | Description |
---|---|
ValueError
|
If an invalid format is specified. |
Source code in sleap_io/io/nwb.py
def save_nwb(
labels: Labels,
filename: Union[str, Path],
nwb_format: Union[NwbFormat, str] = NwbFormat.AUTO,
) -> None:
"""Save a SLEAP dataset to NWB format.
Args:
labels: A SLEAP Labels object to save.
filename: Path to NWB file to save to. Must end in '.nwb'.
nwb_format: Format to use for saving. Options are:
- "auto" (default): Automatically detect based on data
- "annotations": Save training annotations (PoseTraining)
- "annotations_export": Export annotations with video frames
- "predictions": Save predictions (PoseEstimation)
Raises:
ValueError: If an invalid format is specified.
"""
from sleap_io.io import nwb_annotations, nwb_predictions
filename = Path(filename)
# Convert string to enum if needed
if isinstance(nwb_format, str):
try:
nwb_format = NwbFormat(nwb_format)
except ValueError:
raise ValueError(
f"Invalid NWB format: '{nwb_format}'. "
f"Must be one of: {', '.join(f.value for f in NwbFormat)}"
)
# Auto-detect format if needed
if nwb_format == NwbFormat.AUTO:
# Check if there are any user instances
has_user_instances = any(lf.has_user_instances for lf in labels.labeled_frames)
if has_user_instances:
nwb_format = NwbFormat.ANNOTATIONS
else:
nwb_format = NwbFormat.PREDICTIONS
# Route to appropriate backend
if nwb_format == NwbFormat.ANNOTATIONS:
nwb_annotations.save_labels(labels, filename)
elif nwb_format == NwbFormat.ANNOTATIONS_EXPORT:
# Use export_labels for the export format
output_dir = filename.parent
nwb_filename = filename.name
nwb_annotations.export_labels(
labels,
output_dir=output_dir,
nwb_filename=nwb_filename,
clean=True, # Clean up intermediate files
)
elif nwb_format == NwbFormat.PREDICTIONS:
# Always overwrite (no append)
nwb_predictions.write_nwb(labels, filename)
else:
raise ValueError(f"Unexpected NWB format: {nwb_format}")