Skip to content

Get Started

This page walks you through launching UELer for the first time — either instantly in your browser, or locally on your own data.


Try It Instantly (no installation)

The fastest way to see UELer is on Binder. The demo notebook streams a public BioImage Archive study directly over the network, so there is nothing to download and no data to configure — the viewer opens on a real multiplexed imaging dataset.

Binder

Click the badge, wait for the environment to build, then run all cells. The first field of view is fetched on demand — only the channels you open are streamed.

First launch can be slow

Binder builds a fresh environment on first use, which may take a few minutes. Subsequent launches are faster while the image is cached.

The demo runs the development branch

The badge builds from develop, not from the latest release, so you are testing the newest features as they land. If you want the demo to match the version you have installed, point the Binder URL at a release tag instead of develop.


Run Locally

To work with your own data, run UELer inside a Jupyter notebook.

Example Notebooks

Runnable notebooks live in script/ in the repository:

Notebook Use it for
run_ueler.ipynb The starter notebook — local FOV folders, masks, annotations, and a cell table. Start here.
run_ueler_BIA.ipynb Streaming public BioImage Archive studies (S-BIAD*) with worked descriptors for several datasets.
run_ueler_binder.ipynb The zero-setup Binder demo linked above.

The notebooks are not part of the installed package

script/ ships with the repository only, not with the ueler-viewer wheel or sdist. If you installed with pip, download a notebook from the links above or write your own cell calling ueler.run_viewer.

Prerequisites

Make sure you have completed installation and activated the environment:

micromamba activate ark-analysis-ueler

1. Open the Notebook

Open your notebook environment (JupyterLab, Jupyter Notebook, or VS Code), navigate to the cloned UELer repository, and open:

script/run_ueler.ipynb

Select the ark-analysis-ueler kernel for the notebook.

2. Set Your Data Paths

Edit the paths cell near the top of the notebook. Only base_folder is required — masks, annotations, and the cell table are all optional, and the viewer simply skips those features when a path is not provided.

base_folder = "/path/to/your/image_data"                     # Required
masks_folder = "/path/to/segmentation/output"                # Optional
annotations_folder = "/path/to/annotations"                  # Optional
cell_table_path = "/path/to/cell_table.csv"                  # Optional (.csv, .parquet or .h5ad)
Variable Purpose Required
base_folder FOV folders containing per-channel TIFF images ✅ Yes
masks_folder Segmentation .tif rasters ❌ Optional
annotations_folder Annotation raster .tif files ❌ Optional
cell_table_path Per-cell feature table (.csv, .parquet, or .h5ad for AnnData) ❌ Optional

3. Launch the Viewer

UELer is launched from Python. Start with the minimal call and add data sources as you need them.

Minimal — images only:

import ueler
%matplotlib widget

viewer = ueler.run_viewer(base_folder)

run_viewer also accepts masks_folder=... and annotations_folder=... if you want segmentation and annotation overlays without a cell table. If base_folder is read-only, or a downstream pipeline can't tolerate extra files under its dataset root, pass settings_path=... to move UELer's .UELer settings folder elsewhere — see Where does UELer store my work?.

Full — masks, annotations, and a cell table:

import ueler
import pandas as pd
from ueler import load_cell_table
%matplotlib widget

# 1. Build the viewer with images + overlays (do not display yet)
viewer = ueler.run_viewer(
    base_folder,
    masks_folder=masks_folder,
    annotations_folder=annotations_folder,
    auto_display=False,
)

# 2. Attach the cell table, then display
cell_table = pd.read_csv(cell_table_path)
load_cell_table(viewer, cell_table=cell_table, auto_display=True, after_plugins=True)

If your cell table is an AnnData object, pass it directly — see Working with a Cell Table:

import anndata as ad

load_cell_table(viewer, cell_table=ad.read_h5ad("cells.h5ad"), auto_display=True)

Why two steps?

run_viewer builds and displays the image and mask viewer. The cell table is attached separately with load_cell_table, which re-renders the UI with the linked scatter and histogram plots and the cell gallery enabled. If you have no cell table, skip step 2 and let run_viewer display on its own (auto_display defaults to True).

A large table: use Parquet

A study-scale table is wide as well as long, and loading all of it to plot one marker is what makes a big table slow. Convert it once:

python tools/cell_table_to_parquet.py cell_table.csv cell_table.parquet

then pass the .parquet to load_cell_table exactly as you would the CSV. The viewer reads the column names and types up front, so every marker, cluster and annotation dropdown is complete the moment it opens, and it fetches a column's values the first time something plots them. Nothing about using the viewer changes, and nothing is approximated: every column arrives complete, so the mask painter's automatic colour range, the heatmap, FlowSOM and the histogram gates are all still computed over every cell.

The converter prints what each column costs, which is what materialising it will cost later:

wrote cell_table.parquet: 2.8 MB, 16 row group(s) of ~897 rows, compression=zstd

per-column footprint (2.8 MB total):
    2.4%       70.0 KB  CD45
    2.4%       69.5 KB  Ki67
    ...

Use --row-groups if you want to tune it; the default of 16 is chosen for whole-column reads, which is the access pattern the viewer actually has.

%matplotlib widget

The %matplotlib widget magic enables the interactive backend used by the viewer. Run it once per kernel session before launching.


Stream Any BioImage Archive Study

You are not limited to local folders. run_viewer_bia streams a public BioImage Archive study (S-BIAD*) without downloading the whole dataset — pass an accession id (or a direct HTTPS URL) and an optional layout descriptor:

import ueler
%matplotlib widget

viewer = ueler.run_viewer_bia(
    "S-BIAD2557",
    descriptor={
        "mode": "folder",
        "fov_container": "zip",
        "base": "Files/spatial_murine_iCCAvsHCC/image_data",
        "mask_dir": "Files/spatial_murine_iCCAvsHCC/segmentation/cleaned_mask",
        "mask_glob": "{fov}_*.tiff",
        "cell_table": "Files/spatial_murine_iCCAvsHCC/cell_table/pCSL005_cell_table.parquet",
    },
)

# Attach the study's cell table (all 439,339 cells; a few seconds).
ueler.load_bia_cell_table(viewer)

The descriptor's cell_table key names the study's cell table, and load_bia_cell_table attaches it — or pass run_viewer_bia(..., cell_table=True) to attach it as the viewer opens.

S-BIAD2557 publishes the table as both .csv and .parquet, and the descriptor above points at the Parquet one, which is why there is no fovs= here: nothing is downloaded, the file is read over HTTP range requests a column at a time, and all 439,339 cells across 455 FOVs are there from the start. Pointing cell_table at the .csv instead falls back to fetching the file into the workspace, where fovs= is worth using to keep only the rows of the FOVs you name — the CSV is 361 MB and has no column index, so it is read end to end either way.

See script/run_ueler_BIA.ipynb for more worked examples across several studies.


Expected Folder Structure

For local data, UELer expects one subdirectory per FOV, each containing single-channel TIFF images named by the channel/marker:

base_folder/
├── fov1/
│   ├── CD3.tiff
│   ├── CD8.tiff
│   └── DAPI.tiff
├── fov2/
│   ├── CD3.tiff
│   └── ...
└── ...

Next Steps

  • Learn the User Interface layout.
  • Walk through Display Settings — the pixel size, cache size, downsampling, and contrast defaults are tuned for MIBI data and are worth checking once per dataset.
  • Explore the Tutorials for individual features.
  • Check the FAQ if you run into issues.