"
]
@@ -839,9 +827,9 @@
],
"metadata": {
"kernelspec": {
- "display_name": "conda_scar-0.6.0",
+ "display_name": "conda_gpu",
"language": "python",
- "name": "conda_scar-0.6.0"
+ "name": "conda_gpu"
},
"language_info": {
"codemirror_mode": {
@@ -853,7 +841,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.12.3"
+ "version": "3.10.9"
},
"vscode": {
"interpreter": {
diff --git a/docs/tutorials/scAR_tutorial_sgRNA_assignment.ipynb b/docs/tutorials/scAR_tutorial_sgRNA_assignment.ipynb
index 06ad9c5..3ad4d94 100644
--- a/docs/tutorials/scAR_tutorial_sgRNA_assignment.ipynb
+++ b/docs/tutorials/scAR_tutorial_sgRNA_assignment.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "markdown",
- "id": "b48c6ca1",
+ "id": "db46edf9",
"metadata": {},
"source": [
"# sgRNA assignment\n",
@@ -27,7 +27,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "21831340",
+ "id": "22b76e35",
"metadata": {},
"outputs": [],
"source": [
@@ -42,7 +42,7 @@
{
"cell_type": "code",
"execution_count": 1,
- "id": "a5425759",
+ "id": "39e1033c",
"metadata": {},
"outputs": [],
"source": [
@@ -58,7 +58,7 @@
},
{
"cell_type": "markdown",
- "id": "162dc896",
+ "id": "86f1e620",
"metadata": {},
"source": [
"## Download data\n",
@@ -69,13 +69,13 @@
{
"cell_type": "code",
"execution_count": 2,
- "id": "a2f319f4",
+ "id": "e2d98e7d",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "ae48a91f3a364204a6b55388c9c0582e",
+ "model_id": "387a73ce320c440f963734dbf756e882",
"version_major": 2,
"version_minor": 0
},
@@ -97,7 +97,7 @@
},
{
"cell_type": "markdown",
- "id": "11f41dbe",
+ "id": "bde606d4",
"metadata": {},
"source": [
"sgRNA counts (unfiltered droplets)"
@@ -106,7 +106,7 @@
{
"cell_type": "code",
"execution_count": 3,
- "id": "bb4028ce",
+ "id": "0dfe91ac",
"metadata": {},
"outputs": [],
"source": [
@@ -115,7 +115,7 @@
},
{
"cell_type": "markdown",
- "id": "6ef0d42f",
+ "id": "c2a8ea3a",
"metadata": {
"tags": []
},
@@ -125,7 +125,7 @@
},
{
"cell_type": "markdown",
- "id": "83b8c23f",
+ "id": "ea33196f",
"metadata": {},
"source": [
"Identify cell-containing and cell-free droplets using kneeplot of mRNA counts."
@@ -133,7 +133,7 @@
},
{
"cell_type": "markdown",
- "id": "b3005918",
+ "id": "09882854",
"metadata": {},
"source": [
"\n",
@@ -148,7 +148,7 @@
{
"cell_type": "code",
"execution_count": 4,
- "id": "53b0ac8c",
+ "id": "63ae0666",
"metadata": {},
"outputs": [],
"source": [
@@ -164,7 +164,7 @@
},
{
"cell_type": "markdown",
- "id": "2074f2c5",
+ "id": "965e7f43",
"metadata": {},
"source": [
"The thresholds (200 and 500) are experiment-specific. We currently manually determine them by examing the following kneeplot. "
@@ -173,12 +173,12 @@
{
"cell_type": "code",
"execution_count": 5,
- "id": "4c7172d8",
+ "id": "f16e1041",
"metadata": {},
"outputs": [
{
"data": {
- "image/png": "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",
+ "image/png": "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",
"text/plain": [
""
]
@@ -213,7 +213,7 @@
},
{
"cell_type": "markdown",
- "id": "76384998",
+ "id": "af962da9",
"metadata": {
"tags": []
},
@@ -224,7 +224,7 @@
{
"cell_type": "code",
"execution_count": 6,
- "id": "da65b16c",
+ "id": "6ea194fa",
"metadata": {},
"outputs": [],
"source": [
@@ -234,7 +234,7 @@
{
"cell_type": "code",
"execution_count": 7,
- "id": "6f1f6559",
+ "id": "f653d1e1",
"metadata": {},
"outputs": [
{
@@ -452,7 +452,7 @@
},
{
"cell_type": "markdown",
- "id": "1bafe491",
+ "id": "a87b59af",
"metadata": {},
"source": [
"**Ambient profile of sgRNAs**"
@@ -461,7 +461,7 @@
{
"cell_type": "code",
"execution_count": 8,
- "id": "dd0661af",
+ "id": "d452ce6c",
"metadata": {},
"outputs": [
{
@@ -537,7 +537,7 @@
},
{
"cell_type": "markdown",
- "id": "eccdb2c9",
+ "id": "dc36ac46",
"metadata": {},
"source": [
"## Training"
@@ -546,34 +546,33 @@
{
"cell_type": "code",
"execution_count": 9,
- "id": "33a6a2e9",
+ "id": "020c0b79",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
- "2024-08-10 21:02:55|INFO|model|cuda is detected and will be used.\n",
- "2024-08-10 21:02:55|INFO|VAE|Running VAE using the following param set:\n",
- "2024-08-10 21:02:55|INFO|VAE|...denoised count type: sgRNAs\n",
- "2024-08-10 21:02:55|INFO|VAE|...count model: binomial\n",
- "2024-08-10 21:02:55|INFO|VAE|...num_input_feature: 93\n",
- "2024-08-10 21:02:55|INFO|VAE|...NN_layer1: 150\n",
- "2024-08-10 21:02:55|INFO|VAE|...NN_layer2: 100\n",
- "2024-08-10 21:02:55|INFO|VAE|...latent_space: 15\n",
- "2024-08-10 21:02:55|INFO|VAE|...dropout_prob: 0.00\n",
- "2024-08-10 21:02:55|INFO|VAE|...expected data sparsity: 1.00\n",
- "2024-08-10 21:02:55|INFO|model|kld_weight: 1.00e-05\n",
- "2024-08-10 21:02:55|INFO|model|learning rate: 1.00e-03\n",
- "2024-08-10 21:02:55|INFO|model|lr_step_size: 5\n",
- "2024-08-10 21:02:55|INFO|model|lr_gamma: 0.97\n"
+ "2023-05-01 16:45:39|INFO|VAE|Running VAE using the following param set:\n",
+ "2023-05-01 16:45:39|INFO|VAE|...denoised count type: sgRNAs\n",
+ "2023-05-01 16:45:39|INFO|VAE|...count model: binomial\n",
+ "2023-05-01 16:45:39|INFO|VAE|...num_input_feature: 93\n",
+ "2023-05-01 16:45:39|INFO|VAE|...NN_layer1: 150\n",
+ "2023-05-01 16:45:39|INFO|VAE|...NN_layer2: 100\n",
+ "2023-05-01 16:45:39|INFO|VAE|...latent_space: 15\n",
+ "2023-05-01 16:45:39|INFO|VAE|...dropout_prob: 0.00\n",
+ "2023-05-01 16:45:39|INFO|VAE|...expected data sparsity: 1.00\n",
+ "2023-05-01 16:45:40|INFO|model|kld_weight: 1.00e-05\n",
+ "2023-05-01 16:45:40|INFO|model|learning rate: 1.00e-03\n",
+ "2023-05-01 16:45:40|INFO|model|lr_step_size: 5\n",
+ "2023-05-01 16:45:40|INFO|model|lr_gamma: 0.97\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Training: 100%|██████████| 100/100 [02:55<00:00, 1.76s/it, Loss=4.2189e+02]\n"
+ "Training: 100%|██████████| 100/100 [05:17<00:00, 3.18s/it, Loss=2.8968e+02]\n"
]
}
],
@@ -593,7 +592,7 @@
},
{
"cell_type": "markdown",
- "id": "510e3173",
+ "id": "397a229f",
"metadata": {},
"source": [
"Resulting assignment is saved in `sgRNAs.feature_assignment`.\n",
@@ -604,7 +603,7 @@
{
"cell_type": "code",
"execution_count": 10,
- "id": "b0a4f116",
+ "id": "5197865c",
"metadata": {},
"outputs": [
{
@@ -635,8 +634,8 @@
" \n",
" \n",
" AAACCCAAGCTAAGTA-1 \n",
- " APH1A-1, H2AFY-1 \n",
- " 2 \n",
+ " H2AFY-1 \n",
+ " 1 \n",
" \n",
" \n",
" AAACCCAAGGAAGTGA-1 \n",
@@ -645,13 +644,13 @@
" \n",
" \n",
" AAACCCAAGGTTGGAC-1 \n",
- " GSK3A-1, ACE2-1 \n",
- " 2 \n",
+ " ACE2-1 \n",
+ " 1 \n",
" \n",
" \n",
" AAACCCAAGTGCGTCC-1 \n",
- " H2AFY-2, ACE2-2 \n",
- " 2 \n",
+ " ACE2-2 \n",
+ " 1 \n",
" \n",
" \n",
" AAACCCAAGTGCTCGC-1 \n",
@@ -694,18 +693,18 @@
""
],
"text/plain": [
- " sgRNAs n_sgRNAs\n",
- "AAACCCAAGCTAAGTA-1 APH1A-1, H2AFY-1 2\n",
- "AAACCCAAGGAAGTGA-1 PPIB-2 1\n",
- "AAACCCAAGGTTGGAC-1 GSK3A-1, ACE2-1 2\n",
- "AAACCCAAGTGCGTCC-1 H2AFY-2, ACE2-2 2\n",
- "AAACCCAAGTGCTCGC-1 CTCF-2 1\n",
- "... ... ...\n",
- "TTTGTTGTCCCATTTA-1 CSNK2A1-1 1\n",
- "TTTGTTGTCGGAACTT-1 EIF4EBP1-2 1\n",
- "TTTGTTGTCGGCTGTG-1 SUZ12-1 1\n",
- "TTTGTTGTCTGGGCGT-1 GSK3A-2 1\n",
- "TTTGTTGTCTTCCAGC-1 PPIB-2, RBBP4-1 2\n",
+ " sgRNAs n_sgRNAs\n",
+ "AAACCCAAGCTAAGTA-1 H2AFY-1 1\n",
+ "AAACCCAAGGAAGTGA-1 PPIB-2 1\n",
+ "AAACCCAAGGTTGGAC-1 ACE2-1 1\n",
+ "AAACCCAAGTGCGTCC-1 ACE2-2 1\n",
+ "AAACCCAAGTGCTCGC-1 CTCF-2 1\n",
+ "... ... ...\n",
+ "TTTGTTGTCCCATTTA-1 CSNK2A1-1 1\n",
+ "TTTGTTGTCGGAACTT-1 EIF4EBP1-2 1\n",
+ "TTTGTTGTCGGCTGTG-1 SUZ12-1 1\n",
+ "TTTGTTGTCTGGGCGT-1 GSK3A-2 1\n",
+ "TTTGTTGTCTTCCAGC-1 PPIB-2, RBBP4-1 2\n",
"\n",
"[21091 rows x 2 columns]"
]
@@ -721,7 +720,7 @@
},
{
"cell_type": "markdown",
- "id": "cebd202d",
+ "id": "8131bc78",
"metadata": {},
"source": [
"## Visulization"
@@ -729,7 +728,7 @@
},
{
"cell_type": "markdown",
- "id": "46dc569a",
+ "id": "15b9190b",
"metadata": {},
"source": [
"Plot setting"
@@ -738,7 +737,7 @@
{
"cell_type": "code",
"execution_count": 11,
- "id": "b304bffd",
+ "id": "5234d078",
"metadata": {},
"outputs": [
{
@@ -775,7 +774,7 @@
},
{
"cell_type": "markdown",
- "id": "ee7c6080",
+ "id": "cfc89b2f",
"metadata": {},
"source": [
"### Cell number of sgRNA assignments"
@@ -784,7 +783,7 @@
{
"cell_type": "code",
"execution_count": 12,
- "id": "aa8de84e",
+ "id": "7e892df4",
"metadata": {
"tags": [
"nbsphinx-gallery",
@@ -818,7 +817,7 @@
},
{
"cell_type": "markdown",
- "id": "13ce1cf5",
+ "id": "4870a675",
"metadata": {},
"source": [
"Most of cells are assigned with a single sgRNA."
@@ -827,9 +826,9 @@
],
"metadata": {
"kernelspec": {
- "display_name": "conda_scar-0.6.0",
+ "display_name": "conda_gpu",
"language": "python",
- "name": "conda_scar-0.6.0"
+ "name": "conda_gpu"
},
"language_info": {
"codemirror_mode": {
@@ -841,7 +840,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.12.3"
+ "version": "3.10.9"
},
"vscode": {
"interpreter": {
diff --git a/pyproject.toml b/pyproject.toml
index cbd0b18..07f6597 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -33,7 +33,7 @@ Changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md"
[tool.semantic_release]
version_toml = ["pyproject.toml:project.version"]
major_on_zero = false
-branch = "main"
+branch = "develop"
upload_to_release = false
hvcs = "github"
upload_to_repository = false
diff --git a/scar/main/__main__.py b/scar/main/__main__.py
index fb7cb07..0f22dcb 100644
--- a/scar/main/__main__.py
+++ b/scar/main/__main__.py
@@ -4,11 +4,14 @@
import argparse
import os
-import pandas as pd, scanpy as sc
+import pandas as pd
+import scanpy as sc
+from scipy.sparse import csr_matrix
from ._scar import model
from ..__init__ import __version__
from ._utils import get_logger
+
def main():
"""main function for command line interface"""
args = Config()
@@ -25,9 +28,6 @@ def main():
epochs = args.epochs
device = args.device
sparsity = args.sparsity
- batchkey = args.batchkey
- cachecapacity = args.cachecapacity
- gnf = bool(args.get_native_frequencies)
save_model = args.save_model
batch_size = args.batchsize
batch_size_infer = args.batchsize_infer
@@ -63,37 +63,37 @@ def main():
if feature_type.lower() == "all":
features = adata.var["feature_types"].unique()
- count_matrix = adata.copy()
+ count_matrix = adata.to_df()
# Denoising mRNAs
elif feature_type.lower() in ["mrna", "mrnas"]:
features = "Gene Expression"
adata_fb = adata[:, adata.var["feature_types"] == features]
- count_matrix = adata_fb.copy()
+ count_matrix = adata_fb.to_df()
# Denoising sgRNAs
elif feature_type.lower() in ["sgrna", "sgrnas"]:
features = "CRISPR Guide Capture"
adata_fb = adata[:, adata.var["feature_types"] == features]
- count_matrix = adata_fb.copy()
+ count_matrix = adata_fb.to_df()
# Denoising CMO tags
elif feature_type.lower() in ["tag", "tags"]:
features = "Multiplexing Capture"
adata_fb = adata[:, adata.var["feature_types"] == features]
- count_matrix = adata_fb.copy()
+ count_matrix = adata_fb.to_df()
# Denoising ADTs
elif feature_type.lower() in ["adt", "adts"]:
features = "Antibody Capture"
adata_fb = adata[:, adata.var["feature_types"] == features]
- count_matrix = adata_fb.copy()
+ count_matrix = adata_fb.to_df()
# Denoising ATAC peaks
elif feature_type.lower() in ["atac"]:
features = "Peaks"
adata_fb = adata[:, adata.var["feature_types"] == features]
- count_matrix = adata_fb.copy()
+ count_matrix = adata_fb.to_df()
main_logger.info(f"modalities to denoise: {features}")
@@ -135,8 +135,6 @@ def main():
latent_dim=latent_dim,
feature_type=feature_type,
count_model=count_model,
- batch_key=batchkey,
- cache_capacity=cachecapacity,
sparsity=sparsity,
device=device,
)
@@ -149,7 +147,6 @@ def main():
scar_model.inference(
adjust=adjust,
- get_native_frequencies=gnf,
round_to_int=round_to_int,
batch_size=batch_size_infer,
clip_to_obs=clip_to_obs,
@@ -170,35 +167,30 @@ def main():
)
pd.DataFrame(
- scar_model.native_counts.toarray(),
+ scar_model.native_counts,
index=count_matrix.index,
columns=count_matrix.columns,
).to_pickle(output_path01)
- main_logger.info(f"denoised counts saved in: {output_path01}")
-
pd.DataFrame(
- scar_model.noise_ratio.toarray(),
- index=count_matrix.index,
- columns=["noise_ratio"]
+ scar_model.bayesfactor,
+ index=count_matrix.index,
+ columns=count_matrix.columns,
+ ).to_pickle(output_path02)
+ pd.DataFrame(
+ scar_model.native_frequencies,
+ index=count_matrix.index,
+ columns=count_matrix.columns,
+ ).to_pickle(output_path03)
+ pd.DataFrame(
+ scar_model.noise_ratio, index=count_matrix.index, columns=["noise_ratio"]
).to_pickle(output_path04)
- main_logger.info(f"expected noise ratio saved in: {output_path04}")
- if scar_model.native_frequencies is not None:
- pd.DataFrame(
- scar_model.native_frequencies.toarray(),
- index=count_matrix.index,
- columns=count_matrix.columns,
- ).to_pickle(output_path03)
- main_logger.info(f"expected native frequencies saved in: {output_path03}")
+ main_logger.info(f"denoised counts saved in: {output_path01}")
+ main_logger.info(f"BayesFactor matrix saved in: {output_path02}")
+ main_logger.info(f"expected native frequencies saved in: {output_path03}")
+ main_logger.info(f"expected noise ratio saved in: {output_path04}")
if feature_type.lower() in ["sgrna", "sgrnas", "tag", "tags", "cmo", "cmos"]:
- pd.DataFrame(
- scar_model.bayesfactor.toarray(),
- index=count_matrix.index,
- columns=count_matrix.columns,
- ).to_pickle(output_path02)
- main_logger.info(f"BayesFactor matrix saved in: {output_path02}")
-
output_path05 = os.path.join(output_dir, "assignment.pickle")
scar_model.feature_assignment.to_pickle(output_path05)
main_logger.info(f"assignment saved in: {output_path05}")
@@ -209,21 +201,23 @@ def main():
)
denoised_adata = adata.copy()
- denoised_adata.X = scar_model.native_counts
+ denoised_adata.X = csr_matrix(scar_model.native_counts)
denoised_adata.obs["noise_ratio"] = pd.DataFrame(
- scar_model.noise_ratio.toarray(),
- index=count_matrix.obs_names,
+ scar_model.noise_ratio,
+ index=count_matrix.index,
columns=["noise_ratio"],
)
- if scar_model.native_frequencies is not None:
- denoised_adata.layers["native_frequencies"] = scar_model.native_frequencies.toarray()
+
+ denoised_adata.layers["native_frequencies"] = csr_matrix(
+ scar_model.native_frequencies
+ )
+ denoised_adata.layers["BayesFactor"] = csr_matrix(scar_model.bayesfactor)
if feature_type.lower() in ["sgrna", "sgrnas", "tag", "tags", "cmo", "cmos"]:
denoised_adata.obs = denoised_adata.obs.join(scar_model.feature_assignment)
- denoised_adata.layers["BayesFactor"] = scar_model.bayesfactor.toarray()
denoised_adata.write(output_path_h5ad)
- main_logger.info(f"the denoised h5ad file saved in: {output_path_h5ad}")
+ main_logger.info("the denoised h5ad file saved in: {output_path_h5ad}")
class Config:
@@ -244,7 +238,8 @@ def scar_parser():
"""Argument parser"""
parser = argparse.ArgumentParser(
- description="scAR (single-cell Ambient Remover) is a deep learning model for removal of the ambient signals in droplet-based single cell omics",
+ description="scAR (single cell Ambient Remover): \
+ denoising drop-based single-cell omics data",
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument(
@@ -285,27 +280,6 @@ def scar_parser():
default=0.9,
help="The sparsity of expected native signals",
)
- parser.add_argument(
- "-bk",
- "--batchkey",
- type=str,
- default=None,
- help="The batch key for batch correction",
- )
- parser.add_argument(
- "-cache",
- "--cachecapacity",
- type=int,
- default=20000,
- help="The capacity of cache for batch correction",
- )
- parser.add_argument(
- "-gnf",
- "--get_native_frequencies",
- type=int,
- default=0,
- help="Whether to get native frequencies, 0 or 1, by default 0, not to get native frequencies",
- )
parser.add_argument(
"-hl1",
"--hidden_layer1",
diff --git a/scar/main/_scar.py b/scar/main/_scar.py
index 7fcaac4..5d8a94d 100644
--- a/scar/main/_scar.py
+++ b/scar/main/_scar.py
@@ -2,12 +2,17 @@
"""The main module of scar"""
-import sys, time, contextlib, torch
+import sys
+import time
+import warnings
from typing import Optional, Union
-from scipy import sparse
-import numpy as np, pandas as pd, anndata as ad
+import contextlib
+import numpy as np
+import pandas as pd
+import anndata as ad
-from torch.utils.data import Dataset, random_split, DataLoader
+import torch
+from sklearn.model_selection import train_test_split
from tqdm import tqdm
from tqdm.contrib import DummyTqdmFile
@@ -86,19 +91,15 @@ class model:
Thank Will Macnair for the valuable feedback.
.. versionadded:: 0.4.0
- cache_capacity : int, optional
- the capacity of caching data on GPU. Set a smaller value upon GPU memory issue. By default 20000 cells are cached.
-
- .. versionadded:: 0.7.0
batch_key : str, optional
batch key in AnnData.obs, by default None. \
If assigned, batch ambient removel will be performed and \
the ambient profile will be estimated for each batch.
- .. versionadded:: 0.7.0
+ .. versionadded:: 0.6.1
device : str, optional
- either "auto, "cpu" or "cuda" or "mps", by default "auto"
+ either "auto, "cpu" or "cuda", by default "auto"
verbose : bool, optional
whether to print the details, by default True
@@ -152,7 +153,7 @@ class model:
sorted_native_counts = citeseq.native_signals[citeseq.celltype.argsort()][
:, citeseq.ambient_profile.argsort()
] # native counts
- sorted_denoised_counts = citeseq_denoised.native_counts.toarray()[citeseq.celltype.argsort()][
+ sorted_denoised_counts = citeseq_denoised.native_counts[citeseq.celltype.argsort()][
:, citeseq.ambient_profile.argsort()
] # denoised counts
@@ -212,7 +213,6 @@ def __init__(
sparsity: float = 0.9,
batch_key: str = None,
device: str = "auto",
- cache_capacity: int = 20000,
verbose: bool = True,
):
"""initialize object"""
@@ -224,13 +224,14 @@ def __init__(
if device == "auto":
if torch.cuda.is_available():
self.device = torch.device("cuda")
- self.logger.info(f"{self.device} is detected and will be used.")
+ self.logger.info("CPU is detected and will be used.")
elif torch.backends.mps.is_available() and torch.backends.mps.is_built():
self.device = torch.device("mps")
- self.logger.info(f"{self.device} is detected and will be used.")
+ self.logger.info("MPS is detected and will be used.")
+ self.logger.warning("PyTorch is slower on MPS than on the CPU; we recommend using the CPU by specifying device='cpu' on Mac.")
else:
self.device = torch.device("cpu")
- self.logger.info(f"No GPU detected. {self.device} will be used.")
+ self.logger.info("No GPU detected. Use CPU instead.")
else:
self.device = device
self.logger.info(f"{device} will be used.")
@@ -273,19 +274,24 @@ def __init__(
"""float, the sparsity of expected native signals. (0, 1]. \
Forced to be one in the mode of "sgRNA(s)" and "tag(s)".
"""
- self.cache_capacity = cache_capacity
- """int, the capacity of caching data on GPU. Set a smaller value upon GPU memory issue. By default 20000 cells are cached on GPU/MPS.
-
- .. versionadded:: 0.7.0
- """
- if isinstance(raw_count, ad.AnnData):
- if batch_key is not None:
+ if isinstance(raw_count, str):
+ raw_count = pd.read_pickle(raw_count)
+ elif isinstance(raw_count, np.ndarray):
+ raw_count = pd.DataFrame(
+ raw_count,
+ index=range(raw_count.shape[0]),
+ columns=range(raw_count.shape[1]),
+ )
+ elif isinstance(raw_count, pd.DataFrame):
+ pass
+ elif isinstance(raw_count, ad.AnnData):
+ if batch_key:
if batch_key not in raw_count.obs.columns:
raise ValueError(f"{batch_key} not found in AnnData.obs.")
self.logger.info(
- f"Found {raw_count.obs[batch_key].nunique()} batches defined by {batch_key} in AnnData.obs. Estimating ambient profile per batch..."
+ f"Estimating ambient profile for each batch defined by {batch_key} in AnnData.obs..."
)
batch_id_per_cell = pd.Categorical(raw_count.obs[batch_key]).codes
ambient_profile = np.empty((len(np.unique(batch_id_per_cell)),raw_count.shape[1]))
@@ -294,51 +300,38 @@ def __init__(
ambient_profile[batch_id, :] = subset.X.sum(axis=0) / subset.X.sum()
# add a mapper to locate the batch id
- self.batch_id = batch_id_per_cell
- self.n_batch = len(np.unique(batch_id_per_cell))
- else:
- # get ambient profile from AnnData.uns
- if "ambient_profile_all" in raw_count.uns:
- self.logger.info(
- "Found ambient profile in AnnData.uns['ambient_profile_all']"
- )
- ambient_profile = raw_count.uns["ambient_profile_all"]
- else:
- self.logger.info(
- "Ambient profile not found in AnnData.uns['ambient_profile'], estimating it by averaging pooled cells..."
- )
-
- elif isinstance(raw_count, str):
- # read pickle file into dataframe
- raw_count = pd.read_pickle(raw_count)
+ self.batch_id = torch.from_numpy(batch_id_per_cell).int().to(self.device)
+ self.n_batch = np.unique(batch_id_per_cell).size
- elif isinstance(raw_count, np.ndarray):
- # convert np.array to pd.DataFrame
- raw_count = pd.DataFrame(
- raw_count,
- index=range(raw_count.shape[0]),
- columns=range(raw_count.shape[1]),
- )
-
- elif isinstance(raw_count, pd.DataFrame):
- pass
+ # get ambient profile from AnnData.uns
+ elif (ambient_profile is None) and ("ambient_profile_all" in raw_count.uns):
+ self.logger.info(
+ "Found ambient profile in AnnData.uns['ambient_profile_all']"
+ )
+ ambient_profile = raw_count.uns["ambient_profile_all"]
+ elif (ambient_profile is None) and (
+ "ambient_profile_all" not in raw_count.uns
+ ):
+ self.logger.info(
+ "Ambient profile not found in AnnData.uns['ambient_profile'], estimating it by averaging pooled cells..."
+ )
+ # convert AnnData to pd.DataFrame
+ raw_count = raw_count.to_df()
else:
raise TypeError(
- f"Expecting str or np.array or pd.DataFrame or AnnData object, but get a {type(raw_count)}"
+ f"Expecting str or np.array or pd.DataFrame object, but get a {type(raw_count)}"
)
- self.raw_count = raw_count
+ raw_count = raw_count.fillna(0) # missing vals -> zeros
+
+ # Loading numpy to tensor on GPU
+ self.raw_count = raw_count.values
"""raw_count : np.ndarray, raw count matrix.
"""
self.n_features = raw_count.shape[1]
- """int, number of features.
- """
- self.cell_id = raw_count.index.to_list() if isinstance(raw_count, pd.DataFrame) else raw_count.obs_names.to_list()
- """list, cell id.
- """
- self.feature_names = raw_count.columns.to_list() if isinstance(raw_count, pd.DataFrame) else raw_count.var_names.to_list()
- """list, feature names.
- """
+
+ self.cell_id = list(raw_count.index)
+ self.feature_names = list(raw_count.columns)
if isinstance(ambient_profile, str):
ambient_profile = pd.read_pickle(ambient_profile)
@@ -348,13 +341,9 @@ def __init__(
elif isinstance(ambient_profile, np.ndarray):
ambient_profile = np.nan_to_num(ambient_profile) # missing vals -> zeros
elif not ambient_profile:
- self.logger.info(" Evaluate ambient profile from cells")
- if isinstance(raw_count, pd.DataFrame):
- ambient_profile = raw_count.sum() / raw_count.sum().sum()
- ambient_profile = ambient_profile.fillna(0).values
- elif isinstance(raw_count, ad.AnnData):
- ambient_profile = np.array(raw_count.X.sum(axis=0)/raw_count.X.sum())
- ambient_profile = np.nan_to_num(ambient_profile).flatten()
+ self.logger.info(" Evaluate empty profile from cells")
+ ambient_profile = raw_count.sum() / raw_count.sum().sum()
+ ambient_profile = ambient_profile.fillna(0).values
else:
raise TypeError(
f"Expecting str / np.array / None / pd.DataFrame, but get a {type(ambient_profile)}"
@@ -366,7 +355,7 @@ def __init__(
.reshape(1, -1)
)
# add a mapper to locate the artificial batch id
- self.batch_id = np.zeros(raw_count.shape[0], dtype=int)#.reshape(-1, 1)
+ self.batch_id = torch.zeros(raw_count.shape[0]).int().to(self.device)
self.n_batch = 1
self.ambient_profile = ambient_profile
@@ -448,14 +437,19 @@ def train(
After training, a trained_model attribute will be added.
"""
+
+ list_ids = list(range(self.raw_count.shape[0]))
+ train_ids, test_ids = train_test_split(list_ids, train_size=train_size)
+
# Generators
- total_dataset = UMIDataset(self.raw_count, self.ambient_profile, self.batch_id, device=self.device, cache_capacity=self.cache_capacity)
- training_set, validation_set = random_split(total_dataset, [train_size, 1 - train_size])
- training_generator = DataLoader(
- training_set, batch_size=batch_size, shuffle=shuffle,
- drop_last=True
+ training_set = UMIDataset(self.raw_count, self.ambient_profile, self.batch_id, device=self.device, list_ids=train_ids)
+ training_generator = torch.utils.data.DataLoader(
+ training_set, batch_size=batch_size, shuffle=shuffle
+ )
+ val_set = UMIDataset(self.raw_count, self.ambient_profile, self.batch_id, device=self.device, list_ids=test_ids)
+ val_generator = torch.utils.data.DataLoader(
+ val_set, batch_size=batch_size, shuffle=shuffle
)
- self.dataset = total_dataset
loss_values = []
@@ -549,7 +543,6 @@ def inference(
cutoff=3,
round_to_int="stochastic_rounding",
clip_to_obs=False,
- get_native_frequencies=False,
moi=None,
):
"""inference infering the expected native signals, noise ratios, Bayesfactors and expected native frequencies
@@ -583,11 +576,6 @@ def inference(
Use it with caution, as it may lead to over-estimation of overall noise.
.. versionadded:: 0.5.0
-
- get_native_frequencies : bool, optional
- whether to get native frequencies, by default False
-
- .. versionadded:: 0.7.0
moi : int, optional (under development)
multiplicity of infection. If assigned, it will allow optimized thresholding, \
@@ -600,33 +588,19 @@ def inference(
native_frequencies, and noise_ratio. \
A feature_assignment will be added in 'sgRNA' or 'tag' or 'CMO' feature type.
"""
+ total_set = UMIDataset(self.raw_count, self.ambient_profile, self.batch_id, device=self.device)
n_features = self.n_features
sample_size = self.raw_count.shape[0]
+ self.native_counts = np.empty([sample_size, n_features])
+ self.bayesfactor = np.empty([sample_size, n_features])
+ self.native_frequencies = np.empty([sample_size, n_features])
+ self.noise_ratio = np.empty([sample_size, 1])
- dt = np.int64 if round_to_int=="stochastic_rounding" else np.float32
- native_counts = sparse.lil_matrix((sample_size, n_features), dtype=dt)
- noise_ratio = sparse.lil_matrix((sample_size, 1), dtype=np.float32)
-
- native_frequencies = sparse.lil_matrix((sample_size, n_features), dtype=np.float32) if get_native_frequencies else None
-
- if self.feature_type.lower() in [
- "sgrna",
- "sgrnas",
- "tag",
- "tags",
- "cmo",
- "cmos",
- "atac",
- ]:
- bayesfactor = sparse.lil_matrix((sample_size, n_features), dtype=np.float32)
- else:
- bayesfactor = None
-
if not batch_size:
batch_size = sample_size
i = 0
- generator_full_data = DataLoader(
- self.dataset, batch_size=batch_size, shuffle=False
+ generator_full_data = torch.utils.data.DataLoader(
+ total_set, batch_size=batch_size, shuffle=False
)
for x_batch_tot, ambient_freq_tot, x_batch_id_onehot_tot in generator_full_data:
@@ -648,28 +622,20 @@ def inference(
round_to_int=round_to_int,
clip_to_obs=clip_to_obs,
)
- native_counts[
+ self.native_counts[
i * batch_size : i * batch_size + minibatch_size, :
] = native_counts_batch
- noise_ratio[
+ self.bayesfactor[
+ i * batch_size : i * batch_size + minibatch_size, :
+ ] = bayesfactor_batch
+ self.native_frequencies[
+ i * batch_size : i * batch_size + minibatch_size, :
+ ] = native_frequencies_batch
+ self.noise_ratio[
i * batch_size : i * batch_size + minibatch_size, :
] = noise_ratio_batch
- if native_frequencies is not None:
- native_frequencies[
- i * batch_size : i * batch_size + minibatch_size, :
- ] = native_frequencies_batch
- if bayesfactor is not None:
- bayesfactor[
- i * batch_size : i * batch_size + minibatch_size, :
- ] = bayesfactor_batch
-
i += 1
- self.native_counts = native_counts.tocsr()
- self.noise_ratio = noise_ratio.tocsr()
- self.bayesfactor = bayesfactor.tocsr() if bayesfactor is not None else None
- self.native_frequencies = native_frequencies.tocsr() if native_frequencies is not None else None
-
if self.feature_type.lower() in [
"sgrna",
"sgrnas",
@@ -710,7 +676,7 @@ def assignment(self, cutoff=3, moi=None):
index=self.cell_id, columns=[self.feature_type, f"n_{self.feature_type}"]
)
bayesfactor_df = pd.DataFrame(
- self.bayesfactor.toarray(), index=self.cell_id, columns=self.feature_names
+ self.bayesfactor, index=self.cell_id, columns=self.feature_names
)
bayesfactor_df[bayesfactor_df < cutoff] = 0 # Apply the cutoff for Bayesfactors
@@ -737,39 +703,39 @@ def assignment(self, cutoff=3, moi=None):
if moi:
raise NotImplementedError
-class UMIDataset(Dataset):
+
+class UMIDataset(torch.utils.data.Dataset):
"""Characterizes dataset for PyTorch"""
- def __init__(self, raw_count, ambient_profile, batch_id, device, cache_capacity=20000):
+ def __init__(self, raw_count, ambient_profile, batch_id, device, list_ids=None):
"""Initialization"""
-
- self.raw_count = torch.from_numpy(raw_count.fillna(0).values).int() if isinstance(raw_count, pd.DataFrame) else raw_count
- self.ambient_profile = torch.from_numpy(ambient_profile).float().to(device)
- self.batch_id = torch.from_numpy(batch_id).to(torch.int64).to(device)
- self.batch_onehot = torch.from_numpy(np.eye(len(np.unique(batch_id)))).to(torch.int64).to(device)
self.device = device
- self.cache_capacity = cache_capacity
+ self.raw_count = torch.from_numpy(raw_count).int().to(device)
+ self.ambient_profile = torch.from_numpy(ambient_profile).float().to(device)
+ self.batch_id = batch_id.to(torch.int64).to(device)
+ self.batch_onehot = self._onehot()
- # Cache data
- self.cache = {}
+ if list_ids:
+ self.list_ids = list_ids
+ else:
+ self.list_ids = list(range(raw_count.shape[0]))
def __len__(self):
"""Denotes the total number of samples"""
- return self.raw_count.shape[0]
+ return len(self.list_ids)
def __getitem__(self, index):
"""Generates one sample of data"""
-
- if index in self.cache:
- return self.cache[index]
- else:
- # Select samples
- sc_count = self.raw_count[index].to(self.device) if isinstance(self.raw_count, torch.Tensor) else torch.from_numpy(self.raw_count[index].X.toarray().flatten()).int().to(self.device)
- sc_ambient = self.ambient_profile[self.batch_id[index], :]
- sc_batch_id_onehot = self.batch_onehot[self.batch_id[index], :]
-
- # Cache samples
- if len(self.cache) <= self.cache_capacity:
- self.cache[index] = (sc_count, sc_ambient, sc_batch_id_onehot)
-
- return sc_count, sc_ambient, sc_batch_id_onehot
+ # Select sample
+ sc_id = self.list_ids[index]
+ sc_count = self.raw_count[sc_id, :]
+ sc_ambient = self.ambient_profile[self.batch_id[sc_id], :]
+ sc_batch_id_onehot = self.batch_onehot[self.batch_id[sc_id], :]
+ return sc_count, sc_ambient, sc_batch_id_onehot
+
+ def _onehot(self):
+ """One-hot encoding"""
+ n_batch = self.batch_id.unique().size()[0]
+ x_onehot = torch.zeros(n_batch, n_batch).to(self.device)
+ x_onehot.scatter_(1, self.batch_id.unique().unsqueeze(1), 1)
+ return x_onehot
\ No newline at end of file
diff --git a/scar/main/_vae.py b/scar/main/_vae.py
index 98dfd93..00368e1 100644
--- a/scar/main/_vae.py
+++ b/scar/main/_vae.py
@@ -149,18 +149,20 @@ def inference(
elif round_to_int.lower() == "stochastic_rounding":
expected_native_counts = (
np.floor(expected_native_counts)
- + (
- np.random.rand(*expected_native_counts.shape)
- < expected_native_counts - np.floor(expected_native_counts)
- ).astype(int)
+ + np.random.binomial(
+ 1,
+ expected_native_counts - np.floor(expected_native_counts),
+ expected_native_counts.shape,
+ )
).astype(int)
expected_amb_counts = (
np.floor(expected_amb_counts)
- + (
- np.random.rand(*expected_amb_counts.shape)
- < expected_amb_counts - np.floor(expected_amb_counts)
- ).astype(int)
+ + np.random.binomial(
+ 1,
+ expected_amb_counts - np.floor(expected_amb_counts),
+ expected_amb_counts.shape,
+ )
).astype(int)
if clip_to_obs:
@@ -170,6 +172,13 @@ def inference(
a_max=input_matrix_np,
)
+ if clip_to_obs:
+ expected_native_counts = np.clip(
+ expected_native_counts,
+ a_min=np.zeros_like(input_matrix_np),
+ a_max=input_matrix_np,
+ )
+
if not adjust:
adjust = 0
elif adjust == "global":
diff --git a/scar/test/test_scar.py b/scar/test/test_scar.py
index 3080d05..502d62d 100755
--- a/scar/test/test_scar.py
+++ b/scar/test/test_scar.py
@@ -22,7 +22,7 @@ def test_scar(self):
feature_type="sgRNAs",
)
- scarObj.train(epochs=40, batch_size=32)
+ scarObj.train(epochs=40, batch_size=64)
scarObj.inference()
@@ -58,7 +58,7 @@ def test_scar_citeseq(self):
feature_type="ADTs",
)
- citeseq_scar.train(epochs=200, batch_size=32, verbose=False)
+ citeseq_scar.train(epochs=200, batch_size=64, verbose=False)
citeseq_scar.inference()
dist = euclidean_distances(