QXYCell converts cell measurements and spatial data from multiplex
immunofluorescence images processed in QuPath into an analysis-ready AnnData
.h5ad object for cell typing, visualization, and spatial analysis.
The resulting .h5ad object can be used with downstream tools such as
Scanpy,
Squidpy,
scimap, and
SpatialData.
QXYCell is not affiliated with QuPath (GPLv3).
Prepare the QuPath inputs first, then use the compact workflow below and open the focused guides when more detail is needed.
QXYCell requires Python 3.10 or newer.
git clone https://github.com/jsonmad/QXYCell.git
cd QXYCell
conda env create -f environment.yml
conda activate qxycellVerify the installation:
python -c "import qxycell; print('QXYCell import OK')"
qxycell --helpconda activate qxycell
git pull
conda env update -f environment.yml --pruneBefore running QXYCell, follow the QuPath preparation guide (PDF version). It covers:
- Sample, tissue-feature, and imaging-artifact annotations exported as GeoJSON
- Cell segmentation and cell measurements exported as
.tsvor.csv - Single-object classifiers for channel/marker thresholds (
.json) - Cell-boundary geometry exported as GeoJSON
The guide targets QuPath 0.7.0 and multiplex immunofluorescence data from any acquisition platform. QXYCell supports square pixels only and uses a default pixel size of 0.28 µm.
To begin, define the path to the QuPath project directory and an output
directory for the QXYCell results. The output directory can be anywhere but should not sit inside of the QuPath project directory. You can run multiple QXYCell analyses, provided that each process uses a different explicit output_dir. Never share an output directory between active runs, as they would write to the same .h5ad, tables, thresholds, and plots. Automatic output directory names use minute-level timestamps. Multiple runs can read from the same QuPath project directory. Use a separate Python process or notebook and AnnData object for each run.
You can run this quickstart in an interactive Python session. Each data-processing stage checkpoints the current adata object to the active output folder. After activating the QXYCell environment, start ipython (recommended) or python from a terminal, then paste and execute each stage below in order. Pause where noted to review thresholds and cell-type YAML. If you prefer a cell-based interface, use the interactive notebook example.
ipython
# Or, if IPython is not installed:
pythonAt the interactive prompt, paste the Python code below, one stage at a time.
import qxycell as qxy
project_dir = "/path/to/qupath_project"
output_dir = "/path/to/outputs/run_1"
# Optional preflight: inspect inputs without running the analysis.
report = qxy.check(project_dir)
# Stage 1: import cell measurements and create the AnnData checkpoint.
adata = qxy.import_cells(project_dir, output_dir=output_dir)
# Stage 2: add or refresh annotations and optional cell polygons.
# Annotation names containing "sample" define adata.obs["Sample"].
qxy.add_annotations(adata, pixel_size_um=0.28)
# Optional Stage 2b: choose the identifier string used in annotation names.
qxy.remove_cells(adata, remove_cells="ignore")
# qxy.remove_cells(adata, remove_cells="folded_tissue")
# Stage 3: choose either 3A or 3B. Do not run both.
# Stage 3A: apply thresholds from QuPath object-classifier JSON files.
qxy.threshold_from_classifiers(adata)
# Stage 3B: generate, review, and apply a threshold table instead.
# threshold_table = qxy.generate_threshold_table(
# project_dir,
# output_dir=output_dir,
# )
# Pause here to review and fill every per-image threshold in the generated TSV.
# qxy.threshold_from_table(adata, threshold_table)
# Stage 4: generate the prompt used to draft celltype_logic.yaml.
qxy.celltype_prompt(
adata,
context="Describe the tissue and expected populations",
)
# Pause for biology domain expert review, save the reviewed cell type YAML, then continue.
# Stage 5: assign cell types from cell type logic.
qxy.celltype(adata, "/path/to/celltype_logic.yaml")
# Stage 6: sanity check the assigned cell types spatially.
qxy.plot_spatial(adata, category_col="celltype", show=True)
# Stage 7: plot marker positivity and intensity by assigned cell type.
qxy.plot_marker_positivity_heatmap(
adata,
category_col="celltype",
show=True,
)
qxy.plot_marker_intensity_heatmap(
adata,
category_col="celltype",
show=True,
)
# Stage 8: compare marker positivity and intensity between samples.
qxy.plot_marker_positivity_heatmap(
adata,
category_col="Sample",
show=True,
)
qxy.plot_marker_intensity_heatmap(
adata,
category_col="Sample",
show=True,
)You can exit exit() after any stage finishes successfully. To restart, activate the same environment, start a new interactive session, recreate the path variables, and load the .h5ad from the output_dir or the exact .h5ad path.
# restarting a session
import qxycell as qxy
project_dir = "/path/to/qupath_project"
output_dir = "/path/to/outputs/run_1"
adata = qxy.load(output_dir)
# or exact path to .h5ad
adata = qxy.load("/path/to/outputs/run_1/h5ad/qxycell.h5ad")Classifier thresholding saves the applied values to thresholds/classifier_thresholds.tsv. Table thresholding uses only the named
reviewed table.
Each successful stage updates the active .h5ad and refreshes
tables/cells_obs.csv and tables/markers_var.csv. If annotations are updated
after cells have been removed, rerun
adata = qxy.import_cells(project_dir, output_dir=output_dir) before refreshing
annotations and removing cells again.
For notebook setup and rerun guidance, see the interactive workflow example.
| Guide | Use it for |
|---|---|
| QuPath preparation (PDF) | Preparing images, segmenting cells, measuring features, and exporting QuPath assets |
| QuPath inputs, annotations, and thresholds | Input requirements, sample and removal annotations, pixel calibration, threshold sources, conflicts, and TMA cores |
| Running the staged workflow | Checkpoints, rerun rules, output folders, validation, and the optional single-call workflow |
| Sample metadata | Matching experimental, clinical, and batch metadata to images, samples, or TMA cores |
| Cell typing | Prompt generation, reviewed YAML rules, assignment diagnostics, validation, and reruns |
| Cellular neighbourhoods | Local composition profiles, clustering, naming, parameter review, and neighbourhood plots |
| Plotting | Spatial figures, cell boundaries, annotation polygons, bars, heatmaps, formats, and palettes |
| AnnData structure and outputs | Stored fields, dataset summaries, provenance, output files, and save/load behavior |
| Interactive workflow notebook | Running the staged workflow cell by cell |
Additional reference material:
Report reproducible bugs and feature requests through GitHub Issues. Report suspected vulnerabilities privately as described in SECURITY.md. QXYCell is released under the MIT License.
