Skip to content

Commit

Permalink
Skel source (#38)
Browse files Browse the repository at this point in the history
* start adding skel source

* add skeleton source and shader options
  • Loading branch information
ceesem authored Jul 15, 2024
1 parent 7c9c0b6 commit a65c2c3
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 1 deletion.
12 changes: 12 additions & 0 deletions src/nglui/easyviewer/ev_base/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ def add_segmentation_layer(self, layer_name, source, **kwargs):
with self.txn() as s:
s.layers[layer_name] = self._SegmentationLayer(source=source, **kwargs)

@abstractmethod
def append_source_to_segmentation_layer(self, layer_name, source):
pass

@abstractmethod
def add_skeleton_source(self, layer_name, source, shader_text=None):
pass

@abstractmethod
def set_skeleton_shader(self, layer_name, shader_text=None):
pass

def add_image_layer(self, layer_name, source, contrast_range=None, **kwargs):
"""Add segmentation layer to viewer instance.
Expand Down
20 changes: 19 additions & 1 deletion src/nglui/easyviewer/ev_base/mainline.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
from . import utils
from .base import SEGMENTATION_LAYER_TYPES, EasyViewerBase

DEFAULT_SKELETON_SHADER = """void main() {
emitDefault();
}
"""


def nanometer_dimension(resolution):
return neuroglancer.CoordinateSpace(
Expand Down Expand Up @@ -185,7 +190,7 @@ def append_source_to_segmentation_layer(self, layer_name, source):
layer_name : str
Name of an existing layer
source : str or list of str
Source or sources to add to the layer
Source or sources to add to the layer. Can be segment properties or skeleton sources, for example.
"""
if isinstance(source, str):
source = [source]
Expand All @@ -195,6 +200,19 @@ def append_source_to_segmentation_layer(self, layer_name, source):
for src in source:
s.layers[layer_name].source.append({"url": src})

def add_skeleton_source(self, layer_name, source, shader_text=None):
if shader_text is None:
shader_text = DEFAULT_SKELETON_SHADER
with self.txn() as s:
s.layers[layer_name].source.append({"url": source})
s.layers[layer_name].skeletonShader = shader_text

def set_skeleton_shader(self, layer_name, shader_text=None):
if shader_text is None:
shader_text = DEFAULT_SKELETON_SHADER
with self.txn() as s:
s.layers[layer_name].skeletonShader = shader_text

def set_view_options(
self,
show_slices: Optional[bool] = None,
Expand Down
9 changes: 9 additions & 0 deletions src/nglui/easyviewer/ev_base/seunglab.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ def add_segmentation_layer(self, layer_name, source, **kwargs):
warn("Only using first source in list for seung-lab segmentation layer")
super().add_segmentation_layer(layer_name, source, **kwargs)

def append_source_to_segmentation_layer(self, layer_name, source):
warn("Additional segment source is not supported in Seung-lab viewer")

def add_skeleton_source(self, layer_name, source, shader_text=None):
warn("Skeleton sources are not supported in Seung-lab viewer")

def set_skeleton_shader(self, layer_name, shader_text=None):
warn("Skeleton shaders are not supported in Seung-lab viewer")

def add_annotation_layer(
self,
layer_name=None,
Expand Down
20 changes: 20 additions & 0 deletions src/nglui/statebuilder/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ class SegmentationLayerConfig(LayerConfigBase):
Name of the mapping set, the key in the data dictionary for statebuilder. Optional, default is None.
segment_properties: str, optional
Location of a segment properties file. Optional, default is None.
skeleton_source: str, optional
Location of a skeleton source. Optional, default is None.
skeleton_shader: str, optional
Shader function for rendering skeletons, if set with `skeleton_source`. Optional, default is None.
"""

def __init__(
Expand All @@ -237,6 +241,8 @@ def __init__(
data_resolution=None,
mapping_set=None,
segment_properties=None,
skeleton_source=None,
skeleton_shader=None,
):
if name is None:
name = DEFAULT_SEG_LAYER
Expand All @@ -246,6 +252,8 @@ def __init__(
)
self._config["data_resolution"] = data_resolution
self._config["segment_properties"] = segment_properties
self._config["skeleton_source"] = skeleton_source
self._config["skeleton_shader"] = skeleton_shader

if selected_ids_column is not None or fixed_ids is not None:
self._selection_map = SelectionMapper(
Expand Down Expand Up @@ -305,6 +313,14 @@ def source(self):
else:
return out

@property
def skeleton_source(self):
return self._config.get("skeleton_source", None)

@property
def skeleton_shader(self):
return self._config.get("skeleton_shader", None)

def add_segment_propeties(
self,
segment_property: str,
Expand Down Expand Up @@ -447,6 +463,10 @@ def add_selection_map(

def _add_layer(self, viewer):
viewer.add_segmentation_layer(self.name, self.source)
if self.skeleton_source is not None:
viewer.add_skeleton_source(
self.name, self.skeleton_source, self.skeleton_shader
)

def _specific_rendering(
self,
Expand Down
25 changes: 25 additions & 0 deletions tests/test_statebuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ def anno_layer_basic():
return anno_layer


@pytest.fixture
def skel_source():
return "precomputed://https://skeleton-source/"


@pytest.fixture
def skel_shader_text():
return "void main() { emitRGB(vec3(1.0, 0.0, 0.0)); }"


def test_basic(image_layer, seg_layer_basic, anno_layer_basic):
sb = StateBuilder(
[image_layer, seg_layer_basic, anno_layer_basic], target_site="seunglab"
Expand Down Expand Up @@ -355,3 +365,18 @@ def test_timestamp(seg_path_graphene, target_site):
else:
# Not implemented yet in cave-explorer
assert True


@pytest.mark.parametrize("target_site", [None, "seunglab", "cave-explorer"])
def test_skeleton_source(seg_path_graphene, skel_source, target_site, skel_shader_text):
seg = SegmentationLayerConfig(
seg_path_graphene, skeleton_source=skel_source, skeleton_shader=skel_shader_text
)
sb = StateBuilder([seg], target_site=target_site)
state = sb.render_state(return_as="dict")
if target_site == "cave-explorer":
assert state["layers"][0]["source"][1]["url"] == skel_source
assert state["layers"][0]["skeletonRendering"]["shader"] == skel_shader_text
else:
# Not implemented in older versions
assert True

0 comments on commit a65c2c3

Please sign in to comment.