feat: Add catmaid spatially indexed skeletons (read-only)#119
Open
afonsobspinto wants to merge 54 commits intomasterfrom
Open
feat: Add catmaid spatially indexed skeletons (read-only)#119afonsobspinto wants to merge 54 commits intomasterfrom
afonsobspinto wants to merge 54 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces support for spatially indexed skeleton rendering in Neuroglancer, specifically adding a CATMAID data source integration for loading skeletons organized in spatial chunks.
Changes:
- Adds spatially indexed skeleton sources that load skeleton data in spatial chunks (similar to volume rendering) with LOD support
- Implements CATMAID data source provider for fetching skeleton data from CATMAID servers
- Adds UI controls for hidden object opacity and skeleton LOD level
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/skeleton/skeleton_chunk_serialization.ts | New utility module for serializing skeleton chunk data for transfer between backend and frontend |
| src/skeleton/gpu_upload_utils.ts | New utility for uploading vertex attribute data to GPU as 1D textures |
| src/skeleton/frontend.ts | Extended with new spatially indexed skeleton layer classes and rendering logic |
| src/skeleton/base.ts | Added RPC IDs for spatially indexed skeleton layers |
| src/skeleton/backend.ts | Added backend implementation for spatially indexed skeleton chunks with LOD support |
| src/segmentation_display_state/frontend.ts | Added hiddenObjectAlpha field for controlling opacity of non-visible segments |
| src/layer/segmentation/layer_controls.ts | Added UI controls for hidden opacity and LOD |
| src/layer/segmentation/json_keys.ts | Added JSON keys for new configuration options |
| src/layer/segmentation/index.ts | Integrated spatially indexed skeleton layers into segmentation user layer |
| src/datasource/index.ts | Extended DataSubsource type to include new skeleton source types |
| src/datasource/graphene/frontend.ts | Fixed type checking for meshSource RPC access |
| src/datasource/enabled_frontend_modules.ts | Registered CATMAID frontend module |
| src/datasource/enabled_backend_modules.ts | Registered CATMAID backend module |
| src/datasource/catmaid/register_default.ts | CATMAID provider registration |
| src/datasource/catmaid/register_credentials_provider.ts | CATMAID credentials provider registration |
| src/datasource/catmaid/frontend.ts | Frontend implementation for CATMAID data source |
| src/datasource/catmaid/credentials_provider.ts | Credentials provider for CATMAID authentication |
| src/datasource/catmaid/base.ts | Base parameter classes for CATMAID sources |
| src/datasource/catmaid/backend.ts | Backend implementation for CATMAID skeleton fetching |
| src/datasource/catmaid/api.ts | CATMAID API client implementation |
| package.json | Added package.json exports for CATMAID modules |
Comments suppressed due to low confidence (1)
src/datasource/catmaid/frontend.ts:1
- The conditional logic for determining sources is inconsistent. If
mesh instanceof CatmaidMultiscaleSpatiallyIndexedSkeletonSourceis true, passingallSources[0](an array) is incorrect as SpatiallyIndexedSkeletonLayer expects a single source or an array of SliceViewSingleResolutionSource. This should passallSources[0][0].chunkSourcein both cases or adjust the constructor signature.
/**
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
6a3c394 to
c3b8275
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated 9 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
e6f163b to
5bea93f
Compare
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ionality is active
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes:
CATMAID Datasource and Spatially Indexed Skeletons
This document explains how the CATMAID datasource is wired up and how spatially
indexed skeletons are loaded, serialized, and rendered.
CATMAID datasource implementation (
src/datasource/catmaid/)Entry points and registration
register_default.tsregisters the provider under thecatmaidscheme. TheURL format is expected to be
catmaid://<base_url>/<project_id>.Credentials flow
credentials_provider.tsdefinesCatmaidCredentialsProvider, which fetchesan anonymous API token from
<serverUrl>/accounts/anonymous-api-token.fetchOkWithCredentialsin the API client to retryon 401/403 and request a refreshed token when needed.
API client (
api.ts)CatmaidClientwraps all CATMAID endpoints used by the data source.Key operations:
listSkeletons()-> list of skeleton IDsgetSkeleton(skeletonId)-> full skeleton as nodes fromskeletons/<id>/compact-detailfetchNodes(boundingBox, lod)-> spatially indexed nodes fromnode/listusing msgpack; supports multi-LOD data in the responsegetDimensions()andgetResolution()-> stack metadata, including voxelsize and translation
getGridCellSizes()-> grid cache configurations (from custom metadata object); defaults to the hard-codedgrid size if none is present
Provider wiring (
frontend.ts)CatmaidDataSourceProvider.get()resolves the source, builds the coordinatespace, and creates the sub-sources:
Parse URL
catmaid://.httpprefix.Create
CatmaidClientand fetch metadata in parallel:dimensions,resolution,gridCellSizes,skeletonIds.Coordinate space setup
resolution(nm per voxel) to meters.translationanddimensionto establish voxel-space bounds.Create skeleton sources
CatmaidMultiscaleSpatiallyIndexedSkeletonSourceprovides a multiscale slice-view chunk source for spatially indexed
skeleton data.
CatmaidSkeletonSourceloads full skeletons by ID.Create segment properties for skeleton labels
BigIntand stored in aSegmentPropertyMap.Subsources returned
skeletons-chunked(spatially indexed)skeletons(full skeletons)properties(segment labels)bounds(data bounds)Multiscale grid mapping
CatmaidMultiscaleSpatiallyIndexedSkeletonSource.getSources():ChunkLayoutandSliceViewChunkSpecification.chunkToMultiscaleTransformthat scales each grid size relative tothe smallest grid size.
useChunkSizeForScaleSelection = trueso the backend can bias scaleselection based on chunk sizes (rather than voxel size alone).
Spatially indexed skeletons (
src/skeleton/)Data model and chunk serialization
The spatially indexed path uses slice-view chunking but renders as a mesh-like
edge list.
Key data types:
SpatiallyIndexedSkeletonChunk(frontend and backend)vertexPositions(Float32 vec3)vertexAttributes(packed bytes)indices(Uint32 pairs, each edge is two vertex indices)missingConnections(parent edges that cross chunk boundaries)nodeMap(nodeId -> vertexIndex mapping)SkeletonChunkDataserialization packs vertex positions and attributes into asingle
Uint8ArraywithvertexAttributeOffsetsfor GPU upload.Serialization (
skeleton_chunk_serialization.ts):vertexAttributeOffsetsdescribes byte offsets of each attribute.missingConnectionsandnodeMapare serialized alongside.Chunk download (CATMAID backend)
CatmaidSpatiallyIndexedSkeletonSourceBackend.download():chunkGridPositionandchunkDataSize.CatmaidClient.fetchNodes(bbox, currentLod).vertexPositions: XYZ for each node.vertexAttributes: segment ID only (stored as float).indices: edge pairs from parent-child relations.nodeMap: maps CATMAID node IDs to vertex indices.Backend chunk scheduling and LOD
SpatiallyIndexedSkeletonRenderLayerBackend:skeletonLodas a shared watchable value.slider move.
recomputeChunkPriorities():renderScaleTarget,effectiveVoxelSize,chunkLayout.sizeifuseChunkSizeForScaleSelectionis enabled.forEachVisibleVolumetricChunkand applies a scalepriority offset (
SCALE_PRIORITY_MULTIPLIER).Rendering pipeline overview
Rendering is split into two paths:
Regular skeleton layer (
SkeletonLayer)Spatially indexed skeleton layer (
SpatiallyIndexedSkeletonLayer)consistent color usage and visibility filtering.
Spatially indexed draw algorithm (per chunk, per segment)
SpatiallyIndexedSkeletonLayer.draw()performs per-segment rendering to ensurecorrect color assignment and visibility filtering:
Build a global node map across all loaded chunks to resolve inter-chunk
parent references.
For each chunk:
getVisibleSegments).objectAlphaorhiddenObjectAlphabased on visibility.uColorset to the segment color.Per-segment caching
generation, so repeated frames can reuse GPU textures.Inter-chunk edges
missingConnectionsare tracked but not rendered yet.Improvements:
1) Per-draw global node map construction
Detail:
SpatiallyIndexedSkeletonLayer.draw()rebuilds a global node mapevery frame across all loaded chunks.
Risk: This scales with total loaded vertices and can become expensive.
2) Per-segment compaction and buffer swapping
Detail: For each segment in each chunk, the code:
Risk: This is CPU-heavy and generates many short-lived GL buffers, which can
cause stalls and GC pressure for large skeleton sets.
3) Inter-chunk edges are not rendered
Detail:
missingConnectionsare tracked, but the renderer does not drawedges that cross chunk boundaries.
Risk: Skeletons that cross chunk boundaries appear disconnected.