Skip to content

Commit

Permalink
feat: more control over image JSON generator
Browse files Browse the repository at this point in the history
  • Loading branch information
seankmartin committed Sep 12, 2024
1 parent 25b7861 commit e15bace
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
22 changes: 14 additions & 8 deletions cryoet_data_portal_neuroglancer/models/json_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,16 @@ class ImageJSONGenerator(RenderingJSONGenerator):
"""Generates JSON Neuroglancer config for Image volume."""

size: dict[str, float]
contrast_limits: tuple[float, float] = (-64, 64)
contrast_limits: tuple[float, float] | None = None
threedee_contrast_limits: tuple[float, float] | None = None
start: dict[str, float] = None
mean: float = None
rms: float = None
is_visible: bool = True
has_volume_rendering_shader: bool = False
volume_rendering_depth_samples: int = 256 # Ideally, this should be a power of 2
volume_rendering_is_visible: bool = False
volume_rendering_gain: float = 0.0

def __post_init__(self):
self._type = RenderingTypes.IMAGE
Expand All @@ -96,18 +99,19 @@ def _compute_contrast_limits(self) -> tuple[float, float]:
return (self.mean - width, self.mean + width)

def _create_shader_and_controls(self) -> dict[str, Any]:
contrast_limits = self._compute_contrast_limits()
if self.contrast_limits is None:
self.contrast_limits = self._compute_contrast_limits()
if self.threedee_contrast_limits is None:
self.threedee_contrast_limits = self.contrast_limits
self.threedee_contrast_limits = self.threedee_contrast_limits[1], self.threedee_contrast_limits[0]
if self.has_volume_rendering_shader:
# At the moment these are the same limits,
# but in the future the calculation might change for 3D rendering
threedee_contrast_limits = contrast_limits
shader_builder = ImageWithVolumeRenderingShaderBuilder(
contrast_limits=contrast_limits,
threedee_contrast_limits=threedee_contrast_limits,
contrast_limits=self.contrast_limits,
threedee_contrast_limits=self.threedee_contrast_limits,
)
else:
shader_builder = ImageShaderBuilder(
contrast_limits=contrast_limits,
contrast_limits=self.contrast_limits,
)
return shader_builder.build()

Expand All @@ -129,6 +133,8 @@ def generate_json(self) -> dict:
"opacity": 0.51,
"tab": "rendering",
"visible": self.is_visible,
"volumeRendering": "on" if self.volume_rendering_is_visible else "off",
"volumeRenderingGain": self.volume_rendering_gain,
}
if self.has_volume_rendering_shader:
config["volumeRenderingDepthSamples"] = self.volume_rendering_depth_samples
Expand Down
21 changes: 21 additions & 0 deletions cryoet_data_portal_neuroglancer/state_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,18 @@ def generate_image_layer(
rms: float = None,
is_visible: bool = True,
has_volume_rendering_shader: bool = False,
twodee_contrast_limits: tuple[float, float] | None = None,
threedee_contrast_limits: tuple[float, float] | None = None,
volume_rendering_is_visible: bool = False,
volume_rendering_gain: float = -7.8,
) -> dict[str, Any]:
"""Generates JSON for an image layer with optional contrast limits.
Note, if twodee_contrast_limits are not provided, the contrast limits will be calculated using the mean and rms values. If threedee_contrast_limits are not provided, the contrast limits will be the same as the twodee_contrast_limits.
"""
# If volume rendering is visible, set the flag to True for the relevant shader
if not has_volume_rendering_shader and volume_rendering_is_visible:
has_volume_rendering_shader = True
source, name, url, _, scale = _setup_creation(source, name, url, scale=scale)
return ImageJSONGenerator(
source=source,
Expand All @@ -124,6 +135,10 @@ def generate_image_layer(
rms=rms,
is_visible=is_visible,
has_volume_rendering_shader=has_volume_rendering_shader,
contrast_limits=twodee_contrast_limits,
threedee_contrast_limits=threedee_contrast_limits,
volume_rendering_is_visible=volume_rendering_is_visible,
volume_rendering_gain=volume_rendering_gain,
).to_json()


Expand Down Expand Up @@ -153,8 +168,13 @@ def combine_json_layers(
scale: tuple[float, float, float] | list[float] | float,
units: str = "m",
projection_quaternion: list[float] = None,
set_slices_visible_in_3d: bool | None = None,
) -> dict[str, Any]:
"""Note, if set_slices_visible_in_3d is not provided, it will be set to False if there are any image layers in the list with volume rendering."""
image_layers = [layer for layer in layers if layer["type"] == "image"]
if set_slices_visible_in_3d is None:
set_slices_visible_in_3d = not any(layer["volumeRendering"] == "on" for layer in image_layers)

scale = get_scale(scale)
if not projection_quaternion:
projection_quaternion = Rotation.from_euler(seq="xyz", angles=(45, 0, 0), degrees=True).as_quat()
Expand All @@ -169,6 +189,7 @@ def combine_json_layers(
},
"crossSectionBackgroundColor": "#000000",
"layout": "4panel",
"showSlices": set_slices_visible_in_3d,
}
if len(image_layers) > 0 and "_position" in image_layers[0]:
combined_json["position"] = image_layers[0]["_position"]
Expand Down

0 comments on commit e15bace

Please # to comment.