viewer = neuroglancer.Viewer()

"""
Explanation: Create a new (initially empty) viewer.  This starts a webserver in a background thread, which serves a copy of the Neuroglancer client, and which also can serve local volume data and handles sending and receiving Neuroglancer state updates.
End of explanation
"""


viewer

"""
Explanation: Print a link to the viewer (only valid while the notebook kernel is running). Note that while the Viewer is running, anyone with the link can obtain any authentication credentials that the neuroglancer Python module obtains. Therefore, be very careful about sharing the link, and keep in mind that sharing the notebook will likely also share viewer links.
End of explanation
"""


with viewer.txn() as s:
  s.layers['image'] = neuroglancer.ImageLayer(source='precomputed://gs://neuroglancer-public-data/flyem_fib-25/image')
  s.layers['segmentation'] = neuroglancer.SegmentationLayer(source='precomputed://gs://neuroglancer-public-data/flyem_fib-25/ground_truth', selected_alpha=0.3)
  

"""
Explanation: Add some example layers using the precomputed data source (HHMI Janelia FlyEM FIB-25 dataset).
End of explanation
"""


with viewer.txn() as s:
    s.voxel_coordinates = [3000, 3000, 3000]

"""
Explanation: Display a numpy array as an additional layer.  A reference to the numpy array is kept only as long as the layer remains in the viewer.
Move the viewer position.
End of explanation
"""


with viewer.txn() as s:
    s.layers['segmentation'].visible = False

import cloudvolume
image_vol = cloudvolume.CloudVolume('https://storage.googleapis.com/neuroglancer-public-data/flyem_fib-25/image',
                                    mip=0, bounded=True, progress=False, provenance={})
a = np.zeros((200,200,200), np.uint8)
def make_thresholded(threshold):
  a[...] = np.transpose(image_vol[3000:3200,3000:3200,3000:3200][...,0], (2,1,0)) > threshold
make_thresholded(110)
# This volume handle can be used to notify the viewer that the data has changed.
volume = neuroglancer.LocalVolume(a, voxel_size=[8, 8, 8], voxel_offset=[3000, 3000, 3000])
with viewer.txn() as s:
  s.layers['overlay'] = neuroglancer.ImageLayer(
        source=volume,
      # Define a custom shader to display this mask array as red+alpha.
        shader="""
void main() {
  float v = toNormalized(getDataValue(0)) * 255.0;
  emitRGBA(vec4(v, 0.0, 0.0, v));
}
""",
    )

"""
Explanation: Hide the segmentation layer.
End of explanation
"""


make_thresholded(100)
volume.invalidate()

"""
Explanation: Modify the overlay volume, and call invalidate() to notify the Neuroglancer client.
End of explanation
"""


with viewer.txn() as s:
    s.layers['segmentation'].segments.update([1752, 88847])
    s.layers['segmentation'].visible = True

"""
Explanation: Select a couple segments.
End of explanation
"""


viewer.state

"""
Explanation: Print the neuroglancer viewer state.  The Neuroglancer Python library provides a set of Python objects that wrap the JSON-encoded viewer state.  viewer.state returns a read-only snapshot of the state.  To modify the state, use the viewer.txn() function, or viewer.set_state.
End of explanation
"""


viewer.state.layers['segmentation'].segments

"""
Explanation: Print the set of selected segments.|
End of explanation
"""


import copy
new_state = copy.deepcopy(viewer.state)
new_state.layers['segmentation'].segments.add(10625)
viewer.set_state(new_state)

"""
Explanation: Update the state by calling set_state directly.
End of explanation
"""


num_actions = 0
def my_action(s):
    global num_actions
    num_actions += 1
    with viewer.config_state.txn() as st:
      st.status_messages['hello'] = ('Got action %d: mouse position = %r' %
                                     (num_actions, s.mouse_voxel_coordinates))
    print('Got my-action')
    print('  Mouse position: %s' % (s.mouse_voxel_coordinates,))
    print('  Layer selected values: %s' % (s.selected_values,))
viewer.actions.add('my-action', my_action)
with viewer.config_state.txn() as s:
    s.input_event_bindings.viewer['keyt'] = 'my-action'
    s.status_messages['hello'] = 'Welcome to this example'

"""
Explanation: Bind the 't' key in neuroglancer to a Python action.
End of explanation
"""


with viewer.txn() as s:
    s.layout = '3d'
    s.perspective_zoom = 300

"""
Explanation: Change the view layout to 3-d.
End of explanation
"""


with viewer.config_state.txn() as s:
    s.show_ui_controls = False
    s.show_panel_borders = False
    s.viewer_size = [1000, 1000]
from ipywidgets import Image
screenshot_image = Image(value=viewer.screenshot().screenshot.image)
with viewer.config_state.txn() as s:
    s.show_ui_controls = True
    s.show_panel_borders = True
    s.viewer_size = None
screenshot_image

"""
Explanation: Take a screenshot (useful for creating publication figures, or for generating videos).  While capturing the screenshot, we hide the UI and specify the viewer size so that we get a result independent of the browser size.
End of explanation
"""


with viewer.txn() as s:
    s.layout = neuroglancer.row_layout(
        [neuroglancer.LayerGroupViewer(layers=['image', 'overlay']),
         neuroglancer.LayerGroupViewer(layers=['segmentation'])])

"""
Explanation: Change the view layout to show the segmentation side by side with the image, rather than overlayed.  This can also be done from the UI by dragging and dropping.  The side by side views by default have synchronized position, orientation, and zoom level, but this can be changed.
End of explanation
"""


with viewer.txn() as s:
    s.layout = neuroglancer.row_layout(
        [neuroglancer.LayerGroupViewer(layers=['image']),
         neuroglancer.LayerGroupViewer(layers=['segmentation'])])

"""
Explanation: Remove the overlay layer.
End of explanation
"""


print(neuroglancer.to_url(viewer.state))

"""
Explanation: Create a publicly sharable URL to the viewer state (only works for external data sources, not layers served from Python).  The Python objects for representing the viewer state (neuroglancer.ViewerState and friends) can also be used independently from the interactive Python-tied viewer to create Neuroglancer links.
End of explanation
"""


neuroglancer.stop()

"""
Explanation: Stop the Neuroglancer web server, which invalidates any existing links to the Python-tied viewer.
End of explanation
"""


