-
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
Showing
18 changed files
with
390 additions
and
1 deletion.
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,36 @@ | ||
# Package builds | ||
name: Build | ||
|
||
on: | ||
release: | ||
types: | ||
- published | ||
|
||
jobs: | ||
pypi: | ||
name: PyPI Wheel | ||
runs-on: "ubuntu-22.04" | ||
steps: | ||
|
||
- name: Checkout repo | ||
uses: actions/[email protected] | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: 3.8 | ||
|
||
- name: Install dependencies | ||
run: | | ||
pip install --editable .[dev] | ||
- name: Build wheel | ||
run: | | ||
python -m build --wheel | ||
twine check dist/* | ||
- name: Upload | ||
env: | ||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} | ||
run: | | ||
twine upload -u __token__ -p "$PYPI_TOKEN" dist/* --non-interactive --skip-existing --disable-progress-bar |
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,70 @@ | ||
# Continuous integration | ||
name: CI | ||
|
||
on: | ||
push: | ||
paths: | ||
- "sleap_roots/**" | ||
- "tests/**" | ||
- ".github/workflows/ci.yml" | ||
- "environment.yml" | ||
- "setup.cfg" | ||
|
||
jobs: | ||
# Tests with pytest | ||
tests: | ||
|
||
strategy: | ||
fail-fast: false | ||
matrix: | ||
os: ["ubuntu-22.04", "windows-2022"] | ||
python: [3.8] | ||
|
||
name: Tests (${{ matrix.os }}, Python ${{ matrix.python }}) | ||
runs-on: ${{ matrix.os }} | ||
|
||
steps: | ||
|
||
- name: Checkout repo | ||
uses: actions/[email protected] | ||
|
||
- name: Cache conda | ||
uses: actions/cache@v1 | ||
env: | ||
# Increase this value to reset cache if environment.yml has not changed | ||
CACHE_NUMBER: 0 | ||
with: | ||
path: ~/conda_pkgs_dir | ||
key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('environment.yml', 'setup.cfg') }} | ||
|
||
- name: Setup Miniconda | ||
# https://github.com/conda-incubator/setup-miniconda | ||
uses: conda-incubator/[email protected] | ||
with: | ||
python-version: ${{ matrix.python }} | ||
use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly! | ||
environment-file: environment.yml | ||
activate-environment: sleap-roots | ||
|
||
- name: Print environment info | ||
shell: bash -l {0} | ||
run: | | ||
which python | ||
conda info | ||
conda list | ||
- name: Test with pytest | ||
if: ${{ !(startsWith(matrix.os, 'ubuntu') && matrix.python == 3.8) }} | ||
shell: bash -l {0} | ||
run: | | ||
pytest | ||
- name: Test with pytest (with coverage) | ||
if: ${{ startsWith(matrix.os, 'ubuntu') && matrix.python == 3.8 }} | ||
shell: bash -l {0} | ||
run: | | ||
pytest --cov=sleap_roots --cov-report=xml tests/ | ||
- name: Upload coverage | ||
uses: codecov/codecov-action@v3 | ||
if: ${{ startsWith(matrix.os, 'ubuntu') && matrix.python == 3.8 }} | ||
with: | ||
fail_ci_if_error: true | ||
verbose: false |
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,41 @@ | ||
# This action runs: | ||
# | ||
# 1. Linting with black | ||
# | ||
# 2. Docstring style checking with pydocstyle | ||
# Note: This uses Google-style docstring convention | ||
# Ref: https://google.github.io/styleguide/pyguide.html | ||
|
||
name: Lint | ||
|
||
on: | ||
push: | ||
paths: | ||
- "sleap_roots/**" | ||
- "tests/**" | ||
- ".github/workflows/lint.yml" | ||
|
||
jobs: | ||
lint: | ||
name: Lint | ||
runs-on: "ubuntu-22.04" | ||
steps: | ||
|
||
- name: Checkout repo | ||
uses: actions/[email protected] | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: 3.8 | ||
|
||
- name: Install dependencies | ||
run: | | ||
pip install --editable .[dev] | ||
- name: Run Black | ||
run: | | ||
black --check sleap_roots tests | ||
- name: Run pydocstyle | ||
run: | | ||
pydocstyle --convention=google sleap_roots/ |
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 |
---|---|---|
|
@@ -127,3 +127,5 @@ dmypy.json | |
|
||
# Pyre type checker | ||
.pyre/ | ||
|
||
.DS_Store |
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,2 +1,41 @@ | ||
# sleap-roots | ||
Analysis tools for SLEAP-based root phenotyping. | ||
|
||
[](https://github.com/talmolab/sleap-roots/actions/workflows/ci.yml) | ||
[](https://github.com/talmolab/sleap-roots/actions/workflows/lint.yml) | ||
[](https://codecov.io/gh/talmolab/sleap-roots) | ||
[](https://github.com/talmolab/sleap-roots/releases/) | ||
[](https://pypi.org/project/sleap-roots) | ||
|
||
Analysis tools for [SLEAP](https://sleap.ai)-based plant root phenotyping. | ||
|
||
## Installation | ||
``` | ||
pip install sleap-roots | ||
``` | ||
|
||
If you are using conda: | ||
``` | ||
conda create -n sleap-roots python=3.8 | ||
conda activate sleap-roots | ||
pip install sleap-roots | ||
``` | ||
|
||
### Development | ||
For development, use the following syntax to install in editable mode: | ||
``` | ||
conda env create -f environment.yml | ||
``` | ||
This will create a conda environment called `sleap-roots`. | ||
|
||
To run tests, first activate the environment: | ||
``` | ||
conda activate sleap-roots | ||
``` | ||
Then run `pytest` with: | ||
``` | ||
pytest tests | ||
``` | ||
To start fresh, just delete the environment: | ||
``` | ||
conda env remove -n sleap-roots | ||
``` |
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,12 @@ | ||
coverage: | ||
status: | ||
project: # Measures overall project coverage. | ||
default: | ||
target: auto | ||
threshold: 0.05% | ||
informational: true # Project coverage for stats only. | ||
patch: # Only measures lines adjusted in the pull request. | ||
default: | ||
target: auto | ||
threshold: 0.05% | ||
informational: true # Patch coverage for stats only. |
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,7 @@ | ||
name: sleap-roots | ||
|
||
dependencies: | ||
- python=3.8 | ||
- pip | ||
- pip: | ||
- "--editable=.[dev]" |
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,3 @@ | ||
[build-system] | ||
requires = ["setuptools"] | ||
build-backend = "setuptools.build_meta |
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,45 @@ | ||
[metadata] | ||
name = sleap-roots | ||
version = attr: sleap_roots.__version__ | ||
author = Talmo Pereira | ||
author_email = [email protected] | ||
maintainer = Talmo Pereira | ||
maintainer_email = [email protected] | ||
url = https://github.com/talmolab/sleap-roots | ||
description = Analysis tools for SLEAP-based plant root phenotyping. | ||
long_description = file: README.md, LICENSE | ||
long_description_content_type = text/markdown | ||
keywords = sleap, plants, roots | ||
license = BSD 3-Clause License | ||
classifiers = | ||
Programming Language :: Python :: 3 | ||
|
||
[options] | ||
packages = find: | ||
install_requires = | ||
numpy | ||
attrs | ||
matplotlib | ||
|
||
[options.extras_require] | ||
dev = | ||
pytest | ||
pytest-cov | ||
black | ||
pydocstyle | ||
toml | ||
twine | ||
build | ||
|
||
[options.exclude_package_data] | ||
tests = * | ||
docs = * | ||
|
||
[options.packages.find] | ||
exclude = | ||
tests* | ||
docs* | ||
|
||
[pydocstyle] | ||
convention = google | ||
match-dir = 'sleap_roots' |
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,7 @@ | ||
"""High-level imports.""" | ||
|
||
from sleap_roots.series import Series | ||
|
||
# Define package version. | ||
# This is read dynamically by setuptools in setup.cfg to determine the release version. | ||
__version__ = "0.0.1" |
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 @@ | ||
"""Trait calculations that rely on bases (i.e., dicot-only).""" |
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 @@ | ||
"""Convex hull fitting and derived trait calculation.""" |
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 @@ | ||
"""Ellipse fitting and derived trait calculation.""" |
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,88 @@ | ||
"""Series-level data loader.""" | ||
|
||
import attrs | ||
from typing import Optional, Tuple | ||
from pathlib import Path | ||
|
||
try: | ||
import sleap | ||
except: | ||
import sleap_io as sleap | ||
|
||
|
||
@attrs.define | ||
class Series: | ||
h5_path: Optional[str] = None | ||
primary_name: str = "primary_multi_day" | ||
lateral_name: str = "lateral__nodes" | ||
primary_labels: Optional[sleap.Labels] = None | ||
lateral_labels: Optional[sleap.Labels] = None | ||
|
||
@classmethod | ||
def load(cls, h5_path: str, primary_name: str = "primary_multi_day", lateral_name: str = "lateral__nodes"): | ||
primary_path = Path(h5_path).with_suffix(f".{primary_name}.predictions.slp").as_posix() | ||
lateral_path = Path(h5_path).with_suffix(f".{lateral_name}.predictions.slp").as_posix() | ||
|
||
return cls( | ||
h5_path, | ||
primary_name=primary_name, | ||
lateral_name=lateral_name, | ||
primary_labels=sleap.load_file(primary_path), | ||
lateral_labels=sleap.load_file(lateral_path), | ||
) | ||
|
||
@property | ||
def series_name(self) -> str: | ||
return Path(self.h5_path).stem | ||
|
||
@property | ||
def video(self) -> sleap.Video: | ||
return self.primary_labels.video | ||
|
||
def __len__(self) -> int: | ||
return len(self.video) | ||
|
||
def __getitem__(self, idx: int) -> Tuple[sleap.LabeledFrame, sleap.LabeledFrame]: | ||
return self.get_frame(idx) | ||
|
||
def __iter__(self): | ||
for i in range(len(self)): | ||
yield self[i] | ||
|
||
def get_frame(self, frame_idx: int) -> Tuple[sleap.LabeledFrame, sleap.LabeledFrame]: | ||
"""Return labeled frames for primary and lateral predictions. | ||
Args: | ||
frame_idx: Integer frame number. | ||
Returns: | ||
Tuple of (primary_lf, lateral_lf) corresponding to the | ||
sleap.LabeledFrames from each set of predictions on the same frame. | ||
""" | ||
lf_primary = self.primary_labels.find(self.primary_labels.video, frame_idx, return_new=True)[0] | ||
lf_lateral = self.lateral_labels.find(self.lateral_labels.video, frame_idx, return_new=True)[0] | ||
return lf_primary, lf_lateral | ||
|
||
def plot(self, frame_idx: int, scale: float = 1.0, **kwargs): | ||
primary_lf, lateral_lf = self.get_frame(frame_idx) | ||
sleap.nn.viz.plot_img(primary_lf.image, scale=scale) | ||
sleap.nn.viz.plot_instances(primary_lf.instances, cmap=["r"], **kwargs) | ||
sleap.nn.viz.plot_instances(lateral_lf.instances, cmap=["g"], **kwargs) | ||
|
||
|
||
def find_all_series(data_folders: list[str]) -> list[str]: | ||
"""Find all .h5 series from a list of folders. | ||
Args: | ||
data_folders: List of paths to folders containing .h5 series. | ||
Returns: | ||
A list of filenames to .h5 series. | ||
""" | ||
if type(data_folders) != list: | ||
data_folders = [data_folders] | ||
|
||
h5_series = [] | ||
for data_folder in data_folders: | ||
h5_series.extend([Path(p).as_posix() for p in Path(data_folder).glob("*.h5")]) | ||
return h5_series |
Binary file not shown.
Binary file not shown.
Oops, something went wrong.