diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..c9019da
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,81 @@
+name: CI
+
+on:
+ push:
+ branches: [main, develop]
+ pull_request:
+ branches: [main]
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.12"
+ cache: "pip"
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install ruff
+
+ - name: Run ruff linter
+ run: ruff check src tests
+
+ - name: Run ruff formatter check
+ run: ruff format --check src tests
+
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.12"
+ cache: "pip"
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -e ".[dev,viz]"
+
+ - name: Run tests with coverage
+ run: |
+ pytest tests/ -v --tb=short --cov=src/samap --cov-report=xml --cov-report=term
+
+ - name: Upload coverage
+ uses: codecov/codecov-action@v4
+ with:
+ files: ./coverage.xml
+ fail_ci_if_error: false
+
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.12"
+ cache: "pip"
+
+ - name: Install build dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install build
+
+ - name: Build package
+ run: python -m build
+
+ - name: Check build artifacts
+ run: |
+ ls -la dist/
+ pip install dist/*.whl
+ python -c "import samap; print(samap.__version__)"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..8fe08d1
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,47 @@
+name: Release to PyPI
+
+on:
+ push:
+ tags:
+ - "v*"
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+
+ - name: Install build dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install build
+
+ - name: Build package
+ run: python -m build
+
+ - name: Upload build artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: dist
+ path: dist/
+
+ publish:
+ needs: build
+ runs-on: ubuntu-latest
+ environment: pypi
+ permissions:
+ id-token: write
+ steps:
+ - name: Download build artifacts
+ uses: actions/download-artifact@v4
+ with:
+ name: dist
+ path: dist/
+
+ - name: Publish to PyPI
+ uses: pypa/gh-action-pypi-publish@release/v1
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5a2a789
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,102 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+*.egg-info/
+*.egg
+
+# PyInstaller
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Jupyter Notebook
+.ipynb_checkpoints/
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# ruff
+.ruff_cache/
+
+# IDE
+.idea/
+.vscode/
+*.swp
+*.swo
+*~
+
+# OS
+.DS_Store
+Thumbs.db
+
+# Project specific
+*.h5
+*.hdf5
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..40862ab
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,27 @@
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v4.5.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: check-yaml
+ - id: check-added-large-files
+ - id: check-merge-conflict
+
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.2.0
+ hooks:
+ - id: ruff
+ args: [--fix]
+ - id: ruff-format
+
+ - repo: https://github.com/pre-commit/mirrors-mypy
+ rev: v1.8.0
+ hooks:
+ - id: mypy
+ additional_dependencies:
+ - numpy
+ - pandas-stubs
+ args:
+ - --ignore-missing-imports
+ exclude: tests/
diff --git a/README.md b/README.md
index ab56983..7855247 100755
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# SAMap -- version 1.0.15
+# SAMap -- version 2.0.2
# Citation
Please cite the following paper if using SAMap: https://elifesciences.org/articles/66747
@@ -9,7 +9,7 @@ Tarashansky, Alexander J., et al. "Mapping single-cell atlases throughout Metazo
### pip
-`pip install samap`
+`pip install sc-samap`
### Manual installation
Download Anacodna from here:
diff --git a/SAMap_vignette.ipynb b/SAMap_vignette.ipynb
index 148e2f0..0f978d6 100644
--- a/SAMap_vignette.ipynb
+++ b/SAMap_vignette.ipynb
@@ -6,9 +6,9 @@
"metadata": {},
"outputs": [],
"source": [
- "from samap.mapping import SAMAP\n",
+ "from samap import SAMAP\n",
"from samap.analysis import (get_mapping_scores, GenePairFinder,\n",
- " sankey_plot, chord_plot, CellTypeTriangles, \n",
+ " sankey_plot, CellTypeTriangles, \n",
" ParalogSubstitutions, FunctionalEnrichment,\n",
" convert_eggnog_to_homologs, GeneTriangles)\n",
"from samalg import SAM\n",
@@ -469,7 +469,20 @@
"cell_type": "code",
"execution_count": 6,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/Users/alect/Desktop/sam-algorithm/src/samalg/sam.py:500: FutureWarning: `__version__` is deprecated, use `importlib.metadata.version('anndata')` instead.\n",
+ " if version.parse(str(anndata.__version__)) >= version.parse(\"0.7rc1\"):\n",
+ "/Users/alect/Desktop/sam-algorithm/src/samalg/sam.py:500: FutureWarning: `__version__` is deprecated, use `importlib.metadata.version('anndata')` instead.\n",
+ " if version.parse(str(anndata.__version__)) >= version.parse(\"0.7rc1\"):\n",
+ "/Users/alect/Desktop/sam-algorithm/src/samalg/sam.py:500: FutureWarning: `__version__` is deprecated, use `importlib.metadata.version('anndata')` instead.\n",
+ " if version.parse(str(anndata.__version__)) >= version.parse(\"0.7rc1\"):\n"
+ ]
+ }
+ ],
"source": [
"sam1=SAM()\n",
"sam1.load_data(fn1)\n",
@@ -487,15 +500,15 @@
"metadata": {},
"outputs": [
{
- "name": "stdout",
+ "name": "stderr",
"output_type": "stream",
"text": [
- "Not updating the manifold...\n",
- "Not updating the manifold...\n",
- "Not updating the manifold...\n",
- "14355 `pl` gene symbols match between the datasets and the BLAST graph.\n",
- "7605 `sc` gene symbols match between the datasets and the BLAST graph.\n",
- "12637 `hy` gene symbols match between the datasets and the BLAST graph.\n"
+ "INFO: Not updating the manifold...\n",
+ "INFO: Not updating the manifold...\n",
+ "INFO: Not updating the manifold...\n",
+ "INFO: 14355 'pl' gene symbols match between the datasets and the BLAST graph.\n",
+ "INFO: 7605 'sc' gene symbols match between the datasets and the BLAST graph.\n",
+ "INFO: 12637 'hy' gene symbols match between the datasets and the BLAST graph.\n"
]
}
],
@@ -529,64 +542,61 @@
"metadata": {},
"outputs": [
{
- "name": "stdout",
+ "name": "stderr",
"output_type": "stream",
"text": [
- "Prepping datasets for translation.\n",
- "Translating feature spaces pairwise.\n",
- "Projecting data into joint latent space. 3.2279748916625977\n",
- "Correcting data with means. 4.532547950744629\n",
- "Expanding neighbourhoods of species pl...\n",
- "Expanding neighbourhoods of species sc...\n",
- "Expanding neighbourhoods of species hy...\n",
- "Indegree coarsening\n",
- "0/1 (0, 3124)\n",
- "Rescaling edge weights by expression correlations.\n",
- "Concatenating SAM objects...\n",
- "Iteration 1 complete.\n",
- "Alignment scores:\n",
+ "INFO: Prepping datasets for translation.\n",
+ "INFO: Translating feature spaces pairwise.\n",
+ "INFO: Projecting data into joint latent space. 1.46s\n",
+ "INFO: Correcting data with means. 1.18s\n",
+ "INFO: Expanding neighbourhoods of species pl...\n",
+ "INFO: Expanding neighbourhoods of species sc...\n",
+ "INFO: Expanding neighbourhoods of species hy...\n",
+ "INFO: Indegree coarsening\n",
+ "INFO: Rescaling edge weights by expression correlations.\n",
+ "INFO: Concatenating SAM objects...\n",
+ "INFO: Iteration 1 complete.\n",
+ "INFO: Alignment scores:\n",
" hy pl sc\n",
- "hy 0.000000 0.435470 0.424640\n",
- "pl 0.476524 0.000000 0.639555\n",
- "sc 0.478394 0.663902 0.000000\n",
- "Calculating gene-gene correlations in the homology graph...\n",
- "Prepping datasets for translation.\n",
- "Translating feature spaces pairwise.\n",
- "Projecting data into joint latent space. 2.551313877105713\n",
- "Correcting data with means. 2.6602261066436768\n",
- "Expanding neighbourhoods of species pl...\n",
- "Expanding neighbourhoods of species sc...\n",
- "Expanding neighbourhoods of species hy...\n",
- "Indegree coarsening\n",
- "0/1 (0, 3124)\n",
- "Rescaling edge weights by expression correlations.\n",
- "Concatenating SAM objects...\n",
- "Iteration 2 complete.\n",
- "Alignment scores:\n",
+ "hy 0.000000 0.391416 0.382622\n",
+ "pl 0.445996 0.000000 0.601834\n",
+ "sc 0.455310 0.639204 0.000000\n",
+ "INFO: Calculating gene-gene correlations in the homology graph...\n",
+ "INFO: Prepping datasets for translation.\n",
+ "INFO: Translating feature spaces pairwise.\n",
+ "INFO: Projecting data into joint latent space. 1.23s\n",
+ "INFO: Correcting data with means. 1.05s\n",
+ "INFO: Expanding neighbourhoods of species pl...\n",
+ "INFO: Expanding neighbourhoods of species sc...\n",
+ "INFO: Expanding neighbourhoods of species hy...\n",
+ "INFO: Indegree coarsening\n",
+ "INFO: Rescaling edge weights by expression correlations.\n",
+ "INFO: Concatenating SAM objects...\n",
+ "INFO: Iteration 2 complete.\n",
+ "INFO: Alignment scores:\n",
" hy pl sc\n",
- "hy 0.000000 0.527345 0.488376\n",
- "pl 0.582561 0.000000 0.705353\n",
- "sc 0.555789 0.703715 0.000000\n",
- "Calculating gene-gene correlations in the homology graph...\n",
- "Prepping datasets for translation.\n",
- "Translating feature spaces pairwise.\n",
- "Projecting data into joint latent space. 2.362617015838623\n",
- "Correcting data with means. 3.0483272075653076\n",
- "Expanding neighbourhoods of species pl...\n",
- "Expanding neighbourhoods of species sc...\n",
- "Expanding neighbourhoods of species hy...\n",
- "Indegree coarsening\n",
- "0/1 (0, 3124)\n",
- "Rescaling edge weights by expression correlations.\n",
- "Concatenating SAM objects...\n",
- "Iteration 3 complete.\n",
- "Alignment scores:\n",
+ "hy 0.000000 0.476882 0.446729\n",
+ "pl 0.548278 0.000000 0.669231\n",
+ "sc 0.533270 0.681846 0.000000\n",
+ "INFO: Calculating gene-gene correlations in the homology graph...\n",
+ "INFO: Prepping datasets for translation.\n",
+ "INFO: Translating feature spaces pairwise.\n",
+ "INFO: Projecting data into joint latent space. 1.27s\n",
+ "INFO: Correcting data with means. 1.10s\n",
+ "INFO: Expanding neighbourhoods of species pl...\n",
+ "INFO: Expanding neighbourhoods of species sc...\n",
+ "INFO: Expanding neighbourhoods of species hy...\n",
+ "INFO: Indegree coarsening\n",
+ "INFO: Rescaling edge weights by expression correlations.\n",
+ "INFO: Concatenating SAM objects...\n",
+ "INFO: Iteration 3 complete.\n",
+ "INFO: Alignment scores:\n",
" hy pl sc\n",
- "hy 0.000000 0.549762 0.519417\n",
- "pl 0.596325 0.000000 0.709699\n",
- "sc 0.570683 0.709405 0.000000\n",
- "Running UMAP on the stitched manifolds.\n",
- "Elapsed time: 1.3108057181040447 minutes.\n"
+ "hy 0.000000 0.495094 0.474622\n",
+ "pl 0.564872 0.000000 0.675047\n",
+ "sc 0.546122 0.685110 0.000000\n",
+ "INFO: Running UMAP on the stitched manifolds.\n",
+ "INFO: Elapsed time: 0.64 minutes.\n"
]
}
],
@@ -786,11 +796,11 @@
" hy_t34367aep 73.5\n",
" hy_t13960aep 70.3\n",
" dtype: float64,\n",
- " 'correlation': sc_Smp_102690 0.228268\n",
- " sc_Smp_179320 0.871954\n",
- " sc_Smp_198380 0.230778\n",
- " hy_t34367aep 0.672766\n",
- " hy_t13960aep 0.599172\n",
+ " 'correlation': sc_Smp_102690 0.225455\n",
+ " sc_Smp_179320 0.872515\n",
+ " sc_Smp_198380 0.236296\n",
+ " hy_t34367aep 0.655665\n",
+ " hy_t13960aep 0.601378\n",
" dtype: float64}"
]
},
@@ -811,7 +821,7 @@
{
"data": {
"text/plain": [
- "{'blast': 130.0, 'correlation': 0.8719536941498626}"
+ "{'blast': np.float64(130.0), 'correlation': np.float64(0.8725150463770156)}"
]
},
"execution_count": 13,
@@ -875,15 +885,15 @@
" \n",
" \n",
" \n",
@@ -915,123 +925,123 @@
" \n",
- " pl_Muscle: 13 \n",
" sc_Muscle \n",
+ " pl_Muscle: 13 \n",
" pl_Muscle: 14 \n",
- " pl_Neoblast: 0 \n",
" sc_Neoblast \n",
+ " pl_Neoblast: 22 \n",
" ... \n",
- " sc_Intestine \n",
" pl_Protonephridia: 26 \n",
- " pl_Protonephridia: 29 \n",
+ " hy_i_nb4 \n",
+ " hy_ecEp_bd \n",
" sc_Gland \n",
" sc_Neural_KK7 \n",
"