diff --git a/cryoet_data_portal_neuroglancer/models/json_generator.py b/cryoet_data_portal_neuroglancer/models/json_generator.py index 9c414fb..acd2721 100644 --- a/cryoet_data_portal_neuroglancer/models/json_generator.py +++ b/cryoet_data_portal_neuroglancer/models/json_generator.py @@ -5,7 +5,7 @@ import numpy as np -from cryoet_data_portal_neuroglancer.models.shader_builder import ImageShaderBuilder +from cryoet_data_portal_neuroglancer.shaders.shader_builder import ImageShaderBuilder def create_source( diff --git a/cryoet_data_portal_neuroglancer/shaders/__init__.py b/cryoet_data_portal_neuroglancer/shaders/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cryoet_data_portal_neuroglancer/shaders/image.py b/cryoet_data_portal_neuroglancer/shaders/image.py new file mode 100644 index 0000000..9545643 --- /dev/null +++ b/cryoet_data_portal_neuroglancer/shaders/image.py @@ -0,0 +1,69 @@ +from typing import Optional + +from cryoet_data_portal_neuroglancer.shaders.shader_builder import ShaderBuilder +from cryoet_data_portal_neuroglancer.utils import get_window_limits_from_contrast_limits + + +class ImageShaderBuilder(ShaderBuilder): + def __init__( + self, + contrast_limits: tuple[float, float], + threedee_contrast_limits: tuple[float, float], + window_limits: Optional[tuple[float, float]] = None, + threedee_window_limits: Optional[tuple[float, float]] = None, + contrast_name="contrast", + threedee_contrast_name="contrast3D", + ): + super().__init__() + self._contrast_limits = contrast_limits + self._window_limits = ( + window_limits if window_limits is not None else get_window_limits_from_contrast_limits(contrast_limits) + ) + self._threedee_contrast_limits = threedee_contrast_limits + self._threedee_window_limits = ( + threedee_window_limits + if threedee_window_limits is not None + else get_window_limits_from_contrast_limits(threedee_contrast_limits) + ) + self._contrast_name = contrast_name + self._threedee_contrast_name = threedee_contrast_name + + self._make_default_shader() + + def _make_default_shader(self): + self.add_to_shader_controls( + self.make_invertible_invlerp_component( + self._contrast_name, + self._contrast_limits, + self._window_limits, + ), + ) + self.add_to_shader_controls( + self.make_invertible_invlerp_component( + self._threedee_contrast_name, + self._threedee_contrast_limits, + self._threedee_window_limits, + ), + ) + self.add_to_shader_main("float outputValue;") + self._add_cross_section_and_vr_code( + [ + f"outputValue = get_{self._threedee_contrast_name}();", + "emitIntensity(outputValue);", + ], + [ + f"outputValue = get_{self._contrast_name}();", + ], + ) + self.add_to_shader_main("emitGrayscale(outputValue);") + + def _add_cross_section_and_vr_code( + self, + volume_rendering_code: str | list[str], + cross_section_code: str | list[str], + ): + self.add_to_shader_main("if (VOLUME_RENDERING) {") + self.add_to_shader_main(volume_rendering_code, indent=2) + self.add_to_shader_main("} else {") + self.add_to_shader_main(cross_section_code, indent=2) + self.add_to_shader_main("}") diff --git a/cryoet_data_portal_neuroglancer/models/shader_builder.py b/cryoet_data_portal_neuroglancer/shaders/shader_builder.py similarity index 53% rename from cryoet_data_portal_neuroglancer/models/shader_builder.py rename to cryoet_data_portal_neuroglancer/shaders/shader_builder.py index c002331..9b87daf 100644 --- a/cryoet_data_portal_neuroglancer/models/shader_builder.py +++ b/cryoet_data_portal_neuroglancer/shaders/shader_builder.py @@ -1,8 +1,6 @@ """Create GLSL shaders for Neuroglancer.""" -from typing import Any, Optional - -from cryoet_data_portal_neuroglancer.utils import get_window_limits_from_contrast_limits +from typing import Any TAB = " " @@ -82,68 +80,3 @@ def make_invertible_invlerp_component( def make_color_component(self, name: str, default_color: str) -> str: self._shader_controls[name] = default_color return f"#uicontrol vec3 {name} color" - - -class ImageShaderBuilder(ShaderBuilder): - def __init__( - self, - contrast_limits: tuple[float, float], - threedee_contrast_limits: tuple[float, float], - window_limits: Optional[tuple[float, float]] = None, - threedee_window_limits: Optional[tuple[float, float]] = None, - contrast_name="contrast", - threedee_contrast_name="contrast3D", - ): - super().__init__() - self._contrast_limits = contrast_limits - self._window_limits = ( - window_limits if window_limits is not None else get_window_limits_from_contrast_limits(contrast_limits) - ) - self._threedee_contrast_limits = threedee_contrast_limits - self._threedee_window_limits = ( - threedee_window_limits - if threedee_window_limits is not None - else get_window_limits_from_contrast_limits(threedee_contrast_limits) - ) - self._contrast_name = contrast_name - self._threedee_contrast_name = threedee_contrast_name - - self._make_default_shader() - - def _make_default_shader(self): - self.add_to_shader_controls( - self.make_invertible_invlerp_component( - self._contrast_name, - self._contrast_limits, - self._window_limits, - ), - ) - self.add_to_shader_controls( - self.make_invertible_invlerp_component( - self._threedee_contrast_name, - self._threedee_contrast_limits, - self._threedee_window_limits, - ), - ) - self.add_to_shader_main("float outputValue;") - self._add_cross_section_and_vr_code( - [ - f"outputValue = get_{self._threedee_contrast_name}();", - "emitIntensity(outputValue);", - ], - [ - f"outputValue = get_{self._contrast_name}();", - ], - ) - self.add_to_shader_main("emitGrayscale(outputValue);") - - def _add_cross_section_and_vr_code( - self, - volume_rendering_code: str | list[str], - cross_section_code: str | list[str], - ): - self.add_to_shader_main("if (VOLUME_RENDERING) {") - self.add_to_shader_main(volume_rendering_code, indent=2) - self.add_to_shader_main("} else {") - self.add_to_shader_main(cross_section_code, indent=2) - self.add_to_shader_main("}") diff --git a/tests/test_shader.py b/tests/test_shader.py index 4e93462..7a806ad 100644 --- a/tests/test_shader.py +++ b/tests/test_shader.py @@ -1,4 +1,5 @@ -from cryoet_data_portal_neuroglancer.models.shader_builder import ImageShaderBuilder, ShaderBuilder +from cryoet_data_portal_neuroglancer.shaders.image import ImageShaderBuilder +from cryoet_data_portal_neuroglancer.shaders.shader_builder import ShaderBuilder def test_get_default_image_shader():