Skip to content

webknossos.annotation.annotation

Annotations can contain annotated data in two forms:

  • skeleton data, as provided by the Skeleton class, and
  • volume annotation layers (or volume layers short), which can be exported as a SegmentationLayer, see export_volume_layer_to_dataset() and temporary_volume_layer_copy().

Usually, annotations should be created manually in the WEBKNOSSOS interface and can be downloaded using Annotation.download(). The downloaded instance is not persisted to disk automatically, please use save() for this purpose. The general purpose file format is .zip files containing an .nml file with meta-information and the skeleton data and also containing inner .zip files for the volume layers. For skeleton-only annotations without volume layers .nml files can be used directly. Both formats are compatible with the WEBKNOSSOS up- and downloads.

To prepare volume annotations in the code for correction of segmentation data in the WEBKNOSSOS interface, please use add_volume_layer() with the fallback_layer argument, referencing a segmentation layer that is available on WEBKNOSSOS (e.g. using the Dataset upload before). Correcting segmentations using fallback layers is much more efficient, adding volume annotation data programmatically is discouraged therefore.

Classes:

  • Annotation

    Represents an annotation from WEBKNOSSOS containing skeleton and/or volume data.

  • AnnotationState

    This Enum contains the state of annotations belonging to tasks.

  • AnnotationType

    Annotations can be of different types which has to be specified when using Annotation.download()

  • SegmentInformation

Annotation

Represents an annotation from WEBKNOSSOS containing skeleton and/or volume data.

The Annotation class provides functionality to:

  1. Load/save annotations from/to .nml or .zip files
  2. Download/upload annotations from/to WEBKNOSSOS
  3. Work with skeleton data and volume layers
  4. Export volume layers to datasets

Attributes:

Examples:

Create a new annotation:

ann = Annotation(
    name="my_annotation",
    dataset_name="sample_dataset",
    voxel_size=(11.2, 11.2, 25.0)
)

Load annotation from file:

ann = Annotation.load("annotation.nml")

Download from WEBKNOSSOS:

ann = Annotation.download("annotation_id")

Save annotation:

ann.save("annotation.zip")

Add volume layer:

ann.add_volume_layer(
    name="segmentation",
    fallback_layer="segmentation_layer"
)

Methods:

Attributes:

annotation_id class-attribute instance-attribute

annotation_id: Optional[str] = None

dataset_name property writable

dataset_name: str

Name of the dataset this annotation belongs to.

Proxies to skeleton.dataset_name.

description property writable

description: Optional[str]

Optional description of the annotation.

Proxies to skeleton.description.

edit_position class-attribute instance-attribute

edit_position: Optional[Vector3] = None

edit_rotation class-attribute instance-attribute

edit_rotation: Optional[Vector3] = None

metadata class-attribute instance-attribute

metadata: Dict[str, str] = Factory(dict)

name instance-attribute

name: str

organization_id property writable

organization_id: Optional[str]

ID of the organization owning this annotation.

Proxies to skeleton.organization_id.

owner_name class-attribute instance-attribute

owner_name: Optional[str] = None

scale property writable

scale: Tuple[float, float, float]

Deprecated, please use voxel_size.

skeleton class-attribute instance-attribute

skeleton: Skeleton = None

task_bounding_box class-attribute instance-attribute

task_bounding_box: Optional[NDBoundingBox] = None

time class-attribute instance-attribute

time: Optional[int] = ib(factory=time_since_epoch_in_ms)

user_bounding_boxes class-attribute instance-attribute

user_bounding_boxes: List[NDBoundingBox] = Factory(list)

username property writable

username: Optional[str]

Deprecated property for accessing owner_name.

Use owner_name instead.

voxel_size property writable

voxel_size: Tuple[float, float, float]

Voxel dimensions in nanometers (x, y, z).

Proxies to skeleton.voxel_size.

zoom_level class-attribute instance-attribute

zoom_level: Optional[float] = None

add_volume_layer

add_volume_layer(name: str, fallback_layer: Union[Layer, str, None] = None, volume_layer_id: Optional[int] = None) -> None

Adds a new volume layer to the annotation.

