Skip to content

Commit

Permalink
Improve workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasteuwen committed Aug 27, 2024
1 parent 1b25250 commit 4f5ed1c
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 14 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ jobs:
python -m pip install ninja meson meson-python>=0.15.0 numpy==1.26.4 Cython>=0.29 spin pybind11
python -m pip install tifffile>=2024.7.2 pyvips>=2.2.3 tqdm>=2.66.4 pillow>=10.3.0 openslide-python>=1.3.1
python -m pip install opencv-python-headless>=4.9.0.80 shapely>=2.0.4 pybind11>=2.8.0 pydantic coverage pytest psutil darwin-py pytest-mock tox
meson setup builddir
meson compile -C builddir
meson install -C buildir
# meson setup builddir
# meson compile -C builddir
# meson install -C buildir
python -m pip install .
- name: Run tox
run: |
Expand Down
3 changes: 2 additions & 1 deletion .spin/cmds.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import site
import subprocess
import webbrowser
from pathlib import Path
import site

import click
from spin.cmds import meson

Expand Down
67 changes: 64 additions & 3 deletions dlup/annotations_experimental.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,20 @@ def __init__(
sorting: Optional[AnnotationSorting | str] = None,
**kwargs: Any,
) -> None:
"""
Parameters
----------
layers : GeometryCollection
Geometry collection containing the polygons, boxes and points
tags: Optional[tuple[SlideTag, ...]]
A tuple of image-level tags such as staining quality
sorting: AnnotationSorting
Sorting method, see `AnnotationSorting`. This value is typically passed to the constructor
because of operations layer on (such as `__add__`). Typically the classmethod already sorts the data
**kwargs: Any
Additional keyword arguments. In this class they are used for additional metadata or offset functions.
Currently only HaloXML requires offsets. See `.from_halo_xml` for an example
"""
self._layers = layers
self._tags = tags
self._sorting = sorting
Expand All @@ -265,14 +279,19 @@ def tags(self) -> Optional[tuple[SlideTag, ...]]:

@property
def num_polygons(self) -> int:
return len(self._layers.polygons)
return len(self.layers.polygons)

@property
def num_points(self) -> int:
return len(self._layers.points)
return len(self.layers.points)

@property
def num_boxes(self) -> int:
return len(self.layers.boxes)

@property
def metadata(self) -> Optional[dict[str, list[str] | str | int | float | bool]]:
"""Additional metadata for the annotations"""
return self._metadata

@property
Expand Down Expand Up @@ -303,7 +322,8 @@ def offset_function(self, func: Any) -> None:

@property
def layers(self) -> GeometryCollection:
"""Get the layers of the annotations.
"""
Get the layers of the annotations.
This is a GeometryCollection object which contains all the polygons and points
"""
return self._layers
Expand Down Expand Up @@ -1078,6 +1098,47 @@ def read_region(
scaling: float,
size: tuple[GenericNumber, GenericNumber],
) -> AnnotationRegion:
"""Reads the region of the annotations. Function signature is the same as `dlup.SlideImage`
so they can be used in conjunction.
The process is as follows:
1. All the annotations which overlap with the requested region of interest are filtered
2. The polygons in the GeometryContainer in `.layers` are cropped.
The boxes and points are only filtered, so it's possible the boxes have negative (x, y) values
3. The annotation is rescaled and shifted to the origin to match the local patch coordinate system.
The final returned data is a `dlup.geometry.AnnotationRegion`.
Parameters
----------
location: tuple[GenericNumber, GenericNumber]
Top-left coordinates of the region in the requested scaling
size : tuple[GenericNumber, GenericNumber]
Output size of the region
scaling : float
Scaling to apply compared to the base level
Returns
-------
AnnotationRegion
Examples
--------
1. To read geojson annotations and convert them into masks:
>>> from pathlib import Path
>>> from dlup import SlideImage
>>> import numpy as np
>>> wsi = SlideImage.from_file_path(Path("path/to/image.svs"))
>>> wsi = wsi.get_scaled_view(scaling=0.5)
>>> wsi = wsi.read_region(location=(0,0), size=wsi.size)
>>> annotations = SlideAnnotations.from_geojson("path/to/geojson.json")
>>> region = annotations.read_region((0,0), 0.01, wsi.size)
>>> mask = region.to_mask()
>>> color_mask = annotations.color_lut[mask]
>>> polygons = region.polygons # This is a list of `dlup.geometry.Polygon` objects
"""
region = self._layers.read_region(coordinates, scaling, size)
return region

Expand Down
2 changes: 1 addition & 1 deletion dlup/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ background = py.extension_module('_background',
subdir : 'dlup',
link_args : link_args,
c_args : cpp_args + ['-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION'],
dependencies : [py_dep]) # Add Python dependency
dependencies : [py_dep]) # Add Python dependency
2 changes: 1 addition & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ geometry = py.extension_module('_geometry',
include_directories : [third_party_dir, incdir_pybind11],
cpp_args : cpp_args,
link_args : link_args,
dependencies : base_deps + [boost_dep, opencv_dep])
dependencies : base_deps + [boost_dep, opencv_dep])
1 change: 0 additions & 1 deletion third_party/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,3 @@ incdir_pybind11 = incdir_pybind11
base_deps = base_deps
boost_dep = boost_dep
opencv_dep = opencv_dep

8 changes: 4 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
[tox]
envlist = py310, py311
envlist = py311
isolated_build = True

[testenv]
env =
GITHUB_ACTIONS=1
deps =
meson
meson-python>=0.15.0
Expand All @@ -11,11 +13,9 @@ deps =
spin
pybind11
build
pyhaloxml
extras = dev,darwin
commands =
sh -c 'meson setup builddir'
sh -c 'meson compile -C builddir'
sh -c 'cp builddir/*.so dlup'
pytest
allowlist_externals =
sh
Expand Down

0 comments on commit 4f5ed1c

Please sign in to comment.