Cross-species modality prediction using scEve#

[1]:
import warnings
warnings.simplefilter('ignore')

import scanpy as sc
import scparadise
import os
from scipy import sparse
from mousipy import translate
import muon as mu
import numpy as np
import pandas as pd

sc.set_figure_params(dpi = 150, dpi_save = 600)

Recommendations about dataset#

Our models are trained using shifted logarithm normalized data. We recommend the shifted logarithm data normalization method for the proper use of our models. sc.pp.normalize_total(adata, target_sum=None) sc.pp.log1p(adata)

[2]:
# Load ADT data from 10x Genomics
url = "https://cf.10xgenomics.com/samples/cell-exp/7.2.0/4plex_mouse_LymphNode_Spleen_TotalSeqC_multiplex_LymphNode1_BC1_AB1/4plex_mouse_LymphNode_Spleen_TotalSeqC_multiplex_LymphNode1_BC1_AB1_count_sample_filtered_feature_bc_matrix.h5"
mdata = mu.read_10x_h5("dataset.h5", backup_url = url)
mdata.var_names_make_unique()
# RNA data
adata = mdata.mod['rna'].copy()
# Protein data
adata_adt = mdata.mod['prot'].copy()
del mdata
print('RNA data', adata, sep='\n')
print('Protein data', adata_adt, sep='\n')
100%|█████████████████████████████████████| 29.7M/29.7M [00:00<00:00, 52.9MB/s]
RNA data
AnnData object with n_obs × n_vars = 7579 × 19059
    var: 'gene_ids', 'feature_types', 'genome', 'pattern', 'read', 'sequence'
Protein data
AnnData object with n_obs × n_vars = 7579 × 122
    var: 'gene_ids', 'feature_types', 'genome', 'pattern', 'read', 'sequence'

Gene expression data processing#

[3]:
# mitochondrial genes, "MT-" for human, "Mt-" for mouse
adata.var["mt"] = adata.var_names.str.startswith("mt-")
[4]:
sc.pp.calculate_qc_metrics(
    adata, qc_vars=["mt"], inplace=True, log1p=True
)
[5]:
sc.pl.violin(
    adata,
    ["n_genes_by_counts", "total_counts", "pct_counts_mt"],
    jitter=0.4,
    multi_panel=True,
)
../../../_images/tutorials_notebooks_scEve_Cross_species_modality_imputation_using_scEve_7_0.png
[6]:
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)
[7]:
# Doublet detection using scrublet
sc.external.pp.scrublet(adata)
[8]:
# Remove doublets + other QC metrics
adata = adata[adata.obs['predicted_doublet'] == False]
sc.pp.filter_cells(adata, max_genes = 6000)
sc.pp.filter_cells(adata, max_counts = 35000)
adata = adata[adata.obs['pct_counts_mt'] < 5]

Normalization, HVG, neighbors, PCA, UMAP#

[9]:
# Saving count data
adata.layers["counts"] = adata.X.copy()
# Normalization (Shifted logarithm)
sc.pp.normalize_total(adata, target_sum=None)
sc.pp.log1p(adata)
# HVG
sc.pp.highly_variable_genes(adata, n_top_genes=2000)
# PCA
sc.tl.pca(adata)
# Nearest neighbors analysis
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=20)
# UMAP
sc.tl.umap(adata)
# Clusterization
sc.tl.leiden(adata, resolution=0.5, key_added='leiden_0.5')
[10]:
# Visualise clustering
sc.pl.umap(
    adata,
    color = [
        'leiden_0.5'
    ],
    frameon = False,
    add_outline = True,
    legend_loc = 'on data',
    legend_fontsize = 9,
    legend_fontoutline = 2,
    save='_RNA_based_clustering.png'
)
WARNING: saving figure to file figures/umap_RNA_based_clustering.png
../../../_images/tutorials_notebooks_scEve_Cross_species_modality_imputation_using_scEve_13_1.png
[11]:
adata.write_h5ad('mouse_RNA_based_clustering.h5ad')

Observed ADT preprocessing#