Volume layers can be used to store segmentation data. Using fallback layers is recommended for better performance in WEBKNOSSOS.

Parameters:

  • name (str) –

    Name of the volume layer.

  • fallback_layer (Union[Layer, str, None], default: None ) –

    Optional reference to existing segmentation layer in WEBKNOSSOS. Can be Layer instance or layer name.

  • volume_layer_id (Optional[int], default: None ) –

    Optional explicit ID for the layer. Auto-generated if not provided.

Raises:

  • AssertionError

    If volume_layer_id already exists.

  • AssertionError

    If fallback_layer is provided but not a segmentation layer.

Examples:

# Add basic layer
annotation.add_volume_layer("segmentation")

# Add with fallback
annotation.add_volume_layer("segmentation", fallback_layer="base_segmentation")

delete_volume_layer

delete_volume_layer(volume_layer_name: Optional[str] = None, volume_layer_id: Optional[int] = None) -> None

Removes a volume layer from the annotation.

Parameters:

  • volume_layer_name (Optional[str], default: None ) –

    Name of the layer to delete if multiple exist.

  • volume_layer_id (Optional[int], default: None ) –

    ID of the layer to delete if multiple exist.

Raises:

  • ValueError

    If neither name nor ID is provided when multiple layers exist.

  • AssertionError

    If specified layer doesn't exist.

Examples:

# Delete by name
annotation.delete_volume_layer("unused_layer")

# Delete by ID
annotation.delete_volume_layer(volume_layer_id=2)

download classmethod

download(annotation_id_or_url: str, annotation_type: Union[str, AnnotationType, None] = None, webknossos_url: Optional[str] = None, *, skip_volume_data: bool = False) -> Annotation
download(annotation_id_or_url: str, annotation_type: Union[str, AnnotationType, None] = None, webknossos_url: Optional[str] = None, *, skip_volume_data: bool = False, _return_context: bool) -> Tuple[Annotation, ContextManager[None]]
download(annotation_id_or_url: str, annotation_type: Union[str, AnnotationType, None] = None, webknossos_url: Optional[str] = None, *, skip_volume_data: bool = False, _return_context: bool = False) -> Union[Annotation, Tuple[Annotation, ContextManager[None]]]

Downloads an annotation from WEBKNOSSOS.

Parameters:

  • annotation_id_or_url (str) –

    Either an annotation ID or complete WEBKNOSSOS URL. Example URL: https://webknossos.org/annotations/[id]

  • annotation_type (Union[str, AnnotationType, None], default: None ) –

    Deprecated. Type of annotation (no longer required).

  • webknossos_url (Optional[str], default: None ) –

    Optional custom WEBKNOSSOS instance URL.

  • skip_volume_data (bool, default: False ) –

    If True, omits downloading volume layer data.

  • _return_context (bool, default: False ) –

    Internal use only.

Returns:

  • Annotation ( Union[Annotation, Tuple[Annotation, ContextManager[None]]] ) –

    The downloaded annotation instance.

Examples:

# Download by ID
ann = Annotation.download("5f7d3a...")

# Download by URL
ann = Annotation.download("https://webknossos.org/annotations/5f7d3a...")

# Skip volume data
ann = Annotation.download("5f7d3a...", skip_volume_data=True)

export_volume_layer_to_dataset

export_volume_layer_to_dataset(dataset: Dataset, layer_name: str = 'volume_layer', volume_layer_name: Optional[str] = None, volume_layer_id: Optional[int] = None) -> SegmentationLayer

Exports a volume layer to a dataset.

Creates a new layer in the target dataset containing the volume annotation data.

Parameters:

  • dataset (Dataset) –

    Target Dataset instance.

  • layer_name (str, default: 'volume_layer' ) –

    Name for the new layer (default: "volume_layer").

  • volume_layer_name (Optional[str], default: None ) –

    Name of source volume layer if multiple exist.

  • volume_layer_id (Optional[int], default: None ) –

    ID of source volume layer if multiple exist.

Returns:

  • SegmentationLayer ( SegmentationLayer ) –

    The created layer in the target dataset.

Raises:

  • AssertionError

    If specified volume layer doesn't exist.

  • AssertionError

    If volume layer data is not available.

Examples:

