Skip to content

Commit 337040e

Browse files
authored
Support readers for newer image formats (#2)
- Support other image formats, e.g. coming from the SFE package - Realize spatial coordinates as either numpy or sparse arrays - Migrate Github actions to the new versions in biocsetup
1 parent 0048cf9 commit 337040e

4 files changed

Lines changed: 93 additions & 23 deletions

File tree

.github/workflows/run-tests.yml

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,73 @@
1-
name: Run tests
1+
name: Test the library
22

33
on:
44
push:
5-
branches: [master]
5+
branches:
6+
- master # for legacy repos
7+
- main
68
pull_request:
7-
branches: [master]
9+
branches:
10+
- master # for legacy repos
11+
- main
12+
workflow_dispatch: # Allow manually triggering the workflow
13+
schedule:
14+
# Run roughly every 15 days at 00:00 UTC
15+
# (useful to check if updates on dependencies break the package)
16+
- cron: "0 0 1,16 * *"
17+
18+
permissions:
19+
contents: read
20+
21+
concurrency:
22+
group: >-
23+
${{ github.workflow }}-${{ github.ref_type }}-
24+
${{ github.event.pull_request.number || github.sha }}
25+
cancel-in-progress: true
826

927
jobs:
10-
build:
11-
runs-on: ubuntu-latest
28+
test:
1229
strategy:
1330
matrix:
14-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
15-
16-
name: Python ${{ matrix.python-version }}
31+
python: ["3.9", "3.10", "3.11", "3.12", "3.13"]
32+
platform:
33+
- ubuntu-latest
34+
# - macos-latest
35+
# - windows-latest
36+
runs-on: ${{ matrix.platform }}
37+
name: Python ${{ matrix.python }}, ${{ matrix.platform }}
1738
steps:
1839
- uses: actions/checkout@v4
1940

20-
- name: Setup Python
21-
uses: actions/setup-python@v5
41+
- uses: actions/setup-python@v5
42+
id: setup-python
2243
with:
23-
python-version: ${{ matrix.python-version }}
24-
cache: "pip"
44+
python-version: ${{ matrix.python }}
2545

2646
- name: Install dependencies
2747
run: |
2848
python -m pip install --upgrade pip
29-
pip install tox
49+
pip install tox coverage
3050
31-
- name: Test with tox
32-
run: |
51+
- name: Run tests
52+
run: >-
53+
pipx run --python '${{ steps.setup-python.outputs.python-path }}'
3354
tox
55+
-- -rFEx --durations 10 --color yes --cov --cov-branch --cov-report=xml # pytest args
56+
57+
- name: Check for codecov token availability
58+
id: codecov-check
59+
shell: bash
60+
run: |
61+
if [ ${{ secrets.CODECOV_TOKEN }} != '' ]; then
62+
echo "codecov=true" >> $GITHUB_OUTPUT;
63+
else
64+
echo "codecov=false" >> $GITHUB_OUTPUT;
65+
fi
66+
67+
- name: Upload coverage reports to Codecov with GitHub Action
68+
uses: codecov/codecov-action@v5
69+
if: ${{ steps.codecov-check.outputs.codecov == 'true' }}
70+
env:
71+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
72+
slug: ${{ github.repository }}
73+
flags: ${{ matrix.platform }} - py${{ matrix.python }}

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Changelog
22

3-
## Version 0.1
3+
## Version 0.1.0 - 0.1.1
44

55
- Initial version of the readers and writers for `SpatialExperiment`.
6+
- Support other image formats, e.g. coming from the SFE package
7+
- Migrate Github actions to the new versions in biocsetup

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ version_scheme = "no-guess-dev"
1212
line-length = 120
1313
src = ["src"]
1414
exclude = ["tests"]
15-
extend-ignore = ["F821"]
15+
lint.extend-ignore = ["F821"]
1616

17-
[tool.ruff.pydocstyle]
17+
[tool.ruff.lint.pydocstyle]
1818
convention = "google"
1919

2020
[tool.ruff.format]
2121
docstring-code-format = true
2222
docstring-code-line-length = 20
2323

24-
[tool.ruff.per-file-ignores]
24+
[tool.ruff.lint.per-file-ignores]
2525
"__init__.py" = ["E402", "F401"]

src/dolomite_spatial/read_spatial_experiment.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,38 @@
1-
import json
21
import os
32

43
import dolomite_base as dl
54
import dolomite_sce as dlsce
65
import h5py
76
from biocframe import BiocFrame
7+
from delayedarray import is_sparse, to_dense_array, to_scipy_sparse_matrix
88
from dolomite_base.read_object import read_object_registry
99
from spatialexperiment import SpatialExperiment, construct_spatial_image_class
1010

1111
read_object_registry["spatial_experiment"] = "dolomite_spatial.read_spatial_experiment"
1212

1313

14+
def realize_array(x):
15+
"""Realize a `ReloadedArray` into a dense array or sparse matrix.
16+
17+
Args:
18+
x:
19+
`ReloadedArray` object.
20+
21+
Returns:
22+
23+
Realized array or matrix.
24+
"""
25+
from dolomite_matrix import ReloadedArray
26+
27+
if isinstance(x, ReloadedArray):
28+
if is_sparse(x):
29+
x = to_scipy_sparse_matrix(x, "csc")
30+
else:
31+
x = to_dense_array(x)
32+
33+
return x
34+
35+
1436
def read_spatial_experiment(path: str, metadata: dict, **kwargs) -> SpatialExperiment:
1537
"""Load a
1638
:py:class:`~spatialexperiment.SpatialExperiment.SpatialExperiment`
@@ -50,7 +72,7 @@ def read_spatial_experiment(path: str, metadata: dict, **kwargs) -> SpatialExper
5072
_sp_coords_path = os.path.join(path, "coordinates")
5173
if os.path.exists(_sp_coords_path):
5274
_coords = dl.alt_read_object(_sp_coords_path, **kwargs)
53-
spe = spe.set_spatial_coordinates(_coords)
75+
spe = spe.set_spatial_coordinates(realize_array(_coords))
5476
else:
5577
raise FileNotFoundError(f"cannot find spatial coordinates at {path}.")
5678

@@ -77,8 +99,14 @@ def read_spatial_experiment(path: str, metadata: dict, **kwargs) -> SpatialExper
7799
image_data = []
78100
if len(image_samples) > 0:
79101
for i, _ in enumerate(image_samples):
80-
# TODO: write reader for SpatialImage class
81-
image_data.append(construct_spatial_image_class(os.path.join(_img_path, f"{i}.{str(image_formats[i]).lower()}")))
102+
if str(image_formats[i]).lower() == "other":
103+
image_data.append(dl.alt_read_object(os.path.join(_img_path, str(i)), **kwargs))
104+
else:
105+
image_data.append(
106+
construct_spatial_image_class(
107+
os.path.join(_img_path, f"{i}.{str(image_formats[i]).lower()}"), is_url=False
108+
)
109+
)
82110

83111
_image_frame = BiocFrame(
84112
{

0 commit comments

Comments
 (0)