Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update tools provided #15

Merged
merged 7 commits into from
Jul 18, 2023
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
47 changes: 42 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,58 @@ The BrainGlobe project is only possible due to grant funding and the generous su

---

## BrainGlobe tools

This package provides all BrainGlobe tools in one place, requested [through a single command](#installation).

You can read more about the individual tools on the [documentation website](https://brainglobe.info/documentation/index.html).
Currently included packages, and whether they come with the `pip` and `conda-forge` installs are listed below:
| Package | `pip` | `conda` | `from brainglobe import` | Documentation |
| :------------------: | :------: | :------: | :----------------------: | :-----------------------------------------------------------------------: |
| BrainGlobe Atlas API | ☑ | ☑ | `bg_atlasapi` | [Site](https://brainglobe.info/documentation/bg-atlasapi/index.html) |
| `bg-space` | ☑ | ☑ | `bg-space` | [Site](https://brainglobe.info/documentation/bg-space/index.html) |
| `brainreg` | ☑ | ☑ | `brainreg` | [Site](https://brainglobe.info/documentation/brainreg/index.html) |
| `brainreg-segment` | ☑ | ☑ | `brainreg_segment` | [Site](https://brainglobe.info/documentation/brainreg-segment/index.html) |
| `brainrender` | | | | [Site](https://brainglobe.info/documentation/brainrender/index.html) |
| `cellfinder` | ☑ | Pending | `cellfinder_core` | [Site](https://brainglobe.info/documentation/cellfinder/index.html) |
| `morphapi` | ☑ | Pending | `morphapi` | [Site](https://brainglobe.info/documentation/morphapi/index.html) |

---

## Installation

We recommend users install into a fresh virtual environment using `pip`; since this will resolve all complex dependencies (like `tensorflow`) automatically, across all operating systems and (compatible) Python versions.

### **Recommended**: via `pip`
The `brainglobe` package can be installed from [PyPI](https://pypi.org/project/brainglobe/) into a Python environment by running
```sh
pip install brainglobe
```
This will fetch and install all `brainglobe` packages and tools into your current environment.
Alternatively, you can download the source from [PyPI here](https://pypi.org/project/brainglobe/#files).

### **Alternatives**: via `conda`
We are currently in the process of making BrainGlobe's tools available from `conda-forge` as an alternative to `PyPI`.
However certain tools are currently not available on `conda-forge`, specifically:
- `brainrender` (in progress)
- `morphapi` (in progress)
- `cellfinder` ([see below](#cellfinder-and-conda-forge))

If you want to install the additional packages `morphapi` and `cellfinder`, you can specify them as optional dependencies:
In your desired virtual environment, run
```sh
pip install brainglobe[morphapi] # Include morphapi
pip install brainglobe[cellfinder] # Include cellfinder
pip install brainglobe[morphapi,cellfinder] # Include both morphapi and cellfinder
conda install -c conda-forge brainglobe
```
to install the compatible BrainGlobe tools.

Alternatively, you can download the source from [PyPI here](https://pypi.org/project/brainglobe/#files).
#### **`cellfinder` and `conda-forge`**

Choosing to install via `conda` will provide the (source code for the) `cellfinder` tool.
However due to an ongoing issue with `tensorflow`'s availability on `conda-forge`, the install _will not_ provide `tensorflow` itself.
This is because `tensorflow` versions newer than `1.14.0` are not provided via `conda` channels, and `cellfinder-core` (one of the brainglobe tools) requires a version between `2.5.0` and `2.11.1`.
See [this issue on GitHub for more details](https://github.com/conda-forge/cellfinder-core-feedstock/issues/13).
Users that want to run `cellfinder` will need to manually install a compatible version of `tensorflow` into their environment, before running the `conda install` command above.

---

## Contributing

Expand Down
23 changes: 14 additions & 9 deletions brainglobe/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from importlib.metadata import PackageNotFoundError, version

from ._tensorflow_handle import _CELLFINDER_FUNCTIONAL as _CELLFINDER_INSTALLED

try:
__version__ = version("brainglobe")
except PackageNotFoundError:
Expand All @@ -11,19 +13,22 @@
import bg_space
import brainreg
import brainreg_segment
import cellfinder_core

# Determine if optional dependencies were installed,
# and expose if necessary.
# Expose tools that may not be present
# if a conda install was performed

# morphapi
_MORPHAPI_INSTALLED = True
try:
import morphapi
except ImportError:
_MORPHAPI_INSTALLED = False
# cellfinder - not exposed, but still check
_CELLFINDER_INSTALLED = True
try:
import cellfinder
except ImportError:
_CELLFINDER_INSTALLED = False

# cellfinder and associated packages
if _CELLFINDER_INSTALLED:
import cellfinder_core
else:
# Under the cellfinder_core name,
# import an error-throwing function that points users to the
# instructions for getting the cellfinder tool working
from ._tensorflow_handle import throw_error_on_call as cellfinder_core
22 changes: 22 additions & 0 deletions brainglobe/_tensorflow_handle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from importlib.metadata import PackageNotFoundError, version


def throw_error_on_call() -> None:
raise PackageNotFoundError(
"Python cannot locate the tensorflow package, "
"which is required to use cellfinder tools. "
"Please manually install tensorflow into your environment; "
"see https://github.com/brainglobe/brainglobe-meta#installation "
"for more details."
)


_CELLFINDER_FUNCTIONAL = True
try:
version("tensorflow")
except PackageNotFoundError:
# No tensorflow is visible to the Python interpreter.
# Do not expose the cellfinder_core package as it is unusable.
# Instead, import a cellfinder_core name that will
# throw an error if invoked.
_CELLFINDER_FUNCTIONAL = False
11 changes: 4 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@ classifiers = [

dependencies = [
"napari[all]",
"brainglobe-utils",
"bg-space>=0.5.0",
"cellfinder-core>=0.3",
"imio",
"bg-atlasapi>=1.0.0",
# "bg-atlasgen", [WIP]
# "brainglobe-napari", [WIP]
"brainglobe-napari-io",
"morphapi>=0.1.3.0",
"cellfinder-napari",
"brainreg-segment>=0.0.2",
"brainreg",
"brainreg-napari"
"brainreg-napari",
"cellfinder"
]

[project.optional-dependencies]
Expand All @@ -48,12 +51,6 @@ dev = [
"ruff",
"setuptools_scm",
]
morphapi = [
"morphapi>=0.1.3.0"
]
cellfinder = [
"cellfinder"
]

[build-system]
requires = [
Expand Down
12 changes: 12 additions & 0 deletions tests/test_unit/test_tool_exposure.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import inspect

import pytest
from importlib_metadata import PackageNotFoundError

import brainglobe as bg

# Tools that will be exposed in the brainglobe module/namespace
Expand Down Expand Up @@ -39,7 +42,16 @@ def test_tool_exposure() -> None:
assert not hasattr(bg, "morphapi")

# cellfinder - should not be exposed if installed
# cellfinder_core - should be exposed if installed
if bg._CELLFINDER_INSTALLED:
assert not hasattr(
bg, "cellfinder"
), "brainglobe.cellfinder is exposed"
assert hasattr(
bg, "cellfinder_core"
), "brainglobe.cellfinder_core is not exposed"
else:
# cellfinder_core should be aliased to a function
# that throws an error when invoked
with pytest.raises(PackageNotFoundError):
bg.cellfinder_core()