Skip to content

Commit e8cbaa1

Browse files
committed
v0.3.0: Rebuild&Pass tests
1 parent 8d994cd commit e8cbaa1

7 files changed

Lines changed: 36 additions & 25 deletions

File tree

.github/workflows/build.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
strategy:
1515
fail-fast: false
1616
matrix:
17-
python-version: [ 3.11 ]
17+
python-version: [ "3.10", "3.11", "3.12", "3.13" ]
1818

1919
steps:
2020
- name: Checkout repository
@@ -30,8 +30,9 @@ jobs:
3030
sudo apt update
3131
sudo apt install -y libxml2-utils pandoc
3232
curl -sSL https://install.python-poetry.org | python3 -
33-
pip install --upgrade pip
34-
pip install -e ".[docs, dev]"
33+
curl -LsSf https://astral.sh/uv/install.sh | sh
34+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
35+
uv pip install -e ".[docs, dev]" --system
3536
install_pyg_dependencies
3637
3738
- name: Build documentation

.github/workflows/release.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ jobs:
2626
sudo apt update
2727
sudo apt install -y libxml2-utils pandoc
2828
curl -sSL https://install.python-poetry.org | python3 -
29-
pip install --upgrade pip
30-
pip install -e ".[docs, dev]"
29+
curl -LsSf https://astral.sh/uv/install.sh | sh
30+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
31+
uv pip install -e ".[docs, dev]" --system
3132
install_pyg_dependencies
3233
3334
- name: Build documentation

Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ RUN apt-get update \
88
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
99

1010
# Copy DECIPHER package and install
11-
# USER rapids
1211
WORKDIR /app
1312
COPY ./decipher ./decipher
1413
COPY ./README.md ./README.md

