neu-glance

From neu-glance. Neuroglancer viewer states, annotation layers and shareable links — everything a viewer consumes, and nothing that produces data.

python -m neu_glance.cli is equivalent.

The three producers (gen, annotate, bboxes) share one output stage: --format {layer,state,url} chooses the serialization, --out writes it somewhere instead of stdout, and --into merges the new layers into an existing state given as a URL or a JSON file — keeping that state’s own dimensions, position and zoom, so adding a layer does not move your view.

serve takes none of that stage, because what it produces is a running server rather than a serialization: it hosts arrays from its own process and prints a link. A served array is addressed python://volume/<token>, scoped to that process, so there is nothing to save or share — see the guide. It needs the optional serve extra.

gen, annotate and bboxes were neu-vol ng-url-gen, neu-vol annotate-json and neu-vol bboxes-json. A clean break, with no aliases: the old invocations fail loudly rather than quietly doing something slightly different.

Neuroglancer states, layers and links.

Everything a viewer consumes and nothing that produces data: the volumes come from neu-vol and the annotation sources from neu-mark, and neither of those knows a viewer exists.

Neuroglancer keeps its whole state in the URL fragment, so a link IS the state. Everything after ‘#!’ stays in the browser and is never sent to a server — but the whole state travels in the URL, so a large inline annotation layer makes for a long one.

usage: neu-glance [-h] [--version] [--store-logs] COMMAND ...

Positional Arguments

COMMAND

Possible choices: gen, annotate, bboxes, serve, parse, shaders, help

Named Arguments

--version

show program’s version number and exit

--store-logs

do not filter the store’s own logging. The S3 driver emits two AuthCredentialsProvider lines per prefix at ERROR severity that are not failures — they record the providers that missed before the environment one succeeded — so they are filtered by default. PERMISSION_DENIED and AccessDenied are never filtered

Default: False

Sub-commands

gen

Compose a neuroglancer state and emit it as a link or as JSON.

Reads the volumes to get the source scheme and the coordinate space right, which is the part that fails silently by hand: a dimensions block that disagrees with the data loads fine and puts every layer in the wrong place.

neu-glance bboxes s3://.../gt_v2 --label gt --out gt.json
neu-glance gen --image s3://.../em --seg s3://.../gt_v2 \
    --layer gt.json --segments 1,2,3 --layout xy-3d

URL or JSON to stdout, summary to stderr. Reads only.

neu-glance gen [-h] [--image VOLUME] [--seg VOLUME] [--segments IDS]
               [--all-segments LAYER_NAME] [--annotations SOURCE]
               [--presyn-postsyn] [--annotation-shader NAME_OR_PATH]
               [--no-filter-by-segmentation] [--layer PATH_OR_URL]
               [--image-opacity F] [--silhouette LAYER_NAME=VALUE]
               [--opacity-2d LAYER_NAME=VALUE] [--opacity-3d LAYER_NAME=VALUE]
               [--color LAYER_NAME=COLOR]
               [--color-by LAYER_NAME=PROP[,PROP...]] [--no-pick LAYER_NAME]
               [--config TOML] [--voxel-size Z,Y,X] [--format {url,state}]
               [--out PATH_OR_URL] [--into URL_OR_JSON]
               [--layout {4panel,xy,yz,xz,xy-3d,yz-3d,xz-3d,3d}]
               [--position Z,Y,X] [--position-order {zyx,xyz}]
               [--cross-section-scale S] [--projection-scale S]
               [--hide-slices] [--hide LAYER_NAME] [--select LAYER_NAME]
               [--select-last] [--viewer VIEWER] [--expand]

Named Arguments

--image

an image volume (repeatable). Drawn beneath the segmentations

--seg

a segmentation volume (repeatable)

--segments

comma-separated segment ids to select, applied to the –seg volumes in order. Repeat for a second segmentation

--all-segments

