Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions sleap/gui/learning/features.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Temporary feature flags for in-progress functionality.

NOTE: This module is intentionally short-lived. The centroid-only models flag
gates UI for a feature whose *inference* half is still blocked on sleap-nn
(epic talmolab/sleap-nn#508 / PR #562). Once centroid-only inference lands and
the feature is fully supported, delete this module and its call sites
(grep for is_centroid_models_enabled).

In the GUI, this feature is enabled via the "Experimental Features" toggle in
the Help menu. The SLEAP_ENABLE_CENTROID_MODELS environment variable remains
available as a developer override.
"""

import os


def is_centroid_models_enabled(experimental_features: bool = False) -> bool:
"""Return True if the experimental centroid-only models UI is enabled.

Enabled when EITHER:
- experimental_features is True (the "Experimental Features" toggle in
the Help menu, threaded in by the caller), or
- the SLEAP_ENABLE_CENTROID_MODELS environment variable is truthy
("1"/"true"/"yes"/"on", case-insensitive).
"""
if experimental_features:
return True
return os.environ.get("SLEAP_ENABLE_CENTROID_MODELS", "").strip().lower() in (
"1",
"true",
"yes",
"on",
)
28 changes: 28 additions & 0 deletions sleap/skeletons/centroid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"description": "Single-node centroid skeleton for centroid-only models.",
"nx_graph": {
"directed": true,
"graph": {
"name": "centroid",
"num_edges_inserted": 0
},
"links": [],
"multigraph": true,
"nodes": [
{
"id": {
"py/object": "sleap.skeleton.Node",
"py/state": {
"py/tuple": [
"centroid",
1.0
]
}
}
}
]
},
"preview_image": {
"py/b64": "iVBORw0KGgoAAAANSUhEUgAAAMgAAACWCAYAAACb3McZAAABQElEQVR4nO3cwQ3CMBBFwUAZ1EMplEUp1EMbUAGLlOSvg5m5IhQJ/Lw+WFkWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiTvlH8M3lcX99+ux5vfmPBvLjHzCKT8TS7zzgmX9vTRxbvsd6JkijPRe4adLDBGmy9+5vmvQQSIPUYhZJnkCgIJCw9C5vimQJZILFK5IcgUBBIFAQyCTHHsesDIFAQSBQEAgUBAIFgUBBIFAQSEj3dXTX3zMEAgWBQEEgExx7HK9yBPLji1ccWQKBgkAapHZ50yNPIE32Xszi6OG1PwNsuZoujF4myABrF7k4+pkgB+DdvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwTO8NFK1ENqv3Iq8AAAAASUVORK5CYII="
}
}
43 changes: 43 additions & 0 deletions tests/gui/learning/test_features.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Tests for the temporary centroid-only models feature flag."""

import pytest

from sleap.gui.learning.features import is_centroid_models_enabled


def test_disabled_by_default(monkeypatch):
"""The flag is off when the env var is unset."""
monkeypatch.delenv("SLEAP_ENABLE_CENTROID_MODELS", raising=False)
assert is_centroid_models_enabled() is False
assert is_centroid_models_enabled(False) is False


@pytest.mark.parametrize("value", ["1", "true", "yes", "on"])
@pytest.mark.parametrize("transform", [str.lower, str.upper, str.title])
def test_enabled_for_truthy_values(monkeypatch, value, transform):
"""Truthy values enable the flag regardless of case."""
monkeypatch.setenv("SLEAP_ENABLE_CENTROID_MODELS", transform(value))
assert is_centroid_models_enabled() is True
assert is_centroid_models_enabled(False) is True


@pytest.mark.parametrize("value", ["0", "false", ""])
def test_disabled_for_falsy_values(monkeypatch, value):
"""Falsy values keep the flag off."""
monkeypatch.setenv("SLEAP_ENABLE_CENTROID_MODELS", value)
assert is_centroid_models_enabled() is False
assert is_centroid_models_enabled(False) is False


def test_enabled_by_experimental_features_without_env(monkeypatch):
"""The Experimental Features toggle enables the flag without the env var."""
monkeypatch.delenv("SLEAP_ENABLE_CENTROID_MODELS", raising=False)
assert is_centroid_models_enabled(experimental_features=True) is True
assert is_centroid_models_enabled(True) is True


@pytest.mark.parametrize("value", ["0", "false", ""])
def test_experimental_features_overrides_falsy_env(monkeypatch, value):
"""The Experimental Features toggle enables the flag even with a falsy env."""
monkeypatch.setenv("SLEAP_ENABLE_CENTROID_MODELS", value)
assert is_centroid_models_enabled(experimental_features=True) is True
29 changes: 29 additions & 0 deletions tests/gui/test_skeleton_templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Tests for shipped skeleton template files."""

import base64
import io
import json

from PIL import Image

import sleap.util
from sleap.gui.commands import OpenSkeleton


def test_centroid_template_loads_single_node():
"""The shipped centroid.json loads to a single-node, edge-less skeleton."""
path = sleap.util.get_package_file("skeletons/centroid.json")
skeleton = OpenSkeleton.load_skeleton(path)
assert skeleton.node_names == ["centroid"]
assert len(skeleton.edges) == 0


def test_centroid_template_preview_is_rgba():
"""The centroid.json preview image decodes to an RGBA PIL image."""
path = sleap.util.get_package_file("skeletons/centroid.json")
with open(path, "r") as f:
skeleton_data = json.load(f)

b64 = skeleton_data["preview_image"]["py/b64"]
image = Image.open(io.BytesIO(base64.b64decode(b64)))
assert image.mode == "RGBA"
Loading