# Export to dataset
layer = annotation.export_volume_layer_to_dataset(
    dataset,
    layer_name="exported_segmentation"
)

get_remote_annotation_dataset

get_remote_annotation_dataset() -> Dataset

Returns a streamed dataset of the annotation from WEBKNOSSOS.

Creates a remote dataset that includes fallback layers and potentially any active agglomerate mappings. Requires the annotation to be already stored in WEBKNOSSOS.

Returns:

  • Dataset ( Dataset ) –

    Remote dataset instance representing the annotation.

Raises:

  • ValueError

    If annotation_id is not set (annotation not in WEBKNOSSOS).

Examples:

# Stream annotation as dataset
dataset = annotation.get_remote_annotation_dataset()

# Access layers
layer = dataset.get_layer("segmentation")

Note: After an agglomerate mapping was activated in WEBKNOSSOS, it is applied to this method as soon as the first volume editing action is done. Note that this behavior might change in the future.

get_remote_base_dataset

get_remote_base_dataset(sharing_token: Optional[str] = None, webknossos_url: Optional[str] = None) -> RemoteDataset

Returns a remote dataset connection to the base dataset.

Creates a connection to the dataset referenced by this annotation.

Parameters:

  • sharing_token (Optional[str], default: None ) –

    Optional token for accessing private datasets.

  • webknossos_url (Optional[str], default: None ) –

    Optional custom WEBKNOSSOS instance URL.

Returns:

  • RemoteDataset ( RemoteDataset ) –

    Connection to the base dataset.

Examples:

# Connect to base dataset
dataset = annotation.get_remote_base_dataset()

# With sharing token
dataset = annotation.get_remote_base_dataset(
    sharing_token="abc123"
)

get_volume_layer_names

get_volume_layer_names() -> Iterable[str]

Returns names of all volume layers in the annotation.

Returns:

  • Iterable[str]

    Iterable[str]: Iterator of volume layer names.

Examples:

# Print all layer names
for name in annotation.get_volume_layer_names():
    print(f"Found layer: {name}")

get_volume_layer_segments

get_volume_layer_segments(volume_layer_name: Optional[str] = None, volume_layer_id: Optional[int] = None) -> Dict[int, SegmentInformation]

Returns segment information for a volume layer.

Returns a mutable dictionary mapping segment IDs to their metadata. Changes to the returned dictionary are reflected in the annotation locally.

Parameters:

  • volume_layer_name (Optional[str], default: None ) –

    Name of the target volume layer if multiple exist.

  • volume_layer_id (Optional[int], default: None ) –

    ID of the target volume layer if multiple exist.

Returns:

  • Dict[int, SegmentInformation]

    Dict[int, SegmentInformation]: Dictionary mapping segment IDs to their information.

Raises:

  • ValueError

    If neither name nor ID is provided when multiple layers exist.

  • AssertionError

    If specified layer doesn't exist.

Examples:

# Get segments for a layer
segments = annotation.get_volume_layer_segments("segmentation_layer")

# Update segment name
segments[1].name = "Cell A"

Note: Any changes performed on the online version of the annotaiton in webknossos are not synced automatically. The annotation needs to be re-downloaded to update segment information.

load classmethod

load(annotation_path: Union[str, PathLike]) -> Annotation

Loads an annotation from a file.

Supports loading from: - .nml files (skeleton-only annotations) - .zip files (containing .nml and optional volume layers)

Parameters:

  • annotation_path (Union[str, PathLike]) –

    Path to the .nml or .zip file.

Returns:

  • Annotation ( Annotation ) –

    The loaded annotation instance.

Raises:

  • AssertionError

    If the file doesn't exist or has invalid extension.

  • RuntimeError

    If the file format is invalid.

Examples:

# Load from NML
ann = Annotation.load("annotation.nml")

# Load from ZIP
ann = Annotation.load("annotation.zip")

merge_fallback_layer

merge_fallback_layer(target: Path, dataset_directory: Path, volume_layer_name: Optional[str] = None, executor: Optional[Executor] = None) -> None

Merges volume annotations with their fallback layer.

Creates a new dataset containing the merged result of volume annotations and fallback layer data.