select every segment of this –seg layer that its segment_properties lists, so its meshes show in 3D as soon as the layer is on (repeatable). For a few named regions, such as ROI layers, not a segmentation of thousands of bodies

--annotations

a precomputed ANNOTATION source — what neu-mark annotation-source writes (repeatable). Added as its own layer, because unlike mesh and skeletons an annotation source is never named in a volume’s info. Its relationships are bound to the first –seg layer, which is what makes ‘only this body’s synapses’ work. The synapse shader’s show_pre / show_post checkboxes show either end alone, and the Annotations tab toggles the filter per relationship

--presyn-postsyn

also add each synapse source as a ‘presyn’ and a ‘postsyn’ layer, filtered on body_pre and body_post and showing only that end: the selected bodies’ own output and input sites, without their partners’ ends

Default: False

--annotation-shader

GLSL for the annotation layers: a built-in name (synapse), a file, or ‘none’. Default picks a built-in whose properties the source declares, since a shader naming an absent property fails to compile and the layer then draws nothing

--no-filter-by-segmentation

show every annotation instead of only those on the selected segments. By default the filter is ON, so the annotations follow whatever you select — which means a link with no –segments opens showing none until you pick a body. Toggle it per relationship in the layer’s ANNOTATIONS tab. The relationships stay bound either way

Default: True

--layer

a JSON file holding a layer, or a state whose layers are taken — e.g. the output of neu-glance bboxes (repeatable)

--image-opacity

opacity for the –image layers

--silhouette

3D silhouette (0-10): faces turned towards the viewer fade, leaving the outline; 0 is off, larger is stronger of one segmentation layer (repeatable; sets meshSilhouetteRendering)

--opacity-2d

opacity of the selected segments in the 2D panels of one segmentation layer (repeatable; sets selectedAlpha)

--opacity-3d

opacity of the meshes in the 3D panel of one segmentation layer (repeatable; sets objectAlpha)

--color

colour of every segment of one segmentation layer that has no colour of its own: a name, #rrggbb (repeatable; sets segmentDefaultColor). Without it each segment gets its hash colour

--color-by

colour each segment of one segmentation layer by a segment property, from its source’s segment_properties: a tag facet (col, group), a flag tag, or label. A segment takes the first property it has a value for, so col,group colours by column and falls back to group. Each value gets a fixed colour from neuroglancer’s segment palette; segments with none keep their hash colour. Written as segmentColors, so it is fixed when the state is made (repeatable)

--no-pick

make clicks go through this segmentation layer (repeatable; sets pick false), for a shell enclosing what you want to select

--config

site display defaults: volume bounds, annotation shader controls, and per-layer silhouette, opacities, hide and all_segments by layer name (see neu_glance.config). Read only when named; a flag here wins over the file

--voxel-size

level-0 voxel size in nm, overriding what the volumes record. Required when every layer comes from –layer, since a layer file carries its own frame but does not establish the viewer’s

--format

Possible choices: url, state

what to emit (default: url). ‘layer’ is a bare layer object for pasting into a state’s layers array; ‘state’ is a whole state as JSON, for neuroglancer’s {} editor; ‘url’ is a link carrying that state.

--out

