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
5 changes: 2 additions & 3 deletions .bioconda/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@ requirements:
- poetry
- pip
run:
- hmmer
- prodigal
- pyhmmer >=0.10
- pyrodigal >=3.0
- pyfastx >=0.8
- biopython
- numpy
- pandas
- psutil
- seqkit
- requests
- tqdm

Expand Down
5 changes: 2 additions & 3 deletions .conda/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ requirements:
- poetry
- pip
run:
- hmmer >=3.3
- prodigal >=2.6
- pyhmmer >=0.10
- pyrodigal >=3.0
- pyfastx >=0.8
- biopython >=1.8
- numpy
- pandas
- seqkit
- psutil >=5.9
- requests
- tqdm
Expand Down
44 changes: 21 additions & 23 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,47 @@ on:
- '**.ipynb'
- '**.bib'
- 'ms/*'
# No paths-ignore here: these jobs are required status checks, and a PR whose
# only changes match an ignore pattern would otherwise skip them and deadlock
# at "Expected - waiting for status to be reported".
pull_request:
types: [opened, reopened, edited]
paths-ignore:
- '**.md'
- '**.ipynb'
- '**.bib'
- 'ms/*'
types: [opened, reopened, edited, synchronize]

jobs:

create-env:
name: ${{ matrix.os }}
test:
name: ${{ matrix.os }} / py${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash -l {0}

strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ["3.9", "3.12"]

steps:
- name: checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: create environment
uses: conda-incubator/setup-miniconda@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: 3.8
# mamba-version: "*"
channels: conda-forge,bioconda,defaults
auto-activate-base: false
activate-environment: tests_pynteny
environment-file: envs/pynteny-dev.yml
python-version: ${{ matrix.python-version }}

- name: Build & Install Pynteny
run: poetry build && pip install dist/pynteny*.whl
# Pynteny is a pure-pip package (no conda / external binaries required).
- name: Install Pynteny
run: |
python -m pip install --upgrade pip
python -m pip install .
python -m pip install coverage

- name: Run tests and collect coverage
run: pynteny --help && coverage run --omit pynteny/wrappers.py,pynteny/cli.py,pynteny/subcommands.py,pynteny/utils.py -m unittest discover tests && coverage xml
run: |
pynteny --help
coverage run --omit pynteny/wrappers.py,pynteny/cli.py,pynteny/subcommands.py,pynteny/utils.py -m unittest discover tests
coverage xml

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
Expand Down
32 changes: 13 additions & 19 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,30 @@ Unsure where to begin contributing to Pynteny? You can start by looking for issu

## Setting up a local developer environment

Pynteny depends on packages that are not available in pip, namely [HMMER](https://github.com/EddyRivasLab/hmmer) and [Prodigal](https://github.com/hyattpd/Prodigal). These can be installed from the bioconda channel. Hence, to setup up a developer environment for Pynteny:
Pynteny is a pure-Python package. Its dependencies (including the HMMER and
Prodigal engines, provided by [pyhmmer](https://github.com/althonos/pyhmmer)
and [pyrodigal](https://github.com/althonos/pyrodigal)) are all installable
from pip, so no conda or external binaries are required. To set up a developer
environment for Pynteny:

1. Fork and download repo, cd to downloaded directory. You should create a new branch to work on your issue.

2. Create conda environment with required dependencies:

The file `envs/pynteny-dev.yml` contains all dependencies required to use Pynteny. Conda is very slow solving the environment. It is recommended to use [mamba](https://github.com/mamba-org/mamba) instead:

```bash
mamba env create -n pynteny-dev -f envs/pynteny-dev.yml
conda activate pynteny-dev
```

3. Build package
2. Create a virtual environment and install Pynteny in editable mode:

```bash
(pynteny-dev) poetry build
python -m venv .venv
source .venv/bin/activate
pip install -e .
```

4. Install Pynteny
3. Run tests

```bash
(pynteny-dev) pip install dist/pynteny*.whl
python -m unittest discover tests
```

5. Run tests

```bash
(pynteny-dev) python -m unittest discover tests
```
A conda environment file (`envs/pynteny-dev.yml`) is still provided for
contributors who prefer conda, but it is no longer required.

## Using GitHub codespaces

Expand Down
25 changes: 7 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
# FROM mcr.microsoft.com/devcontainers/miniconda:0-3
FROM mambaorg/micromamba:latest
USER root
FROM python:3.11-slim

WORKDIR /Pynteny
# Copy repo to docker container
COPY src/pynteny src/pynteny/
COPY tests tests/
COPY envs envs/
COPY README.md .
COPY pyproject.toml .
COPY LICENSE .

# Make conda environment and activate
# RUN conda install mamba -n base -c conda-forge
RUN micromamba env create -f envs/pynteny-dev.yml
SHELL ["micromamba", "run", "-n", "pynteny-dev", "/bin/bash", "-c"]
# Build and install Pynteny
RUN poetry build && pip install dist/pynteny*.whl && pynteny --help
# Give read/write permissions to install directory (needed to make config.json)
RUN chmod ugo+rw /opt/conda/envs/pynteny-dev/lib/python3.10/site-packages

# Initialize conda for default user
RUN micromamba shell init --shell=bash
# # Activate pynteny environment by default
RUN echo "micromamba activate pynteny-dev" >> ../root/.bashrc
RUN source ../root/.bashrc
# Build and install Pynteny (pure pip, no conda required).
# pyhmmer and pyrodigal ship manylinux wheels, so no compiler toolchain is needed.
RUN pip install --no-cache-dir poetry \
&& poetry build \
&& pip install --no-cache-dir dist/pynteny*.whl \
&& pynteny --help
39 changes: 20 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,35 +36,37 @@ Check out the [Pynteny paper](https://doi.org/10.21105/joss.05289) in the Journa

## 2. :wrench: Setup

Install with conda:
Pynteny is a pure-Python package (it no longer requires conda or any external
binaries). All dependencies, including the HMMER and Prodigal engines, are
provided by the pip packages [pyhmmer](https://github.com/althonos/pyhmmer) and
[pyrodigal](https://github.com/althonos/pyrodigal).

1. Pynteny requires Python 3.10. The easiest way to handle dependencies is by creating a dedicated conda environment:
Install with pip:

```bash
conda create -n pynteny -c bioconda -c conda-forge python=3.10 pynteny
conda activate pynteny
pip install pynteny
```

2. Check that installation worked fine:
Or with conda (from bioconda):

```bash
(pynteny) pynteny --help
conda create -n pynteny -c bioconda -c conda-forge python=3.10 pynteny
conda activate pynteny
```
### 2.1. Installing on Windows

Pynteny is designed to run on Linux machines. However, it can be installed within the [Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/install) via conda.

### 2.2. Installing on MacOS with the latest ARM64 architecture

Pynteny doesn't currently support the latest ARM64 architecture of silicon processors (e.g. MacBook M1 and M2). If that is your case, you can install Pynteny using the workaround below (based on [this post](https://towardsdatascience.com/how-to-manage-conda-environments-on-an-apple-silicon-m1-mac-1e29cb3bad12)):
Check that the installation worked fine:

```bash
CONDA_SUBDIR=osx-64 conda create -n pynteny_x86 python=3.10
conda activate pynteny_x86
conda config --env --set subdir osx-64
conda install -c bioconda pynteny
pynteny --help
```

### 2.1. Installing on Windows

Pynteny is developed and tested on Linux, but since it is now a pure-Python
package, `pip install pynteny` also works on Windows and macOS (including Apple
Silicon / ARM64), provided wheels are available for pyhmmer and pyrodigal on
your platform.

## 3. :rocket: Usage

Consider the following toy example of a syntenic block:
Expand Down Expand Up @@ -126,11 +128,10 @@ You can find more notebooks in the [examples directory](docs/examples/). Find mo
## 5. :arrows_counterclockwise: Dependencies
Pynteny would not work without these awesome projects:

- [hmmer](https://github.com/EddyRivasLab/hmmer)
- [prodigal](https://github.com/hyattpd/Prodigal)
- [pyhmmer](https://github.com/althonos/pyhmmer)
- [pyrodigal](https://github.com/althonos/pyrodigal)
- [pyfastx](https://github.com/lmdu/pyfastx)
- [biopython](https://github.com/biopython/biopython)
- [seqkit](https://bioinf.shenwei.me/seqkit/)
- [numpy](https://github.com/numpy/numpy)
- [pandas](https://github.com/pandas-dev/pandas)
- [psutil](https://github.com/giampaolo/psutil)
Expand Down
31 changes: 6 additions & 25 deletions docs/examples/example_api_colab.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,14 @@
"outputs": [],
"source": [
"%%capture\n",
"#@title Install Pynteny (can take a few minutes)\n",
"#@title Install Pynteny\n",
"try:\n",
" import google.colab\n",
" import sys\n",
" # Install miniconda\n",
" !wget -qnc https://repo.anaconda.com/miniconda/Miniconda3-py38_22.11.1-1-Linux-x86_64.sh\n",
" !chmod +x Miniconda3-py38_22.11.1-1-Linux-x86_64.sh\n",
" !bash ./Miniconda3-py38_22.11.1-1-Linux-x86_64.sh -bfp /usr/local/ 2>&1 1>/dev/null\n",
" !rm ./Miniconda3-py38_22.11.1-1-Linux-x86_64.sh\n",
" # Install Pynteny and dependencies\n",
" !conda install -q -y -c conda-forge -c -c bioconda \\\n",
" python=3.8 \\\n",
" poetry=1.3 \\\n",
" pip \\\n",
" hmmer=3.3 \\\n",
" prodigal=2.6 \\\n",
" pyfastx=0.8 \\\n",
" biopython=1.80 \\\n",
" psutil=5.9 \\\n",
" tqdm \\\n",
" requests 2>&1 1>/dev/null\n",
" !pip install --upgrade numpy==1.21.6\n",
" !pip install --upgrade pandas==1.3.5\n",
" !git clone https://github.com/Robaina/Pynteny.git\n",
" !cd Pynteny && poetry build && pip install -q dist/pynteny*.whl\n",
" !cp -r Pynteny/tests/ . && rm -r Pynteny\n",
" sys.path.insert(0, f\"/usr/local/lib/python3.8/site-packages/\")\n",
" # Pynteny is a pure-pip package (no conda / external binaries required).\n",
" !pip install -q pynteny\n",
" # Grab the bundled test data used throughout this example.\n",
" !git clone -q https://github.com/Robaina/Pynteny.git\n",
" !cp -r Pynteny/tests/ . && rm -rf Pynteny\n",
"except ImportError:\n",
" pass"
]
Expand Down
32 changes: 17 additions & 15 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@ These are the available subcommands in the CLI, run as ```pynteny <subcommand> <

## 2. Setup

Install with conda:
Pynteny is a pure-Python package (it no longer requires conda or any external
binaries). The HMMER and Prodigal engines are provided by the pip packages
[pyhmmer](https://github.com/althonos/pyhmmer) and
[pyrodigal](https://github.com/althonos/pyrodigal).

Pynteny requires Python 3.10. The easiest way to handle dependencies is by creating a dedicated conda environment:
Install with pip:

```bash
pip install pynteny
```

Or with conda (from bioconda):

```bash
conda create -n pynteny -c bioconda -c conda-forge python=3.10 pynteny
Expand All @@ -25,22 +34,15 @@ conda activate pynteny
Check that installation worked fine:

```bash
(pynteny) pynteny --help
pynteny --help
```
### 2.1. Installing on Windows

Pynteny is designed to run on Linux machines. However, it can be installed within the [Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/install) via conda.
### 2.1. Installing on Windows and macOS

### 2.2. Installing on MacOS with the latest ARM64 architecture

Pynteny doesn't currently support the latest ARM64 architecture of silicon processors (e.g. MacBook M1 and M2). If that is your case, you can install Pynteny using the workaround below (based on [this post](https://towardsdatascience.com/how-to-manage-conda-environments-on-an-apple-silicon-m1-mac-1e29cb3bad12)):

```bash
CONDA_SUBDIR=osx-64 conda create -n pynteny_x86 python=3.10
conda activate pynteny_x86
conda config --env --set subdir osx-64
conda install -c bioconda pynteny
```
Pynteny is developed and tested on Linux, but since it is now a pure-Python
package, `pip install pynteny` also works on Windows and macOS (including Apple
Silicon / ARM64), provided wheels are available for pyhmmer and pyrodigal on
your platform.

## 3. General usage

Expand Down
5 changes: 2 additions & 3 deletions envs/pynteny-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@ dependencies:
- python >= 3.8
- poetry >= 1.3
- pip
- hmmer >= 3.3
- prodigal >= 2.6
- pyfastx >=0.8
- biopython >= 1.8
- numpy
- pandas
- seqkit
- psutil >= 5.9
- requests
- tqdm
- pip:
- pyhmmer >=0.10
- pyrodigal >=3.0
- mkdocs
- mkdocs-gen-files
- pymdown-extensions
Expand Down
9 changes: 9 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ packages = [{ include = "pynteny", from = "src" }]
include = ["src/pynteny/config.json"]
[tool.poetry.dependencies]
python = "^3.8"
pyhmmer = ">=0.10"
pyrodigal = ">=3.0"
pyfastx = ">=0.8"
biopython = ">=1.8"
numpy = "*"
pandas = "*"
psutil = ">=5.9"
requests = "*"
tqdm = "*"
[tool.poetry.scripts]
pynteny = "pynteny.cli:main"

Expand Down
6 changes: 3 additions & 3 deletions src/pynteny/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,9 @@ def _assign_code_to_HMM(self, hmm_group_name: str) -> int:
def _add_meta_codes_to_HMM_hits(self, all_hit_labels: pd.Dataframe) -> pd.Dataframe:
"""Add numeric codes for each hmm and strand, compute distance between genes"""
all_hit_labels["gene_pos_diff"] = all_hit_labels.gene_pos.diff()
all_hit_labels.loc[
0, "gene_pos_diff"
] = 1 # required for rolling (skips first nan)
all_hit_labels.loc[0, "gene_pos_diff"] = (
1 # required for rolling (skips first nan)
)
all_hit_labels["hmm_code"] = all_hit_labels.hmm.apply(self._assign_code_to_HMM)
all_hit_labels["strand"] = all_hit_labels.strand.apply(
lambda strand: -1 if strand == "neg" else (1 if strand == "pos" else 0)
Expand Down
Loading
Loading