Parameters:

  • target (Path) –

    Output path for merged dataset.

  • dataset_directory (Path) –

    Directory containing the fallback dataset.

  • volume_layer_name (Optional[str], default: None ) –

    Name of volume layer to merge if multiple exist.

  • executor (Optional[Executor], default: None ) –

    Optional executor for parallel processing.

Raises:

  • AssertionError

    If no volume layers exist.

  • AssertionError

    If specified volume layer doesn't exist.

Examples:

# Merge annotations with fallback
annotation.merge_fallback_layer(
    Path("merged_dataset"),
    Path("original_dataset")
)

open_as_remote_dataset classmethod

open_as_remote_dataset(annotation_id_or_url: str, annotation_type: Union[str, AnnotationType, None] = None, webknossos_url: Optional[str] = None) -> Dataset

save

save(path: Union[str, PathLike]) -> None

Saves the annotation to a file.

For skeleton-only annotations, saves as .nml file. For annotations with volume layers, saves as .zip file containing .nml and layers.

Parameters:

  • path (Union[str, PathLike]) –

    Target path ending in .nml or .zip (.zip required if annotation contains volume layers)

Raises:

  • AssertionError

    If path has invalid extension or trying to save volume layers to .nml file.

Examples:

# Save skeleton-only annotation
annotation.save("skeleton.nml")

# Save with volume layers
annotation.save("full_annotation.zip")

temporary_volume_layer_copy

temporary_volume_layer_copy(volume_layer_name: Optional[str] = None, volume_layer_id: Optional[int] = None, read_only: bool = True) -> Iterator[SegmentationLayer]

Creates a temporary copy of a volume layer as a dataset.

Context manager that provides temporary access to volume layer data as a SegmentationLayer.

Parameters:

  • volume_layer_name (Optional[str], default: None ) –

    Name of target layer if multiple exist.

  • volume_layer_id (Optional[int], default: None ) –

    ID of target layer if multiple exist.

  • read_only (bool, default: True ) –

    If True, prevents modifications to the layer.

Yields:

  • SegmentationLayer ( SegmentationLayer ) –

    Temporary layer containing volume data.

Examples:

# Temporarily access volume data
with annotation.temporary_volume_layer_copy("segmentation") as layer:
    data = layer.get_mag(1).read()

upload

upload() -> str

Uploads the annotation to WEBKNOSSOS.

Uses the current webknossos_context for authentication and target instance. See webknossos.webknossos_context() for configuration.

Returns:

  • str ( str ) –

    URL of the uploaded annotation in WEBKNOSSOS.

Raises:

  • RuntimeError

    If no valid authentication is configured.

Examples:

with webknossos.webknossos_context(token="my_token"):
    url = annotation.upload()
    print(f"Uploaded to: {url}")

AnnotationState

Bases: Enum

This Enum contains the state of annotations belonging to tasks. Can be retrieved via Task instances, getting AnnotationInfo from task.get_annotation_infos().

Attributes:

ACTIVE class-attribute instance-attribute

ACTIVE = 'Active'

CANCELLED class-attribute instance-attribute

CANCELLED = 'Cancelled'

FINISHED class-attribute instance-attribute

FINISHED = 'Finished'

INITIALIZING class-attribute instance-attribute

INITIALIZING = 'Initializing'

AnnotationType

Bases: Enum

Annotations can be of different types which has to be specified when using Annotation.download() with an annotation id.

Attributes:

  • EXPLORATIONAL

    Explorational annotations are all annotations created without the task system, e.g.

  • TASK

    The Task type is automatically assigned to all annotations that are instances of a task.

EXPLORATIONAL class-attribute instance-attribute

EXPLORATIONAL = 'Explorational'

Explorational annotations are all annotations created without the task system, e.g. by uploading an annotation or using the "Create Annotation" Button in the dataset view in webknossos.

TASK class-attribute instance-attribute

TASK = 'Task'

The Task type is automatically assigned to all annotations that are instances of a task. See also Task.

SegmentInformation

Attributes:

anchor_position instance-attribute

anchor_position: Optional[Vec3Int]

color instance-attribute

color: Optional[Vector4]

name instance-attribute

name: Optional[str]