alhena 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- alhena-0.1.0/.github/workflows/docs.yml +63 -0
- alhena-0.1.0/.github/workflows/release.yml +95 -0
- alhena-0.1.0/.github/workflows/tests.yml +143 -0
- alhena-0.1.0/.gitignore +17 -0
- alhena-0.1.0/CITATION.cff +48 -0
- alhena-0.1.0/CONTRIBUTING.md +41 -0
- alhena-0.1.0/LICENSE +29 -0
- alhena-0.1.0/PKG-INFO +200 -0
- alhena-0.1.0/README.md +149 -0
- alhena-0.1.0/ci/constraints-min-extras.txt +6 -0
- alhena-0.1.0/ci/constraints-min.txt +16 -0
- alhena-0.1.0/docs/api/annotate.md +26 -0
- alhena-0.1.0/docs/api/cells.md +50 -0
- alhena-0.1.0/docs/api/celltyper.md +38 -0
- alhena-0.1.0/docs/api/constants.md +78 -0
- alhena-0.1.0/docs/api/encoder.md +60 -0
- alhena-0.1.0/docs/api/errors.md +38 -0
- alhena-0.1.0/docs/api/index.md +38 -0
- alhena-0.1.0/docs/api/io.md +192 -0
- alhena-0.1.0/docs/api/metrics.md +32 -0
- alhena-0.1.0/docs/api/preprocess.md +42 -0
- alhena-0.1.0/docs/api/refbuild.md +47 -0
- alhena-0.1.0/docs/api/reference.md +32 -0
- alhena-0.1.0/docs/api/spatial.md +57 -0
- alhena-0.1.0/docs/api/types.md +59 -0
- alhena-0.1.0/docs/api/viz.md +45 -0
- alhena-0.1.0/docs/assets/alhena_banner.svg +4 -0
- alhena-0.1.0/docs/assets/alhena_lockup.svg +1 -0
- alhena-0.1.0/docs/assets/alhena_lockup_1600.png +0 -0
- alhena-0.1.0/docs/assets/alhena_lockup_reverse.svg +1 -0
- alhena-0.1.0/docs/assets/alhena_mark_512.png +0 -0
- alhena-0.1.0/docs/assets/figures/multiscale_overview.webp +0 -0
- alhena-0.1.0/docs/assets/figures/multiscale_preview.webp +0 -0
- alhena-0.1.0/docs/assets/figures/tutorial4_cell_space.webp +0 -0
- alhena-0.1.0/docs/assets/figures/tutorial4_cell_states.webp +0 -0
- alhena-0.1.0/docs/assets/figures/tutorial4_co_occurrence.webp +0 -0
- alhena-0.1.0/docs/assets/figures/tutorial4_cross_scale.webp +0 -0
- alhena-0.1.0/docs/assets/figures/tutorial4_physical_space.webp +0 -0
- alhena-0.1.0/docs/assets/figures/tutorial4_spatialdata.webp +0 -0
- alhena-0.1.0/docs/assets/figures/tutorial4_tile_gallery.webp +0 -0
- alhena-0.1.0/docs/assets/figures/tutorial4_tile_states.webp +0 -0
- alhena-0.1.0/docs/assets/figures/usecase_field.webp +0 -0
- alhena-0.1.0/docs/assets/figures/usecase_hero.webp +0 -0
- alhena-0.1.0/docs/assets/figures/usecase_neighborhood.webp +0 -0
- alhena-0.1.0/docs/assets/figures/usecase_tissue_contexts.webp +0 -0
- alhena-0.1.0/docs/assets/figures/usecase_triptych.webp +0 -0
- alhena-0.1.0/docs/cite.md +58 -0
- alhena-0.1.0/docs/cli.md +815 -0
- alhena-0.1.0/docs/concepts/cell-pooling.md +222 -0
- alhena-0.1.0/docs/concepts/cell-typing.md +376 -0
- alhena-0.1.0/docs/concepts/geometry.md +521 -0
- alhena-0.1.0/docs/concepts/how-it-works.md +214 -0
- alhena-0.1.0/docs/concepts/references.md +620 -0
- alhena-0.1.0/docs/faq.md +615 -0
- alhena-0.1.0/docs/index.md +119 -0
- alhena-0.1.0/docs/inputs/coordinates.md +300 -0
- alhena-0.1.0/docs/inputs/images.md +432 -0
- alhena-0.1.0/docs/inputs/index.md +113 -0
- alhena-0.1.0/docs/inputs/nuclei.md +400 -0
- alhena-0.1.0/docs/inputs/references.md +145 -0
- alhena-0.1.0/docs/installation.md +220 -0
- alhena-0.1.0/docs/outputs/cell-annotations.md +180 -0
- alhena-0.1.0/docs/outputs/cell-embeddings.md +188 -0
- alhena-0.1.0/docs/outputs/downstream-analysis.md +356 -0
- alhena-0.1.0/docs/outputs/index.md +99 -0
- alhena-0.1.0/docs/outputs/persistence.md +216 -0
- alhena-0.1.0/docs/outputs/tile-embeddings.md +218 -0
- alhena-0.1.0/docs/start/choose-your-task.md +168 -0
- alhena-0.1.0/docs/start/demo.ipynb +622 -0
- alhena-0.1.0/docs/start/getting-started.md +83 -0
- alhena-0.1.0/docs/stylesheets/extra.css +61 -0
- alhena-0.1.0/docs/tutorials/01_tile_embeddings.ipynb +573 -0
- alhena-0.1.0/docs/tutorials/02_cell_embeddings.ipynb +406 -0
- alhena-0.1.0/docs/tutorials/03_cell_annotation.ipynb +720 -0
- alhena-0.1.0/docs/tutorials/04_multiscale_analysis.ipynb +1135 -0
- alhena-0.1.0/docs/tutorials/05_custom_reference.ipynb +612 -0
- alhena-0.1.0/docs/tutorials/06_annotation_evaluation.ipynb +375 -0
- alhena-0.1.0/docs/tutorials/index.md +43 -0
- alhena-0.1.0/docs/use-case/crc_multiscale.ipynb +2001 -0
- alhena-0.1.0/mkdocs.yml +151 -0
- alhena-0.1.0/pyproject.toml +95 -0
- alhena-0.1.0/scripts/alhena_atlas_embed.py +1848 -0
- alhena-0.1.0/scripts/requirements-atlas.txt +11 -0
- alhena-0.1.0/src/alhena/__init__.py +148 -0
- alhena-0.1.0/src/alhena/_bundle.py +121 -0
- alhena-0.1.0/src/alhena/_commands.py +89 -0
- alhena-0.1.0/src/alhena/_constants.py +247 -0
- alhena-0.1.0/src/alhena/_coverage.py +77 -0
- alhena-0.1.0/src/alhena/_defaults.py +35 -0
- alhena-0.1.0/src/alhena/_errors.py +75 -0
- alhena-0.1.0/src/alhena/_frames.py +90 -0
- alhena-0.1.0/src/alhena/_geometry.py +483 -0
- alhena-0.1.0/src/alhena/_hub.py +109 -0
- alhena-0.1.0/src/alhena/_layout.py +532 -0
- alhena-0.1.0/src/alhena/_plotting.py +241 -0
- alhena-0.1.0/src/alhena/_progress.py +166 -0
- alhena-0.1.0/src/alhena/_rings.py +65 -0
- alhena-0.1.0/src/alhena/_shards.py +155 -0
- alhena-0.1.0/src/alhena/_truth.py +126 -0
- alhena-0.1.0/src/alhena/_version.py +3 -0
- alhena-0.1.0/src/alhena/_wording.py +120 -0
- alhena-0.1.0/src/alhena/annotate.py +666 -0
- alhena-0.1.0/src/alhena/api.py +512 -0
- alhena-0.1.0/src/alhena/cells/__init__.py +35 -0
- alhena-0.1.0/src/alhena/cells/_canvas.py +298 -0
- alhena-0.1.0/src/alhena/cells/_centroids.py +261 -0
- alhena-0.1.0/src/alhena/cells/_checks.py +415 -0
- alhena-0.1.0/src/alhena/cells/_drawing.py +253 -0
- alhena-0.1.0/src/alhena/cells/_inputs.py +465 -0
- alhena-0.1.0/src/alhena/cells/_labels.py +255 -0
- alhena-0.1.0/src/alhena/cells/_path.py +413 -0
- alhena-0.1.0/src/alhena/cells/_polygons.py +400 -0
- alhena-0.1.0/src/alhena/cells/_pooling.py +368 -0
- alhena-0.1.0/src/alhena/cells/_table.py +321 -0
- alhena-0.1.0/src/alhena/cli/__init__.py +32 -0
- alhena-0.1.0/src/alhena/cli/_annotate.py +310 -0
- alhena-0.1.0/src/alhena/cli/_demo.py +27 -0
- alhena-0.1.0/src/alhena/cli/_download.py +66 -0
- alhena-0.1.0/src/alhena/cli/_encode.py +209 -0
- alhena-0.1.0/src/alhena/cli/_info.py +74 -0
- alhena-0.1.0/src/alhena/cli/_options.py +239 -0
- alhena-0.1.0/src/alhena/cli/_parser.py +330 -0
- alhena-0.1.0/src/alhena/cli/_reading.py +339 -0
- alhena-0.1.0/src/alhena/cli/_reference.py +139 -0
- alhena-0.1.0/src/alhena/cli/_shared.py +281 -0
- alhena-0.1.0/src/alhena/demo/__init__.py +87 -0
- alhena-0.1.0/src/alhena/demo/_fetch.py +340 -0
- alhena-0.1.0/src/alhena/demo/_main.py +164 -0
- alhena-0.1.0/src/alhena/demo/_pannuke.py +355 -0
- alhena-0.1.0/src/alhena/demo/_report.py +604 -0
- alhena-0.1.0/src/alhena/demo/_run.py +190 -0
- alhena-0.1.0/src/alhena/encoder/__init__.py +34 -0
- alhena-0.1.0/src/alhena/encoder/_adapters.py +234 -0
- alhena-0.1.0/src/alhena/encoder/_inference.py +597 -0
- alhena-0.1.0/src/alhena/encoder/_loading.py +368 -0
- alhena-0.1.0/src/alhena/hub.py +512 -0
- alhena-0.1.0/src/alhena/io/__init__.py +159 -0
- alhena-0.1.0/src/alhena/io/_carry.py +158 -0
- alhena-0.1.0/src/alhena/io/_centroids.py +421 -0
- alhena-0.1.0/src/alhena/io/_files.py +307 -0
- alhena-0.1.0/src/alhena/io/_formats.py +134 -0
- alhena-0.1.0/src/alhena/io/_grid.py +327 -0
- alhena-0.1.0/src/alhena/io/_hdf5.py +328 -0
- alhena-0.1.0/src/alhena/io/_images.py +272 -0
- alhena-0.1.0/src/alhena/io/_labels.py +523 -0
- alhena-0.1.0/src/alhena/io/_nuclei.py +104 -0
- alhena-0.1.0/src/alhena/io/_polygons.py +645 -0
- alhena-0.1.0/src/alhena/io/_resolution.py +278 -0
- alhena-0.1.0/src/alhena/io/_saved.py +447 -0
- alhena-0.1.0/src/alhena/io/_slides.py +467 -0
- alhena-0.1.0/src/alhena/io/_sources.py +442 -0
- alhena-0.1.0/src/alhena/io/_tiles.py +222 -0
- alhena-0.1.0/src/alhena/metrics.py +424 -0
- alhena-0.1.0/src/alhena/preprocess.py +149 -0
- alhena-0.1.0/src/alhena/py.typed +0 -0
- alhena-0.1.0/src/alhena/refbuild.py +737 -0
- alhena-0.1.0/src/alhena/reference.py +648 -0
- alhena-0.1.0/src/alhena/spatial/__init__.py +35 -0
- alhena-0.1.0/src/alhena/spatial/_cells.py +221 -0
- alhena-0.1.0/src/alhena/spatial/_elements.py +233 -0
- alhena-0.1.0/src/alhena/spatial/_nuclei.py +207 -0
- alhena-0.1.0/src/alhena/spatial/_sopa.py +200 -0
- alhena-0.1.0/src/alhena/spatial/_tiles.py +368 -0
- alhena-0.1.0/src/alhena/spatial/_windows.py +180 -0
- alhena-0.1.0/src/alhena/types.py +874 -0
- alhena-0.1.0/src/alhena/viz.py +780 -0
- alhena-0.1.0/tests/conftest.py +15 -0
- alhena-0.1.0/tests/support.py +227 -0
- alhena-0.1.0/tests/test_annotate.py +261 -0
- alhena-0.1.0/tests/test_api.py +127 -0
- alhena-0.1.0/tests/test_atlas_script.py +180 -0
- alhena-0.1.0/tests/test_cells.py +381 -0
- alhena-0.1.0/tests/test_cli.py +383 -0
- alhena-0.1.0/tests/test_demo.py +236 -0
- alhena-0.1.0/tests/test_encode.py +381 -0
- alhena-0.1.0/tests/test_encoder.py +315 -0
- alhena-0.1.0/tests/test_hub.py +264 -0
- alhena-0.1.0/tests/test_io.py +796 -0
- alhena-0.1.0/tests/test_metrics.py +164 -0
- alhena-0.1.0/tests/test_reference.py +231 -0
- alhena-0.1.0/tests/test_results.py +319 -0
- alhena-0.1.0/tests/test_spatial.py +329 -0
- alhena-0.1.0/tests/test_viz.py +257 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: docs
|
|
2
|
+
|
|
3
|
+
# A push to main builds and deploys the site; a pull request only builds it.
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
# Read only; the deploy job alone gets the two Pages permissions.
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
# A running deployment in `pages` is never canceled; a pull request builds in a group of its own.
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ${{ github.event_name == 'push' && 'pages' || format('docs-{0}', github.ref) }}
|
|
16
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v7
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-python@v7
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
|
|
29
|
+
# CPU builds of torch and torchvision: the build never uses CUDA.
|
|
30
|
+
# mkdocstrings parses `src` and the notebooks are not executed: nothing here runs alhena.
|
|
31
|
+
- name: Install
|
|
32
|
+
run: |
|
|
33
|
+
python -m pip install --upgrade pip
|
|
34
|
+
python -m pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
|
|
35
|
+
python -m pip install -e ".[docs]"
|
|
36
|
+
|
|
37
|
+
# --strict fails on any warning: a moved page, a nav entry with no file, an unresolved path.
|
|
38
|
+
- name: Build
|
|
39
|
+
run: mkdocs build --strict
|
|
40
|
+
|
|
41
|
+
- if: github.event_name == 'push'
|
|
42
|
+
uses: actions/upload-pages-artifact@v5
|
|
43
|
+
with:
|
|
44
|
+
path: site
|
|
45
|
+
|
|
46
|
+
# A job of its own, so a failed build never enters the `github-pages` environment.
|
|
47
|
+
deploy:
|
|
48
|
+
if: github.event_name == 'push'
|
|
49
|
+
needs: build
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
permissions:
|
|
52
|
+
pages: write
|
|
53
|
+
id-token: write
|
|
54
|
+
environment:
|
|
55
|
+
name: github-pages
|
|
56
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
57
|
+
|
|
58
|
+
steps:
|
|
59
|
+
# Fails here, naming the cause, where the Pages source is not set to GitHub Actions.
|
|
60
|
+
- uses: actions/configure-pages@v6
|
|
61
|
+
|
|
62
|
+
- id: deployment
|
|
63
|
+
uses: actions/deploy-pages@v5
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# A push to main builds the package; Run workflow also uploads it to TestPyPI, a release to PyPI.
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
release:
|
|
9
|
+
types: [published]
|
|
10
|
+
|
|
11
|
+
# Read only; the two upload jobs alone get id-token: write, for Trusted Publishing.
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
build:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
# The build needs no git access after the checkout, so the token is not kept.
|
|
21
|
+
- uses: actions/checkout@v7
|
|
22
|
+
with:
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-python@v7
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
|
|
29
|
+
- name: Install
|
|
30
|
+
run: python -m pip install build twine
|
|
31
|
+
|
|
32
|
+
# The source archive and the wheel, in dist/.
|
|
33
|
+
- name: Build
|
|
34
|
+
run: python -m build
|
|
35
|
+
|
|
36
|
+
# Checks that the README renders on PyPI; --strict fails on warnings too.
|
|
37
|
+
- name: Check the package
|
|
38
|
+
run: twine check --strict dist/*
|
|
39
|
+
|
|
40
|
+
# A release uploads only the version its tag names: v plus __version__.
|
|
41
|
+
- name: Check the tag
|
|
42
|
+
if: github.event_name == 'release'
|
|
43
|
+
env:
|
|
44
|
+
TAG: ${{ github.event.release.tag_name }}
|
|
45
|
+
run: |
|
|
46
|
+
version=$(python -c "import runpy; print(runpy.run_path('src/alhena/_version.py')['__version__'])")
|
|
47
|
+
if [ "$TAG" != "v$version" ]; then
|
|
48
|
+
echo "::error::Tag $TAG does not match version $version in src/alhena/_version.py: tag the release v$version, or change the version first."
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
- uses: actions/upload-artifact@v7
|
|
53
|
+
with:
|
|
54
|
+
name: python-package-distributions
|
|
55
|
+
path: dist/
|
|
56
|
+
|
|
57
|
+
# Run workflow, by hand: a trial upload to TestPyPI.
|
|
58
|
+
testpypi:
|
|
59
|
+
if: github.event_name == 'workflow_dispatch'
|
|
60
|
+
needs: build
|
|
61
|
+
runs-on: ubuntu-latest
|
|
62
|
+
permissions:
|
|
63
|
+
id-token: write
|
|
64
|
+
environment:
|
|
65
|
+
name: testpypi
|
|
66
|
+
url: https://test.pypi.org/p/alhena
|
|
67
|
+
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/download-artifact@v8
|
|
70
|
+
with:
|
|
71
|
+
name: python-package-distributions
|
|
72
|
+
path: dist/
|
|
73
|
+
|
|
74
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
75
|
+
with:
|
|
76
|
+
repository-url: https://test.pypi.org/legacy/
|
|
77
|
+
|
|
78
|
+
# A published release; waits for approval where the `pypi` environment requires a reviewer.
|
|
79
|
+
pypi:
|
|
80
|
+
if: github.event_name == 'release'
|
|
81
|
+
needs: build
|
|
82
|
+
runs-on: ubuntu-latest
|
|
83
|
+
permissions:
|
|
84
|
+
id-token: write
|
|
85
|
+
environment:
|
|
86
|
+
name: pypi
|
|
87
|
+
url: https://pypi.org/p/alhena
|
|
88
|
+
|
|
89
|
+
steps:
|
|
90
|
+
- uses: actions/download-artifact@v8
|
|
91
|
+
with:
|
|
92
|
+
name: python-package-distributions
|
|
93
|
+
path: dist/
|
|
94
|
+
|
|
95
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
name: tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
# An older run on the same branch is canceled when a new one starts.
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
strategy:
|
|
20
|
+
fail-fast: false
|
|
21
|
+
matrix:
|
|
22
|
+
python-version: ["3.12", "3.13", "3.14"]
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v7
|
|
26
|
+
|
|
27
|
+
- uses: actions/setup-python@v7
|
|
28
|
+
with:
|
|
29
|
+
python-version: ${{ matrix.python-version }}
|
|
30
|
+
|
|
31
|
+
# CPU builds of torch and torchvision: the tests never use CUDA.
|
|
32
|
+
# viz for test_viz.py; the spatial and wsi tests run in the extras and floors jobs.
|
|
33
|
+
- name: Install
|
|
34
|
+
run: |
|
|
35
|
+
python -m pip install --upgrade pip
|
|
36
|
+
python -m pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
|
|
37
|
+
python -m pip install -e ".[dev,viz]"
|
|
38
|
+
|
|
39
|
+
# ruff keeps its format within a minor release: the floors' 0.16.0 and 0.16 here agree.
|
|
40
|
+
- name: Lint
|
|
41
|
+
run: |
|
|
42
|
+
ruff check src tests scripts
|
|
43
|
+
ruff format --check src tests scripts
|
|
44
|
+
|
|
45
|
+
# -rs lists each skipped test with its reason, so a lost dependency shows as a shorter run.
|
|
46
|
+
- name: Test
|
|
47
|
+
run: pytest -rs
|
|
48
|
+
|
|
49
|
+
# Every extra at its latest release, as a new install resolves it.
|
|
50
|
+
extras:
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v7
|
|
55
|
+
|
|
56
|
+
- uses: actions/setup-python@v7
|
|
57
|
+
with:
|
|
58
|
+
python-version: "3.12"
|
|
59
|
+
|
|
60
|
+
- name: Install the extras
|
|
61
|
+
run: |
|
|
62
|
+
python -m pip install --upgrade pip
|
|
63
|
+
python -m pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
|
|
64
|
+
python -m pip install -e ".[dev,viz,spatial,wsi]"
|
|
65
|
+
|
|
66
|
+
- name: Test
|
|
67
|
+
run: pytest -rs
|
|
68
|
+
|
|
69
|
+
# Every dependency at the lowest release pyproject.toml allows, pinned in ci/constraints-min.txt.
|
|
70
|
+
floors:
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@v7
|
|
75
|
+
|
|
76
|
+
- uses: actions/setup-python@v7
|
|
77
|
+
with:
|
|
78
|
+
python-version: "3.12"
|
|
79
|
+
|
|
80
|
+
# torchvision 0.17.0 is the release paired with torch 2.2.0, from the CPU index.
|
|
81
|
+
- name: Install the floors
|
|
82
|
+
run: |
|
|
83
|
+
python -m pip install --upgrade pip
|
|
84
|
+
python -m pip install torch==2.2.0 torchvision==0.17.0 --index-url https://download.pytorch.org/whl/cpu
|
|
85
|
+
python -m pip install -c ci/constraints-min.txt -e ".[dev,viz]"
|
|
86
|
+
|
|
87
|
+
- name: Lint
|
|
88
|
+
run: |
|
|
89
|
+
ruff check src tests scripts
|
|
90
|
+
ruff format --check src tests scripts
|
|
91
|
+
|
|
92
|
+
- name: Test
|
|
93
|
+
run: pytest -rs
|
|
94
|
+
|
|
95
|
+
# Each extra at its floor, the core resolved freely: the spatial stack needs newer core releases.
|
|
96
|
+
floors-spatial:
|
|
97
|
+
runs-on: ubuntu-latest
|
|
98
|
+
|
|
99
|
+
steps:
|
|
100
|
+
- uses: actions/checkout@v7
|
|
101
|
+
|
|
102
|
+
- uses: actions/setup-python@v7
|
|
103
|
+
with:
|
|
104
|
+
python-version: "3.12"
|
|
105
|
+
|
|
106
|
+
- name: Install the spatial extra at its floors
|
|
107
|
+
run: |
|
|
108
|
+
python -m pip install --upgrade pip
|
|
109
|
+
python -m pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
|
|
110
|
+
python -m pip install -c ci/constraints-min-extras.txt -e ".[dev,viz,spatial]"
|
|
111
|
+
|
|
112
|
+
- name: Lint
|
|
113
|
+
run: |
|
|
114
|
+
ruff check src tests scripts
|
|
115
|
+
ruff format --check src tests scripts
|
|
116
|
+
|
|
117
|
+
- name: Test
|
|
118
|
+
run: pytest -rs
|
|
119
|
+
|
|
120
|
+
# A job of its own: tiffslide 2.5.1 needs zarr 2, and spatialdata 0.8.0 needs zarr 3.
|
|
121
|
+
floors-wsi:
|
|
122
|
+
runs-on: ubuntu-latest
|
|
123
|
+
|
|
124
|
+
steps:
|
|
125
|
+
- uses: actions/checkout@v7
|
|
126
|
+
|
|
127
|
+
- uses: actions/setup-python@v7
|
|
128
|
+
with:
|
|
129
|
+
python-version: "3.12"
|
|
130
|
+
|
|
131
|
+
- name: Install the wsi extra at its floor
|
|
132
|
+
run: |
|
|
133
|
+
python -m pip install --upgrade pip
|
|
134
|
+
python -m pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
|
|
135
|
+
python -m pip install -c ci/constraints-min-extras.txt -e ".[dev,viz,wsi]"
|
|
136
|
+
|
|
137
|
+
- name: Lint
|
|
138
|
+
run: |
|
|
139
|
+
ruff check src tests scripts
|
|
140
|
+
ruff format --check src tests scripts
|
|
141
|
+
|
|
142
|
+
- name: Test
|
|
143
|
+
run: pytest -rs
|
alhena-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
.pytest_cache/
|
|
4
|
+
.ruff_cache/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
# the environment of scripts/alhena_atlas_embed.py
|
|
11
|
+
alhena_atlas/
|
|
12
|
+
.ipynb_checkpoints/
|
|
13
|
+
.DS_Store
|
|
14
|
+
|
|
15
|
+
# documentation build
|
|
16
|
+
site/
|
|
17
|
+
.cache/
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: If you use this software, please cite it using the metadata in this file.
|
|
3
|
+
type: software
|
|
4
|
+
title: ALHENA
|
|
5
|
+
abstract: "ALHENA, an H&E encoder distilled from transcriptomic foundation models for multi-scale slide analysis."
|
|
6
|
+
version: 0.1.0
|
|
7
|
+
license: BSD-3-Clause
|
|
8
|
+
repository-code: https://github.com/prism-oncology/ALHENA
|
|
9
|
+
keywords:
|
|
10
|
+
- histopathology
|
|
11
|
+
- spatial-transcriptomics
|
|
12
|
+
- cell-typing
|
|
13
|
+
- foundation-model
|
|
14
|
+
authors:
|
|
15
|
+
- family-names: Giraud-Sauveur
|
|
16
|
+
given-names: Félicie
|
|
17
|
+
email: felicie.giraudsauveur@gmail.com
|
|
18
|
+
- family-names: Blampey
|
|
19
|
+
given-names: Quentin
|
|
20
|
+
- family-names: Marza
|
|
21
|
+
given-names: Pierre
|
|
22
|
+
- family-names: Benkirane
|
|
23
|
+
given-names: Hakim
|
|
24
|
+
- family-names: Vakalopoulou
|
|
25
|
+
given-names: Maria
|
|
26
|
+
- family-names: Cournède
|
|
27
|
+
given-names: Paul-Henry
|
|
28
|
+
- family-names: Christodoulidis
|
|
29
|
+
given-names: Stergios
|
|
30
|
+
preferred-citation:
|
|
31
|
+
type: unpublished
|
|
32
|
+
title: "ALHENA, an H&E encoder distilled from transcriptomic foundation models for multi-scale slide analysis"
|
|
33
|
+
notes: Manuscript under review.
|
|
34
|
+
authors:
|
|
35
|
+
- family-names: Giraud-Sauveur
|
|
36
|
+
given-names: Félicie
|
|
37
|
+
- family-names: Blampey
|
|
38
|
+
given-names: Quentin
|
|
39
|
+
- family-names: Marza
|
|
40
|
+
given-names: Pierre
|
|
41
|
+
- family-names: Benkirane
|
|
42
|
+
given-names: Hakim
|
|
43
|
+
- family-names: Vakalopoulou
|
|
44
|
+
given-names: Maria
|
|
45
|
+
- family-names: Cournède
|
|
46
|
+
given-names: Paul-Henry
|
|
47
|
+
- family-names: Christodoulidis
|
|
48
|
+
given-names: Stergios
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Contributing to ALHENA
|
|
2
|
+
|
|
3
|
+
Bug reports, questions and suggestions are welcome in the
|
|
4
|
+
[issues](https://github.com/prism-oncology/ALHENA/issues). Include the command or code you ran, the
|
|
5
|
+
message it printed in full, and what `alhena info` reports.
|
|
6
|
+
|
|
7
|
+
## Development install
|
|
8
|
+
|
|
9
|
+
Clone the repository and install it in editable mode, with the development tools:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
git clone https://github.com/prism-oncology/ALHENA.git
|
|
13
|
+
cd ALHENA
|
|
14
|
+
pip install -e ".[dev]"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Add the `viz`, `wsi` and `spatial` extras to run the tests that need them.
|
|
18
|
+
|
|
19
|
+
## Tests and style
|
|
20
|
+
|
|
21
|
+
The tests use synthetic data only, so they need no model weights and no network:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pytest
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The code is linted and formatted with ruff, as the continuous integration checks it:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
ruff check src tests scripts
|
|
31
|
+
ruff format --check src tests scripts
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Documentation
|
|
35
|
+
|
|
36
|
+
The documentation is built with MkDocs. Install the docs extra, then serve the site locally:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install -e ".[docs]"
|
|
40
|
+
mkdocs serve
|
|
41
|
+
```
|
alhena-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Félicie Giraud-Sauveur
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
alhena-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: alhena
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ALHENA, an H&E encoder distilled from transcriptomic foundation models for multi-scale slide analysis.
|
|
5
|
+
Project-URL: Homepage, https://github.com/prism-oncology/ALHENA
|
|
6
|
+
Project-URL: Documentation, https://prism-oncology.github.io/ALHENA/
|
|
7
|
+
Project-URL: Source, https://github.com/prism-oncology/ALHENA
|
|
8
|
+
Project-URL: Issues, https://github.com/prism-oncology/ALHENA/issues
|
|
9
|
+
Project-URL: Weights, https://huggingface.co/prism-oncology/ALHENA
|
|
10
|
+
Project-URL: References, https://huggingface.co/prism-oncology/ALHENA-references
|
|
11
|
+
Author-email: Félicie Giraud-Sauveur <felicie.giraudsauveur@gmail.com>
|
|
12
|
+
License-Expression: BSD-3-Clause
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: cell-typing,foundation-model,histopathology,spatial-transcriptomics
|
|
15
|
+
Classifier: Development Status :: 4 - Beta
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
24
|
+
Requires-Python: >=3.12
|
|
25
|
+
Requires-Dist: anndata>=0.12.7
|
|
26
|
+
Requires-Dist: h5py>=3.10
|
|
27
|
+
Requires-Dist: huggingface-hub>=0.34
|
|
28
|
+
Requires-Dist: numpy>=1.26
|
|
29
|
+
Requires-Dist: opencv-python-headless>=4.8
|
|
30
|
+
Requires-Dist: pandas>=2.1.1
|
|
31
|
+
Requires-Dist: pyarrow>=14
|
|
32
|
+
Requires-Dist: safetensors>=0.4
|
|
33
|
+
Requires-Dist: timm<2,>=1.0
|
|
34
|
+
Requires-Dist: torch>=2.2
|
|
35
|
+
Requires-Dist: tqdm>=4.65
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: ruff<0.17,>=0.16; extra == 'dev'
|
|
39
|
+
Provides-Extra: docs
|
|
40
|
+
Requires-Dist: mkdocs-jupyter>=0.25; extra == 'docs'
|
|
41
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
42
|
+
Requires-Dist: mkdocstrings[python]>=0.26; extra == 'docs'
|
|
43
|
+
Provides-Extra: spatial
|
|
44
|
+
Requires-Dist: sopa>=2.2; extra == 'spatial'
|
|
45
|
+
Requires-Dist: spatialdata>=0.8; extra == 'spatial'
|
|
46
|
+
Provides-Extra: viz
|
|
47
|
+
Requires-Dist: matplotlib>=3.8; extra == 'viz'
|
|
48
|
+
Provides-Extra: wsi
|
|
49
|
+
Requires-Dist: tiffslide>=2.5.1; extra == 'wsi'
|
|
50
|
+
Description-Content-Type: text/markdown
|
|
51
|
+
|
|
52
|
+
<p align="center">
|
|
53
|
+
<img src="https://raw.githubusercontent.com/prism-oncology/ALHENA/main/docs/assets/alhena_banner.svg" alt="ALHENA" width="100%" height="168">
|
|
54
|
+
</p>
|
|
55
|
+
|
|
56
|
+
<p align="center">
|
|
57
|
+
<b>ALHENA, an H&E encoder distilled from transcriptomic foundation models for multi-scale slide analysis.</b>
|
|
58
|
+
</p>
|
|
59
|
+
|
|
60
|
+
<p align="center">
|
|
61
|
+
<a href="https://prism-oncology.github.io/ALHENA/"><b>Documentation</b></a> |
|
|
62
|
+
<a href="https://github.com/prism-oncology/ALHENA-paper"><b>Paper code</b></a> |
|
|
63
|
+
<a href="https://huggingface.co/prism-oncology/ALHENA"><b>Weights on Hugging Face</b></a> |
|
|
64
|
+
<a href="https://huggingface.co/prism-oncology/ALHENA-references"><b>References on Hugging Face</b></a>
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
<p align="center">
|
|
68
|
+
<a href="https://pypi.org/project/alhena/"><img alt="PyPI" src="https://img.shields.io/pypi/v/alhena.svg"></a>
|
|
69
|
+
<a href="https://github.com/prism-oncology/ALHENA/actions/workflows/tests.yml"><img alt="Tests" src="https://github.com/prism-oncology/ALHENA/actions/workflows/tests.yml/badge.svg"></a>
|
|
70
|
+
<a href="https://github.com/prism-oncology/ALHENA/actions/workflows/docs.yml"><img alt="Docs" src="https://github.com/prism-oncology/ALHENA/actions/workflows/docs.yml/badge.svg"></a>
|
|
71
|
+
<img alt="License: BSD-3-Clause" src="https://img.shields.io/badge/license-BSD--3--Clause-blue.svg">
|
|
72
|
+
<img alt="Python 3.12+" src="https://img.shields.io/badge/python-3.12%2B-blue.svg">
|
|
73
|
+
</p>
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
ALHENA reads an H&E section and returns two things: **embeddings**, per tile and per cell, and
|
|
78
|
+
**cell types** on an unlabeled section. No spatial transcriptomics is needed at inference, and
|
|
79
|
+
nothing is fitted at deployment.
|
|
80
|
+
|
|
81
|
+
Cell types come from retrieval against a labeled single-cell reference, so a different reference
|
|
82
|
+
gives a different taxonomy. ALHENA provides prebuilt references for fifteen human tissues, built
|
|
83
|
+
from fourteen public single-cell atlases, or you can build a custom reference.
|
|
84
|
+
|
|
85
|
+
When the inputs share a spatial frame, the embeddings and the cell types stay aligned with the
|
|
86
|
+
slide and can be analyzed together across scales.
|
|
87
|
+
|
|
88
|
+
ALHENA is gamma Geminorum, from the Arabic *al-han'ah*, a brand mark placed on something to make it
|
|
89
|
+
readable. To the eye, it appears as a single star, though it is in fact a binary system. The light
|
|
90
|
+
we see comes from a bright A-type subgiant. Its companion has never been imaged and reveals itself
|
|
91
|
+
only through the faint wobble it leaves in the motion of the visible star. The H&E section is that
|
|
92
|
+
visible star, inexpensive, familiar, and collected everywhere. The spatial transcriptome is the
|
|
93
|
+
unseen companion, physically present, shaping what we observe, yet never directly accessible at
|
|
94
|
+
inference.
|
|
95
|
+
|
|
96
|
+
## Install
|
|
97
|
+
|
|
98
|
+
ALHENA needs Python 3.12 or later, and runs with or without a GPU.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
pip install alhena
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Optional extras add plotting (`viz`), whole-slide reading (`wsi`) and SpatialData support
|
|
105
|
+
(`spatial`): `pip install "alhena[viz,wsi,spatial]"`.
|
|
106
|
+
|
|
107
|
+
The UNI2-h model weights are distributed separately by their authors and are not included with
|
|
108
|
+
ALHENA. Their repository is gated: request access at
|
|
109
|
+
[MahmoodLab/UNI2-h](https://huggingface.co/MahmoodLab/UNI2-h) and accept the license. Then log
|
|
110
|
+
in and download the weights, 2.7 GB, into the Hugging Face cache, where ALHENA finds them:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
hf auth login
|
|
114
|
+
hf download MahmoodLab/UNI2-h pytorch_model.bin
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For weights stored elsewhere, set `ALHENA_BACKBONE` to the file. ALHENA adds its own low-rank
|
|
118
|
+
adapters and projection heads on top of the UNI2-h weights, and downloads them from Hugging Face
|
|
119
|
+
on first use, with the prebuilt reference of each tissue it annotates.
|
|
120
|
+
|
|
121
|
+
## See it work
|
|
122
|
+
|
|
123
|
+
The demo needs no data of your own. It reads a few annotated breast H&E fields from the public
|
|
124
|
+
PanNuke dataset, annotates their nuclei with the prebuilt breast reference, and compares the
|
|
125
|
+
predicted cell types with the PanNuke labels. It needs the UNI2-h model weights.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
alhena demo Breast
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Use it on your own data
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import alhena
|
|
135
|
+
|
|
136
|
+
source = alhena.io.read_slide("slide.svs") # an H&E slide, read tile by tile
|
|
137
|
+
nuclei = alhena.io.read_polygons("nuclei.geojson", tiles=source) # nucleus outlines
|
|
138
|
+
|
|
139
|
+
encoder = alhena.load_encoder()
|
|
140
|
+
tiles = encoder.encode_tiles(source) # one embedding per tile
|
|
141
|
+
tiles.write_h5ad("tiles.h5ad") # one row per tile, ready to analyze
|
|
142
|
+
|
|
143
|
+
cells = encoder.encode_cells(source, nuclei=nuclei) # one pass, each tile once
|
|
144
|
+
cells.write_h5ad("cells.h5ad")
|
|
145
|
+
|
|
146
|
+
typer = alhena.load_celltyper(tissue="Breast") # loads the reference alone
|
|
147
|
+
result = typer.annotate(cells) # retrieval, no encoder
|
|
148
|
+
result.to_frame()
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`read_slide` needs the `wsi` extra and reads the resolution the slide declares. `source` can also
|
|
152
|
+
be an array of H&E tiles, `(n_tiles, height, width, 3)` uint8 RGB; `mpp=` then declares the
|
|
153
|
+
resolution it is already at. The nuclei come from a segmenter of your choice: ALHENA does not
|
|
154
|
+
segment. The documentation shows how to
|
|
155
|
+
[segment a slide with sopa and StarDist](https://prism-oncology.github.io/ALHENA/inputs/nuclei/#segment-a-slide-with-sopa-and-stardist).
|
|
156
|
+
`read_polygons` expects the outlines in the slide's full-resolution pixels. Outlines written in
|
|
157
|
+
microns need `units="um"`, and outlines segmented on another image need `transform=`. See
|
|
158
|
+
[Coordinates](https://prism-oncology.github.io/ALHENA/inputs/coordinates/).
|
|
159
|
+
With SpatialData, `alhena.spatial` reads the image and the nucleus outlines from the object.
|
|
160
|
+
|
|
161
|
+
Cells are encoded once and can be annotated again, against another reference or on another
|
|
162
|
+
annotation axis, without rerunning the image encoder: `alhena.io.read_cells("cells.h5ad")` reads
|
|
163
|
+
them back with the provenance that pairs them with a reference.
|
|
164
|
+
`typer.annotate(source, nuclei=nuclei)` runs both steps in one call and keeps the cells on
|
|
165
|
+
`result.cells`.
|
|
166
|
+
|
|
167
|
+
## Documentation
|
|
168
|
+
|
|
169
|
+
**[prism-oncology.github.io/ALHENA](https://prism-oncology.github.io/ALHENA/)**
|
|
170
|
+
|
|
171
|
+
Start with [Choose your task](https://prism-oncology.github.io/ALHENA/start/choose-your-task/):
|
|
172
|
+
tile embeddings, cell embeddings, cell-type annotation, or multi-scale slide analysis.
|
|
173
|
+
[Inputs](https://prism-oncology.github.io/ALHENA/inputs/) says how to provide your images and
|
|
174
|
+
nuclei, whatever form they take.
|
|
175
|
+
|
|
176
|
+
Six [tutorials](https://prism-oncology.github.io/ALHENA/tutorials/) cover these tasks, custom
|
|
177
|
+
references, and annotation evaluation. The [use case example](https://prism-oncology.github.io/ALHENA/use-case/crc_multiscale/) applies
|
|
178
|
+
ALHENA to two public colorectal cancer cohorts, from tissue contexts to patient-level analyses.
|
|
179
|
+
|
|
180
|
+
## Contributing
|
|
181
|
+
|
|
182
|
+
Report a problem or ask a question in the [issues](https://github.com/prism-oncology/ALHENA/issues);
|
|
183
|
+
[CONTRIBUTING.md](https://github.com/prism-oncology/ALHENA/blob/main/CONTRIBUTING.md) explains how to
|
|
184
|
+
install ALHENA for development and run its tests.
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
The ALHENA software is released under the BSD 3-Clause License. The ALHENA model weights,
|
|
189
|
+
comprising the LoRA adapters and the projection heads used at inference, are released under the
|
|
190
|
+
Creative Commons Attribution-NonCommercial 4.0 International License (CC BY-NC 4.0).
|
|
191
|
+
|
|
192
|
+
The precomputed single-cell reference representations are released under the CC BY-NC 4.0
|
|
193
|
+
license. They remain subject to the terms of their source atlases, and those derived from DISCO
|
|
194
|
+
are provided for academic research only, in accordance with the DISCO terms of use.
|
|
195
|
+
|
|
196
|
+
## Citation
|
|
197
|
+
|
|
198
|
+
If you use ALHENA, please cite it as described on the
|
|
199
|
+
[Cite page](https://prism-oncology.github.io/ALHENA/cite/) of the documentation. Please also cite
|
|
200
|
+
the models and datasets ALHENA builds on, listed on the same page.
|