[12]:
mu.prot.pp.clr(adata_adt)
[13]:
adata_adt = adata_adt[adata.obs_names]
adata_adt.obsm['X_umap'] = adata.obsm['X_umap']
[17]:
# Visualise observed proteins
sc.pl.umap(
    adata_adt,
    color = [
        'Ms.CD3',
        'Ms.CD4',
        'Ms.CD8a',
        'Ms.CD19',
        'Ms.IgD',
        'Ms.NK.1.1'
    ],
    frameon = False,
    cmap = 'coolwarm',
    ncols = 3
)
../../../_images/tutorials_notebooks_scEve_Cross_species_modality_imputation_using_scEve_18_0.png

scParadise prediction (scEve)#

To use the model trained on human cells, it is necessary to replace the names of mouse genes with their orthologs from the human genome. Orthologs - genes in different species that evolved from a common ancestor by speciation (Example: Acta2 in mouse, ACTA2 in human).

[15]:
# Find orthologs of mouse genes in human genome
humanized_adata = translate(adata)
100%|███████████████████████████████████| 13167/13167 [00:15<00:00, 855.33it/s]
Found direct orthologs for 12219 genes.
Found multiple orthologs for 235 genes.
Found no orthologs for 442 genes.
Found no index in biomart for 271 genes.
100%|████████████████████████████████████████| 235/235 [00:05<00:00, 40.63it/s]

[18]:
# Check matrix type and add it to raw
humanized_adata.X = sparse.csc_matrix(humanized_adata.X)
humanized_adata.raw = humanized_adata
[19]:
# Available models for cell type annotation
scparadise.sceve.available_models(query = 'PBMC')
[19]:
Model name Tissue/Organ Species Description Suspension RMSE MAE Number of Proteins
0 Human_PBMC_3p blood human Peripheral blood mononuclear cells of healthy ... cells 0.305 0.226 224
1 Human_PBMC_5p blood human Peripheral blood mononuclear cells of healthy ... cells 0.308 0.225 54
[20]:
# Download model for modality prediction
scparadise.sceve.download_model(
    model_name = 'Human_PBMC_3p',
    save_path = ''
)
[21]:
# Predict surface proteins using trained model
adata_adt_pred = scparadise.sceve.predict(
    humanized_adata,
    path_model = 'Human_PBMC_3p_scEve/',
    return_mdata = False
)
Feature prediction using the 2nd version of the scEve model
scEve model loaded from Human_PBMC_3p_scEve/
Feature alignment:
Model features: 2000
New data features: 13052
Matched features: 1162 (58.1%)
Predicting: 100%|██████████████████████████████| 29/29 [00:00<00:00, 60.83it/s]
[22]:
# Add UMAP from RNA data
adata_adt_pred.obsm['X_umap'] = adata.obsm['X_umap']
[24]:
# Visualise imputed proteins
sc.pl.umap(
    adata_adt_pred,
    color = [
        'adt_CD3-1_pred',
        'adt_CD4-1_pred',
        'adt_CD8_pred',
        'adt_CD19_pred',
        'adt_IgD_pred',
        'adt_CD56-2_pred'
    ],
    frameon = False,
    cmap = 'coolwarm',
    ncols = 3,
    save='_imputed_proteins.png'
)
WARNING: saving figure to file figures/umap_imputed_proteins.png
../../../_images/tutorials_notebooks_scEve_Cross_species_modality_imputation_using_scEve_26_1.png

Check correlation between imputed and observed proteins#

[25]:
# Create lists with observed and imputed proteins
lst_prots = ['Ms.CD3', 'Ms.CD4', 'Ms.CD8a', 'Ms.CD19', 'Ms.IgD', 'Ms.NK.1.1']
lst_imp_prots = ['adt_CD3-1_pred', 'adt_CD4-1_pred', 'adt_CD8_pred', 'adt_CD19_pred', 'adt_IgD_pred', 'adt_CD56-2_pred']
[26]:
# Calculate Pearson correlation coefficient for protein pairs
for i, j in zip(lst_prots, lst_imp_prots):
    pearson = scparadise.scnoah.pearson_coef(
        adata=adata_adt,
        adata_pred=adata_adt_pred,
        feature=i,
        feature_pred=j
    )
    coef = round(float(pearson['Pearson coefficient']), ndigits=4)
    print(f'Pearson coefficient for pair {i} - {j}: {coef}')
