Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

# elf

**Important:** We have recently switched to using [bioimage-cpp](https://github.com/computational-cell-analytics/bioimage-cpp) as new library to implement computationally expensive functionality that was previously used from affogato, nifty, and vigra.
This enables installing elf via pip, but may lead to some bugs and incompatibilities.
If you encounter some problem let us know in an issue; you can also install `elf < 0.9` to restore the previous version.

This repository implements common functionality for biomedical image analysis:
- **evaluation**: evaluation of partitions via rand index and variation of information
- **io**: common interface for different libraries / formats
Expand All @@ -25,15 +29,17 @@ It is used by several down-stream dependencies:
- [ilastik](https://github.com/ilastik/ilastik)
- [mobie-python](https://github.com/mobie/mobie-utils-python)
- [plantseg](https://github.com/hci-unihd/plant-seg)
- [torch_em](https://github.com/constantinpape/torch-em)
- [micro_sam](https://github.com/computational-cell-analytics/micro-sam)

## Installation

Install the package from source and in development mode via
```
pip install -e .
```
or via conda
Install the package from pip:
```bash
pip install python-elf
```
or from conda:
```bash
conda install -c conda-forge python-elf
```

Expand Down
27 changes: 18 additions & 9 deletions elf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@
- `elf.tracking`: Graph-based tracking algorithms.
- `elf.wrapper`: Wrapper for large microscopy data to enable on-the-fly processing.

**Important:** We have recently switched to using [bioimage-cpp](https://github.com/computational-cell-analytics/bioimage-cpp) as new library to implement computationally expensive functionality that was previously used from affogato, nifty, and vigra.
This enables installing elf via pip, but may lead to some bugs and incompatibilities.
If you encounter some problem let us know in an issue; you can also install `elf < 0.9` to restore the previous version.

# Installation

`elf` is available on conda-forge. You can install it into an existing conda environment via:
```
`elf` is available on conda-forge and on PyPI. You can install it into an existing conda environment with conda via:
```bash
conda install -c conda-forge python-elf
```
or install it via pip as follows:
```bash
pip install python-elf
```

We also provide a environment for a development environment. To set it up:
1. Clone the elf repository:
Expand Down Expand Up @@ -45,15 +53,16 @@

`elf` also provides command line functionality. Currently provided are the command line interfaces:
- `view_container`: Visualize the content of any file supported by `elf.io` with napari.
"""
""" # noqa

import warnings
from .__version__ import __version__
from .__version__ import __version__ # noqa

warnings.warn(
"elf will switch to from affogato, vigra, and nifty to"
"https://github.com/computational-cell-analytics/bioimage-cpp as new backed for custom functionality"
"implemented in C++, e.g. mutex watershed or multicut etc. This may lead to some changes in behavior and"
"interface. If you rely on elf you may want to consider pinning it to a version < 0.9",
FutureWarning, stacklevel=2
"elf has switched from the affogato, vigra, and nifty librares to "
"https://github.com/computational-cell-analytics/bioimage-cpp as new backed for custom functionality "
"implemented in C++, e.g. mutex watershed, multicut etc. This may lead to some changes in behavior and "
"interface. If you run into issues with the new version consider installing a version < 0.9. "
"Please also consider raising an issue on github so that we are aware of issues with the migration.",
UserWarning, stacklevel=2
)
2 changes: 1 addition & 1 deletion elf/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.8.1"
__version__ = "0.9.0"
20 changes: 15 additions & 5 deletions test/io_tests/test_intern_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import unittest

import numpy as np
import requests

try:
from intern import array
Expand All @@ -16,7 +17,10 @@ def test_can_access_dataset(self):
from elf.io.intern_wrapper import InternDataset

# Choosing a dataset at random to make sure we can access shape and dtype
ds = InternDataset("bossdb://witvliet2020/Dataset_1/em")
try:
ds = InternDataset("bossdb://witvliet2020/Dataset_1/em")
except (requests.exceptions.RequestException, OSError) as exc:
raise unittest.SkipTest(f"Could not access bossdb dataset: {exc}")
self.assertEqual(ds.shape, (300, 26000, 22000))
self.assertEqual(ds.dtype, np.uint8)
self.assertEqual(ds.size, 300 * 26000 * 22000)
Expand All @@ -25,8 +29,11 @@ def test_can_access_dataset(self):
def test_can_download_dataset(self):
from elf.io.intern_wrapper import InternDataset

ds = InternDataset("bossdb://witvliet2020/Dataset_1/em")
cutout = ds[210:212, 7000:7064, 7000:7064]
try:
ds = InternDataset("bossdb://witvliet2020/Dataset_1/em")
cutout = ds[210:212, 7000:7064, 7000:7064]
except (requests.exceptions.RequestException, OSError) as exc:
raise unittest.SkipTest(f"Could not access bossdb dataset: {exc}")
self.assertEqual(cutout.shape, (2, 64, 64))
# Pick a few random points to verify. (This is a static dataset so
# this won't fail unless the internet connection is broken.)
Expand All @@ -39,8 +46,11 @@ def test_can_download_dataset(self):
def test_file(self):
from elf.io.intern_wrapper import InternFile, InternDataset

f = InternFile("bossdb://witvliet2020/Dataset_1/em")
ds = f["data"]
try:
f = InternFile("bossdb://witvliet2020/Dataset_1/em")
ds = f["data"]
except (requests.exceptions.RequestException, OSError) as exc:
raise unittest.SkipTest(f"Could not access bossdb dataset: {exc}")
self.assertIsInstance(ds, InternDataset)


Expand Down
7 changes: 6 additions & 1 deletion test/parallel/test_seeded_watershed.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ class TestSeededWatershed(unittest.TestCase):
def test_seeded_watershed(self):
from elf.parallel import seeded_watershed

mask = binary_blobs(256)
# Seed binary_blobs so the test data is deterministic across runs; otherwise the
# blockwise/global discrepancy varies per run and occasionally exceeds the threshold.
mask = binary_blobs(256, rng=0)
block_shape = (64, 64)
halo = (16, 16)

Expand All @@ -29,6 +31,9 @@ def test_seeded_watershed(self):
res = seeded_watershed(hmap, seeds, res, block_shape, halo, mask=mask)
exp = bic.segmentation.watershed(hmap, seeds, mask=mask)

# The blockwise watershed is an approximation of the global one: a few pixels near
# block boundaries may be assigned to a different seed. The tolerance accounts for
# this expected, small discrepancy.
vis, vim = variation_of_information(exp, res)
self.assertLessEqual(vis + vim, 0.01)

Expand Down
6 changes: 5 additions & 1 deletion test/segmentation/test_lifted_multicut.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import unittest
import bioimage_cpp as bic
import numpy as np
import requests


class TestLiftedMulticut(unittest.TestCase):
Expand Down Expand Up @@ -57,7 +58,10 @@ class TestLiftedMulticutRealProblem(unittest.TestCase):
@classmethod
def setUpClass(cls):
from elf.segmentation.utils import load_multicut_problem
graph, costs = load_multicut_problem('A', 'small')
try:
graph, costs = load_multicut_problem('A', 'small')
except (requests.exceptions.RequestException, OSError) as exc:
raise unittest.SkipTest(f"Could not download multicut test problem: {exc}")
cls.graph = graph
cls.costs = costs.astype('float64')

Expand Down
6 changes: 5 additions & 1 deletion test/segmentation/test_multicut.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import unittest
import numpy as np
import requests
import bioimage_cpp as bic
from elf.segmentation.utils import load_multicut_problem

Expand All @@ -26,7 +27,10 @@ class TestMulticut(unittest.TestCase):

@classmethod
def setUpClass(cls):
load_multicut_problem('A', 'small')
try:
load_multicut_problem('A', 'small')
except (requests.exceptions.RequestException, OSError) as exc:
raise unittest.SkipTest(f"Could not download multicut test problem: {exc}")

# https://github.com/constantinpape/graph/blob/master/src/andres/graph/unit-test/multicut/kernighan-lin.cxx
def toy_problem(self):
Expand Down
21 changes: 12 additions & 9 deletions test/transformation/test_ngff.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ class TestNgff(unittest.TestCase):
@classmethod
def setUpClass(cls):
os.makedirs(cls.tmp_folder, exist_ok=True)
for version in cls.versions:
version_folder = os.path.join(cls.tmp_folder, version)
os.makedirs(version_folder, exist_ok=True)
examples = NGFF_EXAMPLES[version]
for name, example_url in examples.items():
url = os.path.join(example_url, ".zattrs")
out_path = os.path.join(version_folder, f"{name}.json")
with requests.get(url) as r, open(out_path, "w") as f:
f.write(r.content.decode("utf8"))
try:
for version in cls.versions:
version_folder = os.path.join(cls.tmp_folder, version)
os.makedirs(version_folder, exist_ok=True)
examples = NGFF_EXAMPLES[version]
for name, example_url in examples.items():
url = os.path.join(example_url, ".zattrs")
out_path = os.path.join(version_folder, f"{name}.json")
with requests.get(url, timeout=30) as r, open(out_path, "w") as f:
f.write(r.content.decode("utf8"))
except requests.exceptions.RequestException as exc:
raise unittest.SkipTest(f"Could not download NGFF test data: {exc}")

@classmethod
def tearDownClass(cls):
Expand Down
Loading