write it here instead of stdout (local or s3://…). Repeatable; ‘-’ is stdout, so –out link.txt –out - does both

--into

add the layers to an EXISTING state rather than building a new one — a neuroglancer URL or a state JSON file. The state’s own dimensions, position and zoom are kept, so your view does not move; a layer whose name is already taken is renamed and reported. The layer flags reach the state’s own layers too; –config applies only to the layers added. Implies –format url unless –format says otherwise. With nothing to add, gen –into re-emits the state itself — a view file straight to a link. Quote a URL with SINGLE quotes: inside double quotes bash expands ‘!’, which neuroglancer uses both after ‘#’ and for hidden segments.

--layout

Possible choices: 4panel, xy, yz, xz, xy-3d, yz-3d, xz-3d, 3d

neuroglancer panel layout (default: 4panel, or whatever –into already had)

--position

where to put the crosshair, in level-0 voxels

--position-order

Possible choices: zyx, xyz

axis order of –position. Everything in this package is zyx, but neuroglancer DISPLAYS xyz — so pass xyz to use numbers copied straight out of the viewer (default: zyx)

Default: 'zyx'

--cross-section-scale

zoom of the 2D panels: nm per screen pixel, smaller is closer

--projection-scale

zoom of the 3D panel

--hide-slices

set showSlices false, hiding the cross-section planes inside the 3D panel — the usual thing to want when the link is about meshes or skeletons. Omitted from the state unless passed

Default: False

--hide

add this layer switched off, to turn on in the viewer (repeatable). For layers that would crowd the view if all were shown at once. A layer flag names a layer as the viewer shows it, or by its source location, and reaches an –into state’s layers

--select

open the side panel on this layer

--select-last

the same, on whichever layer was added last

Default: False

--viewer

viewer base URL for –format url (default: https://neuroglancer-demo.appspot.com/)

Default: 'https://neuroglancer-demo.appspot.com/'

--expand

with –into a state JSON on s3:// or gs:// and –format url, put the whole state in the link. By default such a link only names the file (<viewer>#!s3://…/state.json), which the viewer fetches, so it stays short and follows later rewrites of the file

Default: False

annotate

Build a neuroglancer annotation layer from points, boxes, lines or ellipsoids you already have — a synapse table, an ROI list, a few coordinates typed by hand.

The annotations are LOCAL, carried inline in the state, and that is the point: only local annotations appear in the Annotations tab, which is what makes them clickable and steppable. For a whole volume’s worth of synapses, write a precomputed source with neu-mark annotation-source and add it with neu-glance gen –annotations.

Coordinates are zyx and in level-0 voxels unless –scale or –nm says otherwise.

neu-glance annotate [-h] [--volume VOLUME] [--points CSV] [--point COORDS]
                    [--boxes CSV] [--box COORDS] [--lines CSV] [--line COORDS]
                    [--ellipsoids CSV] [--ellipsoid COORDS] [--scale N] [--nm]
                    [--name NAME] [--color COLOR] [--label PREFIX]
                    [--link [REL=]LAYER] [--voxel-size Z,Y,X]
                    [--format {layer,state,url}] [--out PATH_OR_URL]
                    [--into URL_OR_JSON]
                    [--layout {4panel,xy,yz,xz,xy-3d,yz-3d,xz-3d,3d}]
                    [--position Z,Y,X] [--position-order {zyx,xyz}]
                    [--cross-section-scale S] [--projection-scale S]
                    [--hide-slices] [--hide LAYER_NAME] [--select LAYER_NAME]
                    [--select-last] [--viewer VIEWER] [--expand]

Named Arguments

--volume

a volume to take the frame from, and to bounds-check against. Optional, but without it you must pass –voxel-size

--points

a CSV of points with columns z, y, x (repeatable; a path, a URL, or - for stdin). Optional columns: id, description, segments, and segments:<relationship> for use with –link

--point

one point inline as z, y, x (repeatable)

--boxes

a CSV of boxes with columns z0, y0, x0, z1, y1, x1 (repeatable; a path, a URL, or - for stdin). Optional columns: id, description, segments, and segments:<relationship> for use with –link

--box

one box inline as z0, y0, x0, z1, y1, x1 (repeatable)

--lines

a CSV of lines with columns z0, y0, x0, z1, y1, x1 (repeatable; a path, a URL, or - for stdin). Optional columns: id, description, segments, and segments:<relationship> for use with –link

--line

one line inline as z0, y0, x0, z1, y1, x1 (repeatable)

--ellipsoids

a CSV of ellipsoids with columns z, y, x, rz, ry, rx (repeatable; a path, a URL, or - for stdin). Optional columns: id, description, segments, and segments:<relationship> for use with –link

--ellipsoid

one ellipsoid inline as z, y, x, rz, ry, rx (repeatable)

--scale

the coordinates are in scale-N voxels; convert using the volume’s own per-level voxel sizes. Needs –volume

--nm

the coordinates are in physical nm; convert using the level-0 voxel size

Default: False

--name

layer name

Default: 'annotations'

--color

annotation colour

Default: '#ffee00'

--label

prefix for generated annotation ids (default: ‘a’)

Default: 'a'

--link

bind a relationship to a segmentation LAYER (by its name in the state), which is what makes an annotation’s segments selectable. REL=LAYER binds a segments:REL column; a bare LAYER binds the plain segments column. Repeatable, so one annotation can name a body in the reference and a segment in each of several other layers

Default: []

--voxel-size

level-0 voxel size in nm, overriding the volume’s

--format

Possible choices: layer, state, url

what to emit (default: layer). ‘layer’ is a bare layer object for pasting into a state’s layers array; ‘state’ is a whole state as JSON, for neuroglancer’s {} editor; ‘url’ is a link carrying that state.

--out

write it here instead of stdout (local or s3://…). Repeatable; ‘-’ is stdout, so –out link.txt –out - does both

--into

add the layers to an EXISTING state rather than building a new one — a neuroglancer URL or a state JSON file. The state’s own dimensions, position and zoom are kept, so your view does not move; a layer whose name is already taken is renamed and reported. The layer flags reach the state’s own layers too; –config applies only to the layers added. Implies –format url unless –format says otherwise. With nothing to add, gen –into re-emits the state itself — a view file straight to a link. Quote a URL with SINGLE quotes: inside double quotes bash expands ‘!’, which neuroglancer uses both after ‘#’ and for hidden segments.

--layout

Possible choices: 4panel, xy, yz, xz, xy-3d, yz-3d, xz-3d, 3d

neuroglancer panel layout (default: 4panel, or whatever –into already had)

--position

where to put the crosshair, in level-0 voxels

--position-order

Possible choices: zyx, xyz

axis order of –position. Everything in this package is zyx, but neuroglancer DISPLAYS xyz — so pass xyz to use numbers copied straight out of the viewer (default: zyx)

Default: 'zyx'

--cross-section-scale

zoom of the 2D panels: nm per screen pixel, smaller is closer

--projection-scale

zoom of the 3D panel

--hide-slices

set showSlices false, hiding the cross-section planes inside the 3D panel — the usual thing to want when the link is about meshes or skeletons. Omitted from the state unless passed

Default: False

--hide

add this layer switched off, to turn on in the viewer (repeatable). For layers that would crowd the view if all were shown at once. A layer flag names a layer as the viewer shows it, or by its source location, and reaches an –into state’s layers

--select

open the side panel on this layer

--select-last

the same, on whichever layer was added last

Default: False

--viewer

viewer base URL for –format url (default: https://neuroglancer-demo.appspot.com/)

Default: 'https://neuroglancer-demo.appspot.com/'

--expand

with –into a state JSON on s3:// or gs:// and –format url, put the whole state in the link. By default such a link only names the file (<viewer>#!s3://…/state.json), which the viewer fetches, so it stays short and follows later rewrites of the file

Default: False

bboxes

Ask a volume where its data is and get one box per written region.

For a volume holding a handful of labeled regions inside a large empty frame, finding them is the hard part. The boxes come from listing which chunk objects exist — TensorStore never persists an all-fill chunk, so the set of present keys IS the occupied footprint — then tightening each box to its nonzero voxels at a coarse level.

The analysis lives in neu-vol (ops.occupancy.labeled_regions); this turns its answer into a layer.

neu-glance bboxes [-h] [--level LEVEL] [--tighten-level N] [--no-tighten]
                  [--kind {box,point}] [--name NAME] [--label PREFIX]
                  [--color COLOR] [--voxel-size Z,Y,X]
                  [--format {layer,state,url}] [--out PATH_OR_URL]
                  [--into URL_OR_JSON]
                  [--layout {4panel,xy,yz,xz,xy-3d,yz-3d,xz-3d,3d}]
                  [--position Z,Y,X] [--position-order {zyx,xyz}]
                  [--cross-section-scale S] [--projection-scale S]
                  [--hide-slices] [--hide LAYER_NAME] [--select LAYER_NAME]
                  [--select-last] [--viewer VIEWER] [--expand]
                  volume

Positional Arguments

volume

the volume to inspect (path or s3://…)

Named Arguments

--level

which level’s chunk grid to list (default: 0)

Default: 0

--tighten-level

tighten each box to its nonzero voxels at level N. Defaults to the greater of 2 and –level; 0 is exact and slowest

--no-tighten

skip tightening: the boxes stay chunk-aligned

Default: False

--kind

Possible choices: box, point

draw each region as a box or as a single centre point

Default: 'box'

--name

layer name

--label

prefix for the region ids (default: r)

--color

annotation colour

Default: '#ffee00'

--voxel-size

level-0 voxel size in nm, overriding the volume’s

--format

Possible choices: layer, state, url

what to emit (default: layer). ‘layer’ is a bare layer object for pasting into a state’s layers array; ‘state’ is a whole state as JSON, for neuroglancer’s {} editor; ‘url’ is a link carrying that state.

--out

write it here instead of stdout (local or s3://…). Repeatable; ‘-’ is stdout, so –out link.txt –out - does both

--into

add the layers to an EXISTING state rather than building a new one — a neuroglancer URL or a state JSON file. The state’s own dimensions, position and zoom are kept, so your view does not move; a layer whose name is already taken is renamed and reported. The layer flags reach the state’s own layers too; –config applies only to the layers added. Implies –format url unless –format says otherwise. With nothing to add, gen –into re-emits the state itself — a view file straight to a link. Quote a URL with SINGLE quotes: inside double quotes bash expands ‘!’, which neuroglancer uses both after ‘#’ and for hidden segments.

--layout

Possible choices: 4panel, xy, yz, xz, xy-3d, yz-3d, xz-3d, 3d

neuroglancer panel layout (default: 4panel, or whatever –into already had)

--position

where to put the crosshair, in level-0 voxels

--position-order

Possible choices: zyx, xyz

axis order of –position. Everything in this package is zyx, but neuroglancer DISPLAYS xyz — so pass xyz to use numbers copied straight out of the viewer (default: zyx)

Default: 'zyx'

--cross-section-scale

zoom of the 2D panels: nm per screen pixel, smaller is closer

--projection-scale

zoom of the 3D panel

--hide-slices

set showSlices false, hiding the cross-section planes inside the 3D panel — the usual thing to want when the link is about meshes or skeletons. Omitted from the state unless passed

Default: False

--hide

add this layer switched off, to turn on in the viewer (repeatable). For layers that would crowd the view if all were shown at once. A layer flag names a layer as the viewer shows it, or by its source location, and reaches an –into state’s layers

--select

open the side panel on this layer

--select-last

the same, on whichever layer was added last

Default: False

--viewer

viewer base URL for –format url (default: https://neuroglancer-demo.appspot.com/)

Default: 'https://neuroglancer-demo.appspot.com/'

--expand

with –into a state JSON on s3:// or gs:// and –format url, put the whole state in the link. By default such a link only names the file (<viewer>#!s3://…/state.json), which the viewer fetches, so it stays short and follows later rewrites of the file

Default: False

serve

Serve one or more arrays from THIS process and print the viewer link.

For looking at something that is not published: a ground-truth crop, a box out of a volume, a probability map. Each –image / –seg / –prob is a path (an HDF5 file, a volume, a slice stack), optionally with a level and a box.

neu-glance serve --seg piece.h5
neu-glance serve --image vol --seg gt --crop-bbox 0,0,0,64,512,512
neu-glance serve --image piece.h5:/raw --prob piece.h5:/affinity

Runs until Ctrl-C. The link is only valid while it runs: a served array is addressed python://volume/<token>, scoped to this process, so it cannot be shared or saved. Use gen for that, against a published volume.

Needs the optional extra: pip install ‘neu-glance[serve]’

neu-glance serve [-h] [--image SRC] [--seg SRC] [--prob SRC] [--level N]
                 [--crop-bbox Z0,Y0,X0,Z1,Y1,X1] [--voxel-size Z,Y,X]
                 [--shader NAME_OR_PATH] [--color COLOR] [--bind ADDRESS]
                 [--port N] [--into PATH_OR_URL] [--annotate [NAME]]

Named Arguments

--image

an image source (repeatable). PATH, or PATH:DATASET for an HDF5 container holding more than one array

--seg

a segmentation source (repeatable). Served as labels whatever the dtype — neuroglancer would read a uint8 label array as an image, which loses the colour hashing and the selection UI

--prob

a probability / continuous-scalar source (repeatable). One channel is drawn in a single colour with the OPACITY carrying the value, so it composites over the image under it; a leading 3-channel axis is shown as three colours instead

--level

which level to read from a multiscale –image/–seg/–prob (default: 0). Applies to every source

Default: 0

--crop-bbox

serve only this box, in –level voxels. Whole volumes are usually far too large to hold in memory, so this is required for anything but a piece or a small volume

--voxel-size

voxel size in nm, overriding what the sources record. Needed for a source that records none (a slice stack, a plain HDF5 file)

--shader

GLSL for the image-like layers: a built-in name (grayscale, probability, colormap, rgb, none), or ‘none’ for neuroglancer’s own default. Default picks by kind and channel count

--color

colour for the –prob layers (default: red): a name (red, cyan, orange, …) or #rrggbb. Any colour matplotlib names works too where matplotlib is installed. Applies to a shader with a single colour, which the one-channel default has; the viewer’s own control changes it afterwards

--bind

the address to serve on (default: 127.0.0.1, reachable only from this machine). Use 0.0.0.0 when the browser is elsewhere; the printed link then names this host

Default: '127.0.0.1'

--port

port to serve on (default: 0, meaning any free one)

Default: 0

--into

start from an existing state, given as a URL or a JSON file, and add the served layers to it — keeping its view. Single-quote a URL, since bash expands ‘!’ inside double quotes

--annotate

add an empty annotation layer to draw boxes in, read back by Server.boxes(). Off by default: a viewer that opens with a layer nobody asked for reads as a bug. Give a NAME to call it something else

Default: False

parse

Decode the state out of a link, for reading or editing it.

Note that gen –into accepts a URL directly, so this is not a required step in that workflow — it is the inspection tool. The reverse, a state JSON back to a link, is gen –into STATE.json.

neu-glance parse [-h] [--layers] [--out PATH_OR_URL] url

Positional Arguments

url

the neuroglancer URL, in single quotes (or - to read one from stdin)

Named Arguments

--layers

print just the layer names and types, one per line

Default: False

--out

write the state JSON here instead of stdout. Repeatable; ‘-’ is stdout

shaders

List the built-in shaders, or print one to edit.

A shader lives in the viewer state rather than in the source, so a link is the only place one can be shipped. Print one, edit it, and pass the file back with –annotation-shader path.glsl.

neu-glance shaders [-h] [name]

Positional Arguments

name

print this shader’s GLSL. Omit to list them

help

Print the help for the tool, or for one of its subcommands.

neu-glance help serve and neu-glance serve –help are the same thing.

neu-glance help [-h] [COMMAND ...]

Positional Arguments

COMMAND

the subcommand to describe (default: the whole tool)