cellcanvas / cellcanvas/cellier

Goals and principles of cellier

Open
#5 0 comments 2 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
9
Forks
2
Avg merge
3d 11h
Merged PRs (30d)
4

Description

This issue discusses the goals and principles of `cellier`

## Goals
The overarching goal of `cellier` is to experiment with architectures for rich visualization of multiscale data. The idea is to provide a toolkit for visualization using `pygfx` as a backend.

A few goals:
- visualize nD data
- support rendering of large meshes and point clouds
- multicanvas support
- oblique slicing
- render to desktop- and browser-based GUIs
- it should be easy to serialize and deserialize the full viewer state. I want it to be easy to share views of data (ideally even between different viewers)

A few non-goals:
- build a fully featured application that is a one-stop shop for visualization and analysis. If done well, `cellier` would be a foundation for such a tool, but it is not a goal of `cellier` itself.
- support all visualization backends. while I hope that the architecture makes it easy to implement other backends, this is not a driving requirement.

## Principles

### Data flow
I think it is important that a dataset can be easily visualized with multiple representations without copying data. Below is a figure for a way I think data can flow through the viewer that supports this. I have started to work on this in #4

![cellier_overview_data_flow](https://github.com/kevinyamauchi/cellier/assets/1120672/12aa645b-2e2e-4c63-99a7-be019c8cbff5)

### Slicing and transformation

![cellier_overview_slicing_transformation](https://github.com/kevinyamauchi/cellier/assets/1120672/43f59613-0100-479a-bbcc-595eae399975)

In practice the following happens when the dims are changed. This is currently synchronous. Also a redraw is triggered each time a visual is updated. For small numbers of visuals this is probably fine, but we might want to wait until all are updated before redrawing.

1. All dims events are connected to the DataSlicer._on_dims_update()` callback method. This method triggers reslicing of the specific scene the dims object is a member of. https://github.com/kevinyamauchi/cellier/blob/8c7d158dd6d50fd782896f8076b110ea59efb34f/src/cellier/slicer/slicer.py#L48
2. The `_on_dims_update()` method calls the [`DataSlicer.reslice_scene()` method](https://github.com/kevinyamauchi/cellier/blob/8c7d158dd6d50fd782896f8076b110ea59efb34f/src/cellier/slicer/slicer.py#L69). This method makes a [`DataSliceRequest`](https://github.com/kevinyamauchi/cellier/blob/8c7d158dd6d50fd782896f8076b110ea59efb34f/src/cellier/slicer/data_slice.py#L12-L59) for each visual in the scene. The slice request is processed by the `DataSlicer.get_slice()` method, which makes the appropriate requests to the data streams/stores and gets the `SliceResult`, which contains all data required to render the new slice. Each `SliceResult` is emitted as a [`new_slice` event](https://github.com/kevinyamauchi/cellier/blob/8c7d158dd6d50fd782896f8076b110ea59efb34f/src/cellier/slicer/slicer.py#L99)
3. The `RenderManager._on_new_slice()` callback takes the `SliceResult` from the `new_slice` event and updates the `pygfx` objects. Once completed, the `RenderManager` emits a [`redraw_canvas` event](https://github.com/kevinyamauchi/cellier/blob/8c7d158dd6d50fd782896f8076b110ea59efb34f/src/cellier/render/render_manager.py#L189).
4. The `redraw_canvas` event triggers the [`ViewerController._on_canvas_redraw_event()` method](https://github.com/kevinyamauchi/cellier/blob/8c7d158dd6d50fd782896f8076b110ea59efb34f/src/cellier/viewer_controller.py#L69-L74), which makes the canvases udpate.

Some notes about the construction:
- The events coordinating the slicing/rendering updates are connected here: https://github.com/kevinyamauchi/cellier/blob/8c7d158dd6d50fd782896f8076b110ea59efb34f/src/cellier/viewer_controller.py#L61-L66
- The dims update is connected in the DataSlicer: https://github.com/kevinyamauchi/cellier/blob/8c7d158dd6d50fd782896f8076b110ea59efb34f/src/cellier/slicer/slicer.py#L48

### Viewer state is serializable

The viewer state should be serializable. A (very) rough draft of how the viewer model could be structured to support the data flow shown above.

![cellier_overview_viewer_model](https://github.com/kevinyamauchi/cellier/assets/1120672/2a005c82-6272-48ca-8142-1c8d02e3a3d3)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.