google / neuroglancer

WebGL-based viewer for volumetric data
Apache License 2.0
1.06k stars 294 forks source link

Setting volumeRendering to string value with Python API fails #615

Closed dstansby closed 1 month ago

dstansby commented 2 months ago

In the example neuroglancer state below (taken from the web app), volumeRendering is set to a string ("max") indicating the rendering method. Trying to set this in the Python API using neuroglancer.ImageLayer(..., volume_rendering="max") fails with:

x = 'max'

    def validator_func(x):
        if not isinstance(x, wrapped_type):
>           raise TypeError(wrapped_type, x)
E           TypeError: (<class 'bool'>, 'max')
{
  "dimensions": {
    "x": [
      0.0000022200000000000003,
      "m"
    ],
    "y": [
      0.0000022200000000000003,
      "m"
    ],
    "z": [
      0.0000022200000000000003,
      "m"
    ]
  },
  "position": [
    1921,
    1921,
    17722.5
  ],
  "crossSectionScale": 10,
  "projectionOrientation": [
    0.27194035053253174,
    0.20693938434123993,
    0.04154021292924881,
    -0.9388817548751831
  ],
  "projectionScale": 7463.398606399528,
  "layers": [
    {
      "type": "image",
      "source": "n5://gs://ucl-hip-ct-35a68e99feaae8932b1d44da0358940b/FO-20-129/lung-left_upper_lobe/2.22um_VOI-05.2_bm05/",
      "tab": "rendering",
      "shaderControls": {
        "normalized": {
          "range": [
            12503,
            24946
          ]
        }
      },
      "volumeRendering": "max",
      "name": "FO-20-129_lung_left_upper_lobe_VOI-05.2_2.22um_bm05"
    }
  ],
  "showSlices": false,
  "selectedLayer": {
    "visible": true,
    "layer": "FO-20-129_lung_left_upper_lobe_VOI-05.2_2.22um_bm05"
  },
  "layout": "4panel"
}
seankmartin commented 2 months ago

Thanks for reporting this one @dstansby! Is this happening for you on main? I think the neuroglancer pypi package might be outdated and causing the issue if this isn't on main.

For me the code below launches up a viewer with max projection volume rendering selected for the image layer with a local build of neuroglancer's Python API from main:

import argparse
import webbrowser
import neuroglancer
import numpy as np
import neuroglancer.cli

def add_image_layer(state):
    shape = (50,) * 3
    dimensions = neuroglancer.CoordinateSpace(
        names=["x", "y", "z"], units="nm", scales=[40, 40, 40]
    )
    data = np.full(shape=shape, fill_value=255, dtype=np.uint8)
    local_volume = neuroglancer.LocalVolume(data, dimensions)
    state.layers.append(
        name="image",
        layer=neuroglancer.ImageLayer(
            source=local_volume,
            volume_rendering_mode="max",
            volume_rendering_depth_samples=400,
        ),
        shader="""
void main() {
    emitIntensity(1.0);
    emitRGBA(vec4(1.0, 1.0, 1.0, 0.01));
    }
    """,
    )
    state.layout = "3d"

def launch_nglancer():
    ap = argparse.ArgumentParser()
    neuroglancer.cli.add_server_arguments(ap)
    args = ap.parse_args()
    neuroglancer.cli.handle_server_arguments(args)
    viewer = neuroglancer.Viewer()
    return viewer

def main():
    viewer = launch_nglancer()
    with viewer.txn() as s:
        add_image_layer(s)
    webbrowser.open_new(viewer.get_viewer_url())

if __name__ == "__main__":
    main()
dstansby commented 2 months ago

Ahh thanks for checking, I'm on 2.39.1. Will try 2.40 soon and report back if it's fixed or still and issue 👍

dstansby commented 1 month ago

Thanks - looks good in 2.40