Architecture¶
Bin2Cell Explorer combines a Python backend (Flask plugin) and a JavaScript frontend layered onto TissUUmaps’ OpenSeadragon viewer. This section documents the main components and the engineering decisions that shaped them.
High-level Diagram¶
┌─────────────────────┐
│ Bin2CellExplorer.js │ UI controls, overlays, minimap, AJAX calls
└────────┬────────────┘
│/plugins/Bin2CellExplorer/{endpoint}
┌─────────────────────┐
│ Bin2CellExplorer.py │ Dataset loaders, cache, overlay builder, presets, exports
└────────┬────────────┘
│Local FS + in-memory cache
┌─────────────────────┐
│ Data assets │ he.tiff, he.npz, P2_CRC_annotated.h5ad
└─────────────────────┘
Backend (Bin2CellExplorer.py)¶
Dataset Loading Path¶
- Normalize paths and expand
~. - Load H&E TIFF via
skimage.io.imread(usesimagecodecsfor LZW). - Load sparse labels (
scipy.sparse.load_npz). - Load AnnData with
anndata.read_h5ad. - Cache the context (H&E, sparse labels, centroid coordinates, AnnData) and tile definitions in a module-level state.
- Persist dataset metadata to
dataset_state.jsonfor rehydration across sessions.
Key choices
- Caching: heavy assets only load once. Subsequent overlay calls reuse cached data, preventing repeated 4 GB loads.
- Lazy rehydration:
_ensure_context()can rebuildB2CContextif the module is reloaded or the Flask plugin is re-instantiated. - Error handling:
try/exceptaround every endpoint with_error_responseensures the UI receives structured JSON (never raw HTML error pages). - TileCache: per-tile overlay data (expanded labels, polygons) is cached with an LRU eviction to avoid recomputing for repeated requests.
Overlay Generation¶
get_overlay accepts a tile ID plus gene/observation parameters and returns:
- Expanded and raw label polygons (per cell) plus outlines.
- Centroid bookkeeping (used server-side to aggregate expression and majority votes).
- Legend metadata (continuous gradient or categorical swatches).
Steps:
- Retrieve tile info (
_tile_entry) — computes or fetches cached expanded labels, polygons, outlines. - Branch on overlay type:
- Gene: compute maximum expression per expanded cell, map to colors, optionally limit top N or quantile.
- Observation: majority vote over expanded cell, map categories, filter if requested.
- Return structured JSON for the frontend to draw.
Exporting & Presets¶
export_overlay: reusesget_overlay, converts polygons to GeoJSON.save_preset/list_presets/delete_preset: CRUD operations on a JSON file stored under~/.tissuumaps/plugins/Bin2CellExplorer/presets.json.
Frontend (Bin2CellExplorer.js)¶
UI Construction¶
Declared parameters drive the autogenerated form (via TissUUmaps plugin system). Key custom elements:
- Tile overview canvas (minimap) with click-to-jump behavior.
- Outline toggles (expanded vs. nuclei) that switch both fills and helper outlines.
- Overlay legend with checkboxes to toggle categories or genes without rerendering.
Data Flow¶
- User actions trigger
inputTrigger. - Load dataset →
load_datasetendpoint → update internal state and the tile overview. - Update overlay →
get_overlayendpoint → render overlay and legend. - Export/preset actions follow similar request/response loops.
Rendering¶
- SVG overlay: uses OpenSeadragon’s SVG overlay (
overlayUtils._d3nodes) to draw polygons and helper outlines. - Tile overview: HTML canvas minimap (~320 px square) with gradient styling; clicking selects and centers tiles, so an extra on-slide grid is unnecessary.
- Viewport utilities: helper functions convert pixel coordinates to viewport space (accounting for image flip).
Interaction Helpers¶
panToTile(tileId, animate)→ centers the viewer on a tile by converting pixel coordinates to OpenSeadragonRect.renderTileOverview()→ redraws minimap whenever tiles load or selection changes.attachTileSelectListener()→ keeps dropdown, minimap, and viewer selection in sync.
Performance Considerations¶
- Initial load: dominated by reading TIFF +
.h5ad; expect ~20–30 seconds on SSD. Loading is single-threaded (library limitation). - Overlay computation: per tile, typically < 1 s thanks to caching of expanded labels.
- Memory footprint: entire H&E (≈1.2 GB in RAM), sparse labels, AnnData (4 GB), plus caches. Ensure ≥8 GB free RAM during development.
- Tile overview: drawn in canvas to avoid heavy DOM operations; scaled rendering keeps hover/selection lightweight even for thousands of tiles.