Pearson coefficient for pair Ms.CD3 - adt_CD3-1_pred: 0.81
Pearson coefficient for pair Ms.CD4 - adt_CD4-1_pred: 0.887
Pearson coefficient for pair Ms.CD8a - adt_CD8_pred: 0.945
Pearson coefficient for pair Ms.CD19 - adt_CD19_pred: 0.867
Pearson coefficient for pair Ms.IgD - adt_IgD_pred: 0.823
Pearson coefficient for pair Ms.NK.1.1 - adt_CD56-2_pred: 0.234
[27]:
import session_info2
session_info2.session_info()
[27]:
PackageVersion
pandas2.3.3
scanpy1.11.5
scparadise1.2.0
scipy1.17.1
mousipy0.1.7
muon0.1.7
numpy2.4.6
anndata0.12.16
ComponentInfo
Python3.11.15 (main, Jun 11 2026, 15:20:16) [GCC 14.3.0]
OSLinux-6.8.0-138-generic-x86_64-with-glibc2.39
Updated2026-09-03 19:48
Dependencies
DependencyVersion
scverse-misc0.0.3
threadpoolctl3.6.0
requests2.34.2
multidict6.7.1
prompt_toolkit3.0.52
pytorch-tabnet4.1.0
scikit-learn1.9.0
defusedxml0.7.1
fonttools4.63.0
donfig0.8.1.post1
executing2.2.1
wcwidth0.8.1
matplotlib3.11.0
comm0.2.3
asttokens3.0.1
ipython9.14.1
stack-data0.6.3
tornado6.5.7
session-info20.4.1
setuptools81.0.0
pure_eval0.2.3
pyarrow24.0.0
umap-learn0.5.12
attrs26.1.0
texttable1.7.0
jupyter_core5.9.1
kiwisolver1.5.0
scikit-image0.26.0
charset-normalizer3.4.7
typing_extensions4.15.0
python-dateutil2.9.0.post0
xarray2026.4.0
pynndescent0.6.0
jupyter_client8.9.1
optuna4.9.0
colorlog6.10.1
sparse0.18.0
cycler0.12.1
google-crc32c1.8.0
parso0.8.7
numcodecs0.16.5
decorator5.3.1
cloudpickle3.1.2
pyzmq27.1.0
argparse1.4.0 (1.1)
cuda-pathfinder1.5.5
numba0.65.1
platformdirs4.10.0
ipykernel7.3.0
packaging26.0
seaborn0.13.2
zarr3.1.6
torch2.12.0 (2.12.0+cu130)
psutil7.2.2
Cython3.3.0
shap0.49.1
typing3.7.4.3
sklearn-compat0.1.6
yarl1.24.2
mudata0.3.8
imbalanced-learn0.14.2
pathlib1.0.1
jedi0.20.0
six1.17.0
slicer0.0.8
pytz2026.2
aiosignal1.4.0
joblib1.5.3
h5py3.16.0
dataclasses0.6
narwhals2.22.1
cffi2.0.0
certifi2026.5.20 (2026.05.20)
statsmodels0.14.6
aiohttp3.14.1
tqdm4.68.2
pillow12.2.0
PyYAML6.0.3
urllib32.7.0
patsy1.0.2
aiohappyeyeballs2.6.2
matplotlib-inline0.2.2
frozenlist1.8.0
traitlets5.15.1
leidenalg0.12.0
propcache0.5.2
Pygments2.20.0
idna3.18
lazy-loader0.5
debugpy1.8.21
pycparser3.0 (3.00)
rich15.0.0
igraph1.0.0
natsort8.4.0
llvmlite0.47.0
cuda-bindings13.3.1
plottable0.1.5
opt_einsum3.4.0
pyparsing3.3.2
fsspec2026.4.0
legacy-api-wrap1.5
Copyable Markdown
| Package    | Version |
| ---------- | ------- |
| pandas     | 2.3.3   |
| scanpy     | 1.11.5  |
| scparadise | 1.2.0   |
| scipy      | 1.17.1  |
| mousipy    | 0.1.7   |
| muon       | 0.1.7   |
| numpy      | 2.4.6   |
| anndata    | 0.12.16 |

