Metadata-Version: 2.4
Name: nglscenes
Version: 0.5.0
Summary: Tools to generate and manipulate neuroglancer scenes
Author-email: Philipp Schlegel <pms70@cam.ac.uk>
License-Expression: GPL-3.0-or-later
Project-URL: Homepage, https://github.com/schlegelp/nglscenes
Project-URL: Documentation, https://github.com/schlegelp/nglscenes
Project-URL: Source, https://github.com/schlegelp/nglscenes
Project-URL: Changelog, https://github.com/schlegelp/nglscenes/blob/main/NEWS.md
Keywords: neuroglancer,scenes,FlyWire
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests
Requires-Dist: cmap
Requires-Dist: neuroglancer
Requires-Dist: numpy
Requires-Dist: pandas
Requires-Dist: pyperclip
Requires-Dist: trimesh
Requires-Dist: flask
Requires-Dist: flask-cors
Requires-Dist: cloud-volume
Dynamic: license-file

[![Tests](https://github.com/schlegelp/nglscenes/actions/workflows/test-package.yml/badge.svg)](https://github.com/schlegelp/nglscenes/actions/workflows/test-package.yml)

# nglscenes
An interface to generate and manipulate [neuroglancer](https://github.com/google/neuroglancer) scenes.

## Features

- extract scenes from URLs, clipboard, (JSON) files or strings
- manipulate state dictionary
- write scenes to files or clipboard
- easily create segment properties
- run and remote-control a local neuroglancer

## Install

```shell
$ pip install nglscenes
```

From Github:

```shell
$ pip install git+https://github.com/schlegelp/nglscenes@main
```

## Usage

### Overview

At this point, `nglscenes` has two different types of "scenes":

1. Use a basic `Scene` to construct and manipulate neuroglancer states.
2. Use a `LocalScene` to starts a local neuroglancer server which then
   keeps the state between the browser and Python synced.

### Examples

#### Manually construct a simple scene

```python
>>> from nglscenes import *
>>> # Generate empty scene
>>> scene = Scene()

>>> # Generate some layers
>>> img = ImageLayer(source='precomputed://gs://neuroglancer-fafb-data/fafb_v14/fafb_v14_clahe')
>>> seg = SegmentationLayer(source="precomputed://gs://fafb-ffn1-20200412/segmentation")
>>> an = AnnotationLayer(source="precomputed://gs://neuroglancer-20191211_fafbv14_buhmann2019_li20190805")

>>> # Add layers to scene
>>> scene.add_layers(img, seg, an)
>>> scene
<Scene(1 segmentation, 0 mesh, 1 image, 1 annotation)>

https://neuroglancer-demo.appspot.com/#!%7B%22laye[...]

>>> # Open in browser
>>> scene.open()

>>> # Copy to clipborad
>>> scene.to_clipboard()
URL copied to clipboard.
```

#### Manipulate a scene

```python
>>> from nglscenes import *
>>> # Read scene from URL or JSON-formatted string
>>> scene = Scene.from_clipboard()
>>> scene
<Scene(3 segmentation, 1 mesh, 3 image, 1 annotation)>

https://fafb-dot-neuroglancer-demo.appspot.com/#!%7[...]

>>> # Inspect layers
>>> scene.layers[2]
<SegmentationLayer(name=fafb-ffn1-20200412, source=precomputed://gs://fafb-ffn1-20200412/segmentation, selected segments=1)>
>>> # Drop the last layer
>>> scene.drop_layer(-1)
>>> # Add segments to the segmentation layer
>>> len(scene.layers[2]['segments'])
1
>>> scene.layers[2]['segments'] += [12345, 56789]
>>> len(scene.layers[2]['segments'])
3
```

#### Combine two scenes

```python
>>> # Read two scenes
>>> scene1 = Scene.from_clipboard()
>>> scene2 = Scene.from_clipboard()

>>> # Use addition to simply combine the layers of both scenes
>>> comb = scene1 + scene2
>>> len(comb) == len(scene1) + len(scene2)
True

>>> # Use OR operator to merge the layers
>>> # This will merge layers with the same data source
>>> # For segmentation layers, this will merge the selected segments
>>> merged = scene1 | scene2
>>> len(merged) < len(scene1) + len(scene2)
True
```

All of the above examples will also work with the other scene types.


#### Remote controlling neuroglancer

```python
>>> from nglscenes import *
>>> # Generate empty scene
>>> scene = LocalScene()
>>> scene
<LocalScene(1 segmentation, 0 mesh, 1 image, 1 annotation)>

http://127.0.0.1:53955/v/4dc530306753007bd4fc39b745673d604e58d2a5/

>>> # Open scene in browser
>>> scene.open()

>>> # Generate and add layers
>>> # -> you should see the layers appear in the browser window
>>> scene.add_layers(ImageLayer(source='precomputed://gs://neuroglancer-fafb-data/fafb_v14/fafb_v14_clahe'))
>>> scene.add_layers(SegmentationLayer(source="precomputed://gs://fafb-ffn1-20200412/segmentation"))
>>> scene.add_layers(AnnotationLayer(source="precomputed://gs://neuroglancer-20191211_fafbv14_buhmann2019_li20190805"))

>>> # The state is automatically synced:
>>> scene.layers[-1].state
OrderedDict([('source',
              'precomputed://gs://neuroglancer-20191211_fafbv14_buhmann2019_li20190805'),
             ('type', 'annotation'),
             ('name', 'annotations'),
             ('tab', 'source'),
             ('visible', False)])
>>> # Hide the layer
>>> scene.layers[-1]['visible'] = False
>>> # Get the same layer by name and unhide
>>> scene.layers['annotations']['visible'] = True
>>> # Set selected segments
>>> scene.layers[1]['segments'] = [5280982928, 5517604362]

>>> # Serve skeletons from a local folder containing SWC files
>>> # (this also works from a zip file)
>>> scene.add_layers(LocalSkeletonLayer(LocalSkeletonLayer(source='~/skeletons/')))
>>> scene.layers[-1]['segments'] = [123456]
```