decipher/cls.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ def register_data(
9393
self.edge_index = edge_index
9494
np.save(self.work_dir / "edge_index.npy", self.edge_index.numpy())
9595

96+
# Save hyperparameters
97+
OmegaConf.save(CFG, self.work_dir / "hyperparams.yaml")
98+
9699
def fit_sc(self) -> None:
97100
r"""
98101
Fit on single cell data
@@ -133,7 +136,6 @@ def fit_omics(self) -> None:
133136
# save embeddings
134137
np.save(self.work_dir / "center_emb.npy", self.center_emb)
135138
np.save(self.work_dir / "nbr_emb.npy", self.nbr_emb)
136-
OmegaConf.save(CFG, self.work_dir / "hyperparams.yaml")
137139
logger.info(f"Results saved to {self.work_dir}")
138140

139141
def load(self, from_dir: str) -> None:
@@ -170,6 +172,7 @@ def fit_ddp(self, gpus: int = -1) -> None:
170172
max_gpus = torch.cuda.device_count()
171173
assert max_gpus > 1, "DDP requires at least 2 GPUs."
172174
gpus = min(gpus, max_gpus) if gpus > 0 else max_gpus
175+
logger.info(f"Using {gpus} GPUs for DDP training.")
173176

174177
# DDP fit omics
175178
subprocess.run(

decipher/explain/regress/regression.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pandas as pd
77
import ray
88
import torch
9+
from loguru import logger
910
from omegaconf import OmegaConf
1011
from pytorch_lightning import LightningDataModule, LightningModule
1112
from rui_utils.torch.trainer import fit_and_inference
@@ -126,7 +127,11 @@ def calc_metric(self, pred_y, y):
126127
"test_r2_score": float(r2),
127128
"test_mae_score": float(mae),
128129
}
129-
self.log_dict(self.test_metric, prog_bar=True)
130+
try:
131+
self.log_dict(self.test_metric, prog_bar=True)
132+
except Exception as e: # noqa
133+
logger.error(f"Error logging test metrics: {e}")
134+
print(self.test_metric)
130135

131136

132137
def train_regress(
@@ -173,6 +178,8 @@ def train_regress(
173178
config.trainer.model_dir = str(Path(config.work_dir) / save_dir)
174179
regress_model = DeepRegression(config, test_cell_type)
175180
fit_and_inference(regress_model, data, config.trainer)
181+
if not hasattr(regress_model, "test_metric"):
182+
regress_model.on_test_epoch_end()
176183
test_metric = regress_model.test_metric
177184

178185
metric_path = Path(config.work_dir) / save_dir / "test_metric.json"

pyproject.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api"
66
[tool.poetry]
77
name = "cell-decipher"
88
packages = [{include = "decipher"}]
9-
version = "0.2.2"
9+
version = "0.3.0"
1010
description = "Spatial-omics data embedding and analysis"
1111
readme = "README.md"
1212
license = "MIT"
@@ -43,13 +43,14 @@ bs4 = "*"
4343
rui_utils = "*"
4444
harmony-pytorch = "*"
4545

46-
torch = ">=2.0"
46+
torch = ">=2.0, <2.9"
4747
torchvision = "*"
4848
torchaudio = "*"
4949
pytorch-lightning = ">=2.1"
5050
torch_geometric = ">=2.3.0"
5151
tensorboard = "*"
5252
einops = "*"
53+
transformers = "*"
5354

5455
sphinx = {version = "<=6.2.1", optional = true}
5556
sphinx-autodoc-typehints = {version = "*", optional = true}
@@ -106,8 +107,8 @@ source = ["decipher"]
106107
show_missing = true
107108

108109
[tool.poetry.scripts]
109-
decipher_ddp_sc = "decipher.ddp:decipher_ddp_sc"
110-
decipher_ddp_spatial = "decipher.ddp:decipher_ddp_spatial"
110+
decipher_ddp_sc = "decipher.utils:decipher_ddp_sc"
111+
decipher_ddp_spatial = "decipher.utils:decipher_ddp_spatial"
111112
install_pyg_dependencies = "decipher.utils:install_pyg_dep"
112113

113114
[tool.jupytext]

tests/test_explain.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import torch
22
from torch_geometric.data import Batch, Data
33

4+
from decipher import CFG
45
from decipher.explain.gene.gene_selection import train_GAE
56
from decipher.explain.regress.mixin import train_regress
6-
from decipher.utils import GENESELECT_CFG, REGRESS_CFG
77

88

99
def test_GAE_mimic():
10-
GENESELECT_CFG.center_dim = 8
11-
GENESELECT_CFG.expr_dim = 100
12-
GENESELECT_CFG.work_dir = "./results/explain"
13-
GENESELECT_CFG.gae_epochs = 2
14-
GENESELECT_CFG.fit.epochs = 2
10+
CFG.gene_select.center_dim = 8
11+
CFG.gene_select.expr_dim = 100
12+
CFG.gene_select.work_dir = "./results/explain"
13+
CFG.gene_select.gae_epochs = 2
1514

1615
N_CELL1 = 100
1716
graph1 = Data(
@@ -27,19 +26,19 @@ def test_GAE_mimic():
2726
expr=torch.randn(N_CELL2, 100),
2827
)
2928
graph_all = Batch.from_data_list([graph1, graph2])
30-
train_GAE(graph1, GENESELECT_CFG, save_dir="test_GAE")
31-
train_GAE(graph_all, GENESELECT_CFG, save_dir="test_GAE_batched")
29+
train_GAE(graph1, CFG.gene_select, save_dir="test_GAE")
30+
train_GAE(graph_all, CFG.gene_select, save_dir="test_GAE_batched")
3231

3332

3433
def test_regress_mimic():
35-
REGRESS_CFG.center_dim = 8
36-
REGRESS_CFG.nbr_dim = 8
37-
REGRESS_CFG.work_dir = "./results/explain"
38-
REGRESS_CFG.fit.epochs = 2
34+
CFG.regress.center_dim = 8
35+
CFG.regress.nbr_dim = 8
36+
CFG.regress.work_dir = "./results/explain"
37+
CFG.regress.trainer.epochs = 2
3938

4039
x = torch.randn(100, 8)
4140
y = torch.randn(100, 8)
42-
train_regress(x, y, REGRESS_CFG, save_dir="test_regress")
41+
train_regress(x, y, CFG.regress, save_dir="test_regress")
4342

4443

4544
if __name__ == "__main__":

0 commit comments

Comments
 (0)