| Dependency         | Version                |
| ------------------ | ---------------------- |
| scverse-misc       | 0.0.3                  |
| threadpoolctl      | 3.6.0                  |
| requests           | 2.34.2                 |
| multidict          | 6.7.1                  |
| prompt_toolkit     | 3.0.52                 |
| pytorch-tabnet     | 4.1.0                  |
| scikit-learn       | 1.9.0                  |
| defusedxml         | 0.7.1                  |
| fonttools          | 4.63.0                 |
| donfig             | 0.8.1.post1            |
| executing          | 2.2.1                  |
| wcwidth            | 0.8.1                  |
| matplotlib         | 3.11.0                 |
| comm               | 0.2.3                  |
| asttokens          | 3.0.1                  |
| ipython            | 9.14.1                 |
| stack-data         | 0.6.3                  |
| tornado            | 6.5.7                  |
| session-info2      | 0.4.1                  |
| setuptools         | 81.0.0                 |
| pure_eval          | 0.2.3                  |
| pyarrow            | 24.0.0                 |
| umap-learn         | 0.5.12                 |
| attrs              | 26.1.0                 |
| texttable          | 1.7.0                  |
| jupyter_core       | 5.9.1                  |
| kiwisolver         | 1.5.0                  |
| scikit-image       | 0.26.0                 |
| charset-normalizer | 3.4.7                  |
| typing_extensions  | 4.15.0                 |
| python-dateutil    | 2.9.0.post0            |
| xarray             | 2026.4.0               |
| pynndescent        | 0.6.0                  |
| jupyter_client     | 8.9.1                  |
| optuna             | 4.9.0                  |
| colorlog           | 6.10.1                 |
| sparse             | 0.18.0                 |
| cycler             | 0.12.1                 |
| google-crc32c      | 1.8.0                  |
| parso              | 0.8.7                  |
| numcodecs          | 0.16.5                 |
| decorator          | 5.3.1                  |
| cloudpickle        | 3.1.2                  |
| pyzmq              | 27.1.0                 |
| argparse           | 1.4.0 (1.1)            |
| cuda-pathfinder    | 1.5.5                  |
| numba              | 0.65.1                 |
| platformdirs       | 4.10.0                 |
| ipykernel          | 7.3.0                  |
| packaging          | 26.0                   |
| seaborn            | 0.13.2                 |
| zarr               | 3.1.6                  |
| torch              | 2.12.0 (2.12.0+cu130)  |
| psutil             | 7.2.2                  |
| Cython             | 3.3.0                  |
| shap               | 0.49.1                 |
| typing             | 3.7.4.3                |
| sklearn-compat     | 0.1.6                  |
| yarl               | 1.24.2                 |
| mudata             | 0.3.8                  |
| imbalanced-learn   | 0.14.2                 |
| pathlib            | 1.0.1                  |
| jedi               | 0.20.0                 |
| six                | 1.17.0                 |
| slicer             | 0.0.8                  |
| pytz               | 2026.2                 |
| aiosignal          | 1.4.0                  |
| joblib             | 1.5.3                  |
| h5py               | 3.16.0                 |
| dataclasses        | 0.6                    |
| narwhals           | 2.22.1                 |
| cffi               | 2.0.0                  |
| certifi            | 2026.5.20 (2026.05.20) |
| statsmodels        | 0.14.6                 |
| aiohttp            | 3.14.1                 |
| tqdm               | 4.68.2                 |
| pillow             | 12.2.0                 |
| PyYAML             | 6.0.3                  |
| urllib3            | 2.7.0                  |
| patsy              | 1.0.2                  |
| aiohappyeyeballs   | 2.6.2                  |
| matplotlib-inline  | 0.2.2                  |
| frozenlist         | 1.8.0                  |
| traitlets          | 5.15.1                 |
| leidenalg          | 0.12.0                 |
| propcache          | 0.5.2                  |
| Pygments           | 2.20.0                 |
| idna               | 3.18                   |
| lazy-loader        | 0.5                    |
| debugpy            | 1.8.21                 |
| pycparser          | 3.0 (3.00)             |
| rich               | 15.0.0                 |
| igraph             | 1.0.0                  |
| natsort            | 8.4.0                  |
| llvmlite           | 0.47.0                 |
| cuda-bindings      | 13.3.1                 |
| plottable          | 0.1.5                  |
| opt_einsum         | 3.4.0                  |
| pyparsing          | 3.3.2                  |
| fsspec             | 2026.4.0               |
| legacy-api-wrap    | 1.5                    |

| Component | Info                                               |
| --------- | -------------------------------------------------- |
| Python    | 3.11.15 (main, Jun 11 2026, 15:20:16) [GCC 14.3.0] |
| OS        | Linux-6.8.0-138-generic-x86_64-with-glibc2.39      |
| Updated   | 2026-09-03 19:48                                   |