-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
176c370
commit 6f0ab3d
Showing
12 changed files
with
2,139 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
name: Pytest testing | ||
|
||
on: [push] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: [3.10] | ||
|
||
steps: | ||
- uses: actions/checkout | ||
with: | ||
fetch-depth: 2 # Shallow clone last 2 commits | ||
|
||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
|
||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
python -m pip install pytest | ||
python -m pip install . | ||
- name: Run Pytest | ||
run: python -m pytest . | ||
|
||
- name: Run Pytest with Marker | ||
run: pytest -m wsi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
CLAM | ||
WSI | ||
==== | ||
This is a fork of the repository from [Mahmood lab's CLAM repository](https://github.com/mahmoodlab/CLAM). | ||
It is made available under the GPLv3 License and is available for non-commercial academic purposes. | ||
|
@@ -8,7 +8,7 @@ It is made available under the GPLv3 License and is available for non-commercial | |
|
||
The purpose of the fork is to compartimentalize the features related with processing of whole-slide images (WSI) from the CLAM model. | ||
|
||
The package has been renamed to `wsi_core` as that was the name of the module related with whole slide image processing. | ||
The package has been renamed to `wsi`. | ||
|
||
|
||
## Installation | ||
|
@@ -17,8 +17,9 @@ While the repository is private, make sure you [exchange SSH keys of the machine | |
|
||
Then simply install with `pip`: | ||
```bash | ||
git clone [email protected]:rendeirolab/CLAM.git | ||
cd CLAM | ||
# pip install git+ssh://[email protected]:rendeirolab/wsi.git | ||
git clone [email protected]:rendeirolab/wsi.git | ||
cd wsi | ||
pip install . | ||
``` | ||
|
||
|
@@ -29,12 +30,34 @@ Note that the package uses setuptols-scm for version control and therefore the i | |
This package is meant for both interactive use and for use in a pipeline at scale. | ||
By default actions do not return anything, but instead save the results to disk in files relative to the slide file. | ||
|
||
|
||
```python | ||
from wsi import WholeSlideImage | ||
from wsi.utils import Path | ||
|
||
# Get example slide image | ||
slide_file = Path("GTEX-12ZZW-2726.svs") | ||
if not slide_file.exists(): | ||
import requests | ||
url = f"https://brd.nci.nih.gov/brd/imagedownload/{slide_file.stem}" | ||
with open(slide_file, "wb") as handle: | ||
req = requests.get(url) | ||
handle.write(req.content) | ||
|
||
# Instantiate slide object | ||
slide = WholeSlideImage(slide_file) | ||
|
||
# Instantiation can be done with custom attributes | ||
slide = WholeSlideImage(slide_file, attributes=dict(donor="GTEX-12ZZW")) | ||
|
||
|
||
|
||
All major functions have sensible defaults but allow for customization. | ||
Please check the docstring of each function for more information. | ||
|
||
```python | ||
from wsi_core import WholeSlideImage | ||
from wsi_core.utils import Path | ||
from wsi import WholeSlideImage | ||
from wsi.utils import Path | ||
|
||
# Get example slide image | ||
slide_file = Path("GTEX-12ZZW-2726.svs") | ||
|
@@ -48,7 +71,7 @@ if not slide_file.exists(): | |
# Instantiate slide object | ||
slide = WholeSlideImage(slide_file) | ||
|
||
# Instantiate slide object | ||
# Instantiation can be done with custom attributes | ||
slide = WholeSlideImage(slide_file, attributes=dict(donor="GTEX-12ZZW")) | ||
|
||
# Segment tissue (segmentation mask is stored as polygons in slide.contours_tissue) | ||
|
@@ -75,15 +98,28 @@ for img in images: | |
slide.save_tile_images(output_dir=slide_file.parent / (slide_file.stem + "_tiles")) | ||
|
||
# Use in a torch dataloader | ||
loader = slide.as_data_loader() | ||
loader = slide.as_data_loader(with_coords=True) | ||
|
||
# Extract features | ||
# Extract features "manually" | ||
import torch | ||
from tqdm import tqdm | ||
model = torch.hub.load("pytorch/vision", "resnet50", pretrained=True) | ||
for count, (batch, coords) in tqdm(enumerate(loader), total=len(loader)): | ||
model = torch.hub.load("pytorch/vision", "resnet18", weights="DEFAULT") | ||
feats = list() | ||
coords = list() | ||
for count, (batch, yx) in tqdm(enumerate(loader), total=len(loader)): | ||
with torch.no_grad(): | ||
features = model(batch).numpy() | ||
f = model(batch).numpy() | ||
feats.append(f) | ||
coords.append(yx) | ||
|
||
feats = np.concatenate(feats, axis=0) | ||
coords = np.concatenate(coords, axis=0) | ||
|
||
# Extract features "automatically" | ||
feats, coords = slide.inference('resnet18') | ||
|
||
# Additional parameters can also be specified | ||
feats, coords = slide.inference('resnet18', device='cuda', data_loader_kws=dict(batch_size=512)) | ||
``` | ||
|
||
## Reference | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# PIP, using PEP621 | ||
[project] | ||
name = "wsi_core" | ||
name = "wsi" | ||
authors = [ | ||
{name = "Andre Rendeiro", email = "[email protected]"}, | ||
] | ||
|
@@ -11,8 +11,9 @@ keywords = [ | |
] | ||
classifiers = [ | ||
"Programming Language :: Python :: 3 :: Only", | ||
"Programming Language :: Python :: 3.7", | ||
"Programming Language :: Python :: 3.8", | ||
"Programming Language :: Python :: 3.10", | ||
"Programming Language :: Python :: 3.11", | ||
"Programming Language :: Python :: 3.12", | ||
"Development Status :: 3 - Alpha", | ||
"Typing :: Typed", | ||
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", | ||
|
@@ -51,9 +52,9 @@ doc = [ | |
] | ||
|
||
[project.urls] | ||
homepage = "https://github.com/rendeirolab/CLAM" | ||
documentation = "https://github.com/rendeirolab/CLAM/blob/main/README.md" | ||
repository = "https://github.com/rendeirolab/CLAM" | ||
homepage = "https://github.com/rendeirolab/wsi" | ||
documentation = "https://github.com/rendeirolab/wsi/blob/main/README.md" | ||
repository = "https://github.com/rendeirolab/wsi" | ||
|
||
[build-system] | ||
# requires = ["poetry>=0.12", "setuptools>=45", "wheel", "poetry-dynamic-versioning"] | ||
|
@@ -62,7 +63,7 @@ requires = ["setuptools>=45", "wheel", "setuptools_scm[toml]>=6.0"] | |
build-backend = "setuptools.build_meta" | ||
|
||
[tool.setuptools_scm] | ||
write_to = "wsi_core/_version.py" | ||
write_to = "wsi/_version.py" | ||
write_to_template = 'version = __version__ = "{version}"' | ||
|
||
[tool.black] | ||
|
@@ -104,7 +105,7 @@ module = [ | |
'matplotlib.*', | ||
'networkx.*', | ||
# | ||
'wsi_core.*' | ||
'wsi.*' | ||
] | ||
ignore_missing_imports = true | ||
|
||
|
@@ -117,5 +118,5 @@ testpaths = [ | |
] | ||
markers = [ | ||
'slow', # 'marks tests as slow (deselect with "-m 'not slow'")', | ||
'serial' | ||
] | ||
"wsi" | ||
] |
Oops, something went wrong.