Quick Start

This example fits two count modalities stored in a MuData object. MultiGEDI expects raw counts for M/M_list observations and performs its log1p or paired log-ratio transform internally; do not normalize or log-transform these matrices first.

Minimal multimodal example

import mudata as md
import multigedi as gd

mdata = md.read_h5mu("your_data.h5mu")

# Each modality uses AnnData orientation: cells x features.
# Both participating .obs tables contain a "sample" column.
gd.tl.multigedi(
    mdata,
    modalities={
        "gene": {"obs_type": "M", "orthoZ": True},
        "splicing": {
            "obs_type": "M_list",
            "orthoZ": False,
            "layers": (None, "M2"),
        },
    },
    sample_key="sample",
    K=20,
    max_iterations=30,
    use_gpu=False,
)

For a sample that occurs in several modalities, the cell identifiers and their within-sample order must match. Entire sample blocks may be absent from a modality.

Results

# Canonical joint payload
result = mdata.uns["multigedi"]
joint_bi = result["model"]["joint"]["Bi"]
cell_metadata = result["model"]["joint"]["global_cell_metadata"]

# Every modality gets rows aligned to its own AnnData observations.
gene_pca = mdata["gene"].obsm["X_multigedi_pca"]
splicing_pca = mdata["splicing"].obsm["X_multigedi_pca"]

Use either modality’s row-aligned coordinates with scanpy:

import scanpy as sc

sc.pp.neighbors(mdata["gene"], use_rep="X_multigedi_pca")
sc.tl.umap(mdata["gene"])
sc.pl.umap(mdata["gene"], color="sample")

Set use_gpu=True only after installing a GPU-enabled build. A different GPU batch_size is part of run identity and can change trailing float64 digits.

Single-modal GEDI

For one AnnData object, use gd.tl.gedi(adata, batch_key="sample"). Pass raw counts there as well. Single-modal results live in adata.obsm, adata.varm, and adata.uns['gedi'].

Next steps