roxylib 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- roxylib-0.2.0/.github/workflows/examples.yml +30 -0
- roxylib-0.2.0/.github/workflows/pre-commit.yml +17 -0
- roxylib-0.2.0/.github/workflows/publish-pypi.yml +48 -0
- roxylib-0.2.0/.github/workflows/tests.yml +34 -0
- roxylib-0.2.0/.gitignore +36 -0
- roxylib-0.2.0/AGENTS.md +37 -0
- roxylib-0.2.0/DEVELOPMENT.md +52 -0
- roxylib-0.2.0/LICENSE +21 -0
- roxylib-0.2.0/PKG-INFO +154 -0
- roxylib-0.2.0/README.md +123 -0
- roxylib-0.2.0/examples/basic_api.py +30 -0
- roxylib-0.2.0/examples/cli_roundtrip.py +91 -0
- roxylib-0.2.0/examples/configured_descriptors.py +50 -0
- roxylib-0.2.0/examples/run_ci_examples.sh +6 -0
- roxylib-0.2.0/prek.toml +48 -0
- roxylib-0.2.0/pyproject.toml +124 -0
- roxylib-0.2.0/roxy/__init__.py +26 -0
- roxylib-0.2.0/roxy/cli/__init__.py +7 -0
- roxylib-0.2.0/roxy/cli/_utils.py +24 -0
- roxylib-0.2.0/roxy/cli/compute.py +167 -0
- roxylib-0.2.0/roxy/cli/describe_descriptor.py +101 -0
- roxylib-0.2.0/roxy/cli/init_config.py +61 -0
- roxylib-0.2.0/roxy/cli/list_descriptors.py +78 -0
- roxylib-0.2.0/roxy/cli/main.py +65 -0
- roxylib-0.2.0/roxy/core/__init__.py +17 -0
- roxylib-0.2.0/roxy/core/constants.py +450 -0
- roxylib-0.2.0/roxy/core/exceptions.py +17 -0
- roxylib-0.2.0/roxy/core/io.py +140 -0
- roxylib-0.2.0/roxy/data/__init__.py +1 -0
- roxylib-0.2.0/roxy/data/aaindex.csv +567 -0
- roxylib-0.2.0/roxy/descriptors/__init__.py +22 -0
- roxylib-0.2.0/roxy/descriptors/_utils.py +284 -0
- roxylib-0.2.0/roxy/descriptors/aaindex/__init__.py +5 -0
- roxylib-0.2.0/roxy/descriptors/aaindex/aaindex.py +138 -0
- roxylib-0.2.0/roxy/descriptors/autocorrelation/__init__.py +5 -0
- roxylib-0.2.0/roxy/descriptors/autocorrelation/autocorrelation.py +195 -0
- roxylib-0.2.0/roxy/descriptors/base.py +82 -0
- roxylib-0.2.0/roxy/descriptors/complexity/__init__.py +11 -0
- roxylib-0.2.0/roxy/descriptors/complexity/entropy_complexity.py +166 -0
- roxylib-0.2.0/roxy/descriptors/complexity/local_repetition.py +217 -0
- roxylib-0.2.0/roxy/descriptors/complexity/run_blockiness.py +128 -0
- roxylib-0.2.0/roxy/descriptors/composition/__init__.py +15 -0
- roxylib-0.2.0/roxy/descriptors/composition/aac.py +63 -0
- roxylib-0.2.0/roxy/descriptors/composition/compositional_bias.py +147 -0
- roxylib-0.2.0/roxy/descriptors/composition/dpc.py +70 -0
- roxylib-0.2.0/roxy/descriptors/composition/grouped.py +54 -0
- roxylib-0.2.0/roxy/descriptors/composition/kmer_full_alphabet.py +86 -0
- roxylib-0.2.0/roxy/descriptors/ctd/__init__.py +9 -0
- roxylib-0.2.0/roxy/descriptors/ctd/ctd_classic.py +155 -0
- roxylib-0.2.0/roxy/descriptors/ctd/distribution.py +130 -0
- roxylib-0.2.0/roxy/descriptors/hybrid/__init__.py +5 -0
- roxylib-0.2.0/roxy/descriptors/hybrid/family_summary.py +205 -0
- roxylib-0.2.0/roxy/descriptors/motif/__init__.py +13 -0
- roxylib-0.2.0/roxy/descriptors/motif/functional_residue_content.py +123 -0
- roxylib-0.2.0/roxy/descriptors/motif/pattern.py +112 -0
- roxylib-0.2.0/roxy/descriptors/motif/spacing.py +185 -0
- roxylib-0.2.0/roxy/descriptors/motif/user_regex.py +128 -0
- roxylib-0.2.0/roxy/descriptors/physicochemical/__init__.py +15 -0
- roxylib-0.2.0/roxy/descriptors/physicochemical/charge.py +172 -0
- roxylib-0.2.0/roxy/descriptors/physicochemical/global_basic.py +202 -0
- roxylib-0.2.0/roxy/descriptors/physicochemical/hydrophobicity.py +191 -0
- roxylib-0.2.0/roxy/descriptors/physicochemical/order_disorder.py +165 -0
- roxylib-0.2.0/roxy/descriptors/physicochemical/structural_propensity.py +140 -0
- roxylib-0.2.0/roxy/descriptors/positional/__init__.py +11 -0
- roxylib-0.2.0/roxy/descriptors/positional/normalized.py +122 -0
- roxylib-0.2.0/roxy/descriptors/positional/sliding_window.py +124 -0
- roxylib-0.2.0/roxy/descriptors/positional/terminal.py +116 -0
- roxylib-0.2.0/roxy/descriptors/pseudo/__init__.py +11 -0
- roxylib-0.2.0/roxy/descriptors/pseudo/pseaac.py +122 -0
- roxylib-0.2.0/roxy/descriptors/pseudo/qso.py +114 -0
- roxylib-0.2.0/roxy/descriptors/pseudo/sequence_order.py +159 -0
- roxylib-0.2.0/roxy/descriptors/registry.py +36 -0
- roxylib-0.2.0/tests/__init__.py +0 -0
- roxylib-0.2.0/tests/cli/__init__.py +0 -0
- roxylib-0.2.0/tests/cli/_helpers.py +8 -0
- roxylib-0.2.0/tests/cli/test_compute_cli.py +65 -0
- roxylib-0.2.0/tests/cli/test_concat_frames.py +43 -0
- roxylib-0.2.0/tests/cli/test_config.py +43 -0
- roxylib-0.2.0/tests/cli/test_resolve_names.py +27 -0
- roxylib-0.2.0/tests/cli/test_smoke.py +66 -0
- roxylib-0.2.0/tests/core/__init__.py +0 -0
- roxylib-0.2.0/tests/core/test_exceptions.py +17 -0
- roxylib-0.2.0/tests/core/test_io.py +83 -0
- roxylib-0.2.0/tests/descriptors/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/_helpers.py +23 -0
- roxylib-0.2.0/tests/descriptors/aaindex/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/aaindex/test_aaindex.py +63 -0
- roxylib-0.2.0/tests/descriptors/autocorrelation/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/autocorrelation/test_autocorrelation.py +57 -0
- roxylib-0.2.0/tests/descriptors/complexity/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/complexity/test_entropy_complexity.py +59 -0
- roxylib-0.2.0/tests/descriptors/complexity/test_local_repetition.py +52 -0
- roxylib-0.2.0/tests/descriptors/complexity/test_run_blockiness.py +53 -0
- roxylib-0.2.0/tests/descriptors/composition/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/composition/test_aac.py +50 -0
- roxylib-0.2.0/tests/descriptors/composition/test_compositional_bias.py +50 -0
- roxylib-0.2.0/tests/descriptors/composition/test_dpc.py +47 -0
- roxylib-0.2.0/tests/descriptors/composition/test_grouped.py +42 -0
- roxylib-0.2.0/tests/descriptors/composition/test_kmer_full_alphabet.py +55 -0
- roxylib-0.2.0/tests/descriptors/conftest.py +30 -0
- roxylib-0.2.0/tests/descriptors/ctd/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/ctd/test_ctd_classic.py +68 -0
- roxylib-0.2.0/tests/descriptors/ctd/test_distribution.py +57 -0
- roxylib-0.2.0/tests/descriptors/hybrid/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/hybrid/test_family_summary.py +44 -0
- roxylib-0.2.0/tests/descriptors/motif/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/motif/test_functional_residue_content.py +54 -0
- roxylib-0.2.0/tests/descriptors/motif/test_pattern.py +55 -0
- roxylib-0.2.0/tests/descriptors/motif/test_spacing.py +60 -0
- roxylib-0.2.0/tests/descriptors/motif/test_user_regex.py +56 -0
- roxylib-0.2.0/tests/descriptors/physicochemical/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/physicochemical/test_charge.py +57 -0
- roxylib-0.2.0/tests/descriptors/physicochemical/test_global_basic.py +73 -0
- roxylib-0.2.0/tests/descriptors/physicochemical/test_hydrophobicity.py +55 -0
- roxylib-0.2.0/tests/descriptors/physicochemical/test_order_disorder.py +52 -0
- roxylib-0.2.0/tests/descriptors/physicochemical/test_structural_propensity.py +59 -0
- roxylib-0.2.0/tests/descriptors/positional/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/positional/test_normalized.py +65 -0
- roxylib-0.2.0/tests/descriptors/positional/test_sliding_window.py +50 -0
- roxylib-0.2.0/tests/descriptors/positional/test_terminal.py +55 -0
- roxylib-0.2.0/tests/descriptors/pseudo/__init__.py +0 -0
- roxylib-0.2.0/tests/descriptors/pseudo/test_pseaac.py +50 -0
- roxylib-0.2.0/tests/descriptors/pseudo/test_qso.py +36 -0
- roxylib-0.2.0/tests/descriptors/pseudo/test_sequence_order.py +53 -0
- roxylib-0.2.0/tests/descriptors/test_registry_metadata.py +76 -0
- roxylib-0.2.0/uv.lock +867 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: examples
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
paths:
|
|
6
|
+
- "roxy/**"
|
|
7
|
+
- "examples/**"
|
|
8
|
+
- "pyproject.toml"
|
|
9
|
+
- "uv.lock"
|
|
10
|
+
- ".github/workflows/examples.yml"
|
|
11
|
+
pull_request:
|
|
12
|
+
paths:
|
|
13
|
+
- "roxy/**"
|
|
14
|
+
- "examples/**"
|
|
15
|
+
- "pyproject.toml"
|
|
16
|
+
- "uv.lock"
|
|
17
|
+
- ".github/workflows/examples.yml"
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
examples:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: astral-sh/setup-uv@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: uv sync --all-extras
|
|
29
|
+
- name: Run examples
|
|
30
|
+
run: bash examples/run_ci_examples.sh
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: pre-commit
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
prek:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: astral-sh/setup-uv@v5
|
|
13
|
+
with:
|
|
14
|
+
python-version: "3.12"
|
|
15
|
+
- name: Install dependencies
|
|
16
|
+
run: uv sync --all-extras
|
|
17
|
+
- uses: j178/prek-action@v2
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: publish-pypi
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: publish-pypi-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: false
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- uses: astral-sh/setup-uv@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
- name: Build distributions
|
|
25
|
+
run: uv build
|
|
26
|
+
- name: Upload distributions
|
|
27
|
+
uses: actions/upload-artifact@v4
|
|
28
|
+
with:
|
|
29
|
+
name: python-package-distributions
|
|
30
|
+
path: dist/
|
|
31
|
+
|
|
32
|
+
publish:
|
|
33
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
34
|
+
needs: build
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
environment:
|
|
37
|
+
name: pypi
|
|
38
|
+
url: https://pypi.org/p/roxylib
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write
|
|
41
|
+
steps:
|
|
42
|
+
- name: Download distributions
|
|
43
|
+
uses: actions/download-artifact@v4
|
|
44
|
+
with:
|
|
45
|
+
name: python-package-distributions
|
|
46
|
+
path: dist/
|
|
47
|
+
- name: Publish package distributions to PyPI
|
|
48
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
paths:
|
|
6
|
+
- "roxy/**"
|
|
7
|
+
- "tests/**"
|
|
8
|
+
- "pyproject.toml"
|
|
9
|
+
- "uv.lock"
|
|
10
|
+
- ".github/workflows/tests.yml"
|
|
11
|
+
pull_request:
|
|
12
|
+
paths:
|
|
13
|
+
- "roxy/**"
|
|
14
|
+
- "tests/**"
|
|
15
|
+
- "pyproject.toml"
|
|
16
|
+
- "uv.lock"
|
|
17
|
+
- ".github/workflows/tests.yml"
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
tests:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: astral-sh/setup-uv@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: ${{ matrix.python-version }}
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: uv sync --all-extras
|
|
33
|
+
- name: Run tests
|
|
34
|
+
run: uv run pytest -q
|
roxylib-0.2.0/.gitignore
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
*.egg
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
env/
|
|
13
|
+
|
|
14
|
+
# Testing & coverage
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
.coverage
|
|
17
|
+
.coverage.*
|
|
18
|
+
htmlcov/
|
|
19
|
+
|
|
20
|
+
# Tools
|
|
21
|
+
.ruff_cache/
|
|
22
|
+
.mypy_cache/
|
|
23
|
+
|
|
24
|
+
# uv
|
|
25
|
+
.uv-cache/
|
|
26
|
+
.uv_cache/
|
|
27
|
+
|
|
28
|
+
# Jupyter
|
|
29
|
+
.ipynb_checkpoints/
|
|
30
|
+
|
|
31
|
+
# IDEs
|
|
32
|
+
.idea/
|
|
33
|
+
.vscode/
|
|
34
|
+
|
|
35
|
+
# OS
|
|
36
|
+
.DS_Store
|
roxylib-0.2.0/AGENTS.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to AI agents when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
**Roxy** is a Python library for computing classical protein sequence descriptors for machine learning workflows. It sits between:
|
|
8
|
+
|
|
9
|
+
- **Sylphy** (sequence encoders and embeddings) — parallel; Roxy does NOT duplicate Sylphy's one-hot/ordinal/k-mers/FFT encoders
|
|
10
|
+
|
|
11
|
+
**Roxy scope**: classical descriptors only. Input: amino-acid sequences (strings). Output: `polars.DataFrame` of numerical features.
|
|
12
|
+
|
|
13
|
+
This project uses `uv` and `taskipy` — see `DEVELOPMENT.md` for setup and task commands.
|
|
14
|
+
|
|
15
|
+
## Descriptor Architecture
|
|
16
|
+
|
|
17
|
+
New descriptor families follow this pattern:
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from roxy.descriptors import BaseDescriptor, register
|
|
21
|
+
|
|
22
|
+
@register("aac", family="composition")
|
|
23
|
+
class AACDescriptor(BaseDescriptor):
|
|
24
|
+
def compute_one(self, sequence: str) -> dict[str, float]:
|
|
25
|
+
...
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- `compute_one` returns unprefixed feature names (`{"A": 0.05, "C": 0.02, ...}`).
|
|
29
|
+
- `compute(sequences, ids=...)` calls `compute_one` per sequence and returns a DataFrame with columns prefixed by `{name}_`.
|
|
30
|
+
- Register families by importing the module in `descriptors/__init__.py`.
|
|
31
|
+
|
|
32
|
+
## Key Invariants
|
|
33
|
+
|
|
34
|
+
- Descriptors must be stateless or only hold configuration (no mutable global state).
|
|
35
|
+
- `compute_one` must handle empty or non-standard sequences gracefully (return NaN, not raise).
|
|
36
|
+
- Never import EDA, projection, or visualisation libraries — those are out of scope.
|
|
37
|
+
- AAIndex CSV is bundled in `roxy/data/aaindex.csv` and loaded via `importlib.resources`. No download or cache path needed.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- Python 3.11–3.14
|
|
6
|
+
- [uv](https://docs.astral.sh/uv/) (package manager)
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
git clone https://github.com/ProteinEngineering-PESB2/roxy_library
|
|
12
|
+
cd roxy_library
|
|
13
|
+
uv sync --all-extras
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Common Tasks
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv run task format # sort imports + ruff format
|
|
20
|
+
uv run task lint # ruff check (no fixes)
|
|
21
|
+
uv run task lint-fix # ruff check --fix
|
|
22
|
+
uv run task test # pytest -q
|
|
23
|
+
uv run task test-v # pytest -v
|
|
24
|
+
uv run task test-cov # pytest + HTML coverage report
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Running the CLI
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv run roxy --version
|
|
31
|
+
uv run roxy --help
|
|
32
|
+
uv run roxy list
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Adding a Descriptor Family
|
|
36
|
+
|
|
37
|
+
1. Create `roxy/descriptors/<family_name>/<module>.py`.
|
|
38
|
+
2. Implement a class inheriting `BaseDescriptor` and decorate with `@register`.
|
|
39
|
+
3. Import the module in `roxy/descriptors/__init__.py` so the decorator fires.
|
|
40
|
+
4. Add tests in `tests/descriptors/<family_name>/`.
|
|
41
|
+
|
|
42
|
+
See `AGENTS.md` for the full list of families and their source notebooks in `dev_notebooks/`.
|
|
43
|
+
|
|
44
|
+
## Project Structure
|
|
45
|
+
|
|
46
|
+
See `AGENTS.md` for the full package layout.
|
|
47
|
+
|
|
48
|
+
## Branches
|
|
49
|
+
|
|
50
|
+
- `main` — stable releases
|
|
51
|
+
- `refactor/cleanup-base` — current base refactor (S1)
|
|
52
|
+
- `feat/descriptors-<family>` — individual descriptor families (S2/S3)
|
roxylib-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kren AI Lab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
roxylib-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: roxylib
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Protein sequence descriptors for machine learning.
|
|
5
|
+
Project-URL: Homepage, https://github.com/kren-ai-lab/roxy
|
|
6
|
+
Project-URL: Repository, https://github.com/kren-ai-lab/roxy
|
|
7
|
+
Project-URL: Issues, https://github.com/kren-ai-lab/roxy/issues
|
|
8
|
+
Author-email: Kren AI Lab <krenai@umag.cl>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: bioinformatics,descriptors,feature-engineering,machine-learning,proteins
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
22
|
+
Requires-Python: <3.15,>=3.11
|
|
23
|
+
Requires-Dist: numpy<3.0,>=2.4
|
|
24
|
+
Requires-Dist: polars>=1.40.0
|
|
25
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
26
|
+
Requires-Dist: rich<16.0,>=15.0
|
|
27
|
+
Requires-Dist: scikit-learn<2.0,>=1.8
|
|
28
|
+
Requires-Dist: scipy<2.0,>=1.17
|
|
29
|
+
Requires-Dist: typer<1.0,>=0.27
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# Roxy
|
|
33
|
+
|
|
34
|
+
[](https://pypi.org/project/roxylib/)
|
|
35
|
+
[](https://github.com/kren-ai-lab/roxylib)
|
|
36
|
+
[](https://github.com/kren-ai-lab/roxy/actions/workflows/tests.yml)
|
|
37
|
+

|
|
38
|
+
[](https://doi.org/10.5281/zenodo.21917534)
|
|
39
|
+
|
|
40
|
+
Classical protein sequence descriptors for machine learning.
|
|
41
|
+
|
|
42
|
+
Roxy computes classical numerical descriptors from amino-acid sequences and
|
|
43
|
+
returns tabular features as `polars.DataFrame` objects.
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install roxylib
|
|
49
|
+
# or with uv:
|
|
50
|
+
uv add roxylib
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quickstart
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from roxy import read_fasta, DESCRIPTOR_REGISTRY
|
|
57
|
+
|
|
58
|
+
# Load sequences from FASTA
|
|
59
|
+
records = read_fasta("sequences.fasta") # [(id, seq), ...]
|
|
60
|
+
sequences = [seq for _, seq in records]
|
|
61
|
+
ids = [seq_id for seq_id, _ in records]
|
|
62
|
+
|
|
63
|
+
descriptor = DESCRIPTOR_REGISTRY["aac"]()
|
|
64
|
+
features = descriptor.compute(sequences, ids=ids) # polars.DataFrame
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
For direct Python use, descriptors are importable by family:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from roxy.descriptors.aaindex import AAIndexDescriptor
|
|
71
|
+
from roxy.descriptors.composition import KmerFullAlphabetDescriptor
|
|
72
|
+
from roxy.descriptors.physicochemical import ChargeDescriptor
|
|
73
|
+
|
|
74
|
+
kmer = KmerFullAlphabetDescriptor(k=2)
|
|
75
|
+
aaindex = AAIndexDescriptor()
|
|
76
|
+
charge = ChargeDescriptor()
|
|
77
|
+
|
|
78
|
+
kmer_features = kmer.compute(["ACDEFGHIK"])
|
|
79
|
+
aaindex_features = aaindex.compute(["ACDEFGHIK"])
|
|
80
|
+
charge_features = charge.compute(["ACDEFGHIK"])
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## CLI
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
roxy --help
|
|
87
|
+
roxy --version
|
|
88
|
+
|
|
89
|
+
# List and inspect descriptors
|
|
90
|
+
roxy list
|
|
91
|
+
roxy list --family composition
|
|
92
|
+
roxy describe aac
|
|
93
|
+
|
|
94
|
+
# Compute descriptors from FASTA, CSV, or Parquet input
|
|
95
|
+
roxy compute sequences.fasta -d aac -d charge -o features.csv
|
|
96
|
+
roxy compute sequences.fasta -f composition -o composition.parquet
|
|
97
|
+
roxy compute sequences.csv -d aac --seq-col sequence --id-col id -o features.csv
|
|
98
|
+
roxy compute sequences.fasta --all -o all_features.parquet
|
|
99
|
+
|
|
100
|
+
# Generate and use a YAML config with descriptor parameters
|
|
101
|
+
roxy init-config -d aac -d charge -o roxy.yaml
|
|
102
|
+
roxy init-config -f composition -o composition.yaml
|
|
103
|
+
roxy init-config --all -o all_descriptors.yaml
|
|
104
|
+
roxy compute sequences.fasta --config roxy.yaml -o configured_features.csv
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`roxy compute` requires exactly one descriptor selector: `--config`, `--all`,
|
|
108
|
+
`--descriptor/-d`, or `--family/-f`. CSV and Parquet inputs use `sequence` as
|
|
109
|
+
the default sequence column; pass `--seq-col` and `--id-col` when needed.
|
|
110
|
+
|
|
111
|
+
## Examples
|
|
112
|
+
|
|
113
|
+
The repository ships a few plain Python scripts under [`examples/`](examples):
|
|
114
|
+
|
|
115
|
+
- `examples/basic_api.py` for direct descriptor use from Python
|
|
116
|
+
- `examples/configured_descriptors.py` for parameterized descriptor instances
|
|
117
|
+
- `examples/cli_roundtrip.py` for an end-to-end CLI config and compute flow
|
|
118
|
+
|
|
119
|
+
Run them with:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
bash examples/run_ci_examples.sh
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Descriptor Families
|
|
126
|
+
|
|
127
|
+
Registry keys are the names used by `roxy compute -d`, config files, and output
|
|
128
|
+
column prefixes.
|
|
129
|
+
|
|
130
|
+
| Family | Descriptor keys |
|
|
131
|
+
|-----------------|---------------------------------------------------------------------------------------|
|
|
132
|
+
| aaindex | `aaindex` |
|
|
133
|
+
| autocorrelation | `autocorrelation` |
|
|
134
|
+
| complexity | `entropy_complexity`, `local_repetition`, `run_blockiness` |
|
|
135
|
+
| composition | `aac`, `compositional_bias`, `dpc`, `grouped`, `kmer_full_alphabet` |
|
|
136
|
+
| ctd | `ctd_classic`, `distribution` |
|
|
137
|
+
| hybrid | `family_summary` |
|
|
138
|
+
| motif | `functional_residue_content`, `pattern`, `spacing`, `user_regex` |
|
|
139
|
+
| physicochemical | `charge`, `global_basic`, `hydrophobicity`, `order_disorder`, `structural_propensity` |
|
|
140
|
+
| positional | `normalized`, `sliding_window`, `terminal` |
|
|
141
|
+
| pseudo | `pseaac`, `qso`, `sequence_order` |
|
|
142
|
+
|
|
143
|
+
## Development
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
uv sync
|
|
147
|
+
uv run pytest -q
|
|
148
|
+
uv run task lint
|
|
149
|
+
uv run roxy --help
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Related Projects
|
|
153
|
+
|
|
154
|
+
- [Sylphy](https://github.com/kren-ai-lab/sylphy) — sequence encoders and pretrained model embeddings
|
roxylib-0.2.0/README.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Roxy
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/roxylib/)
|
|
4
|
+
[](https://github.com/kren-ai-lab/roxylib)
|
|
5
|
+
[](https://github.com/kren-ai-lab/roxy/actions/workflows/tests.yml)
|
|
6
|
+

|
|
7
|
+
[](https://doi.org/10.5281/zenodo.21917534)
|
|
8
|
+
|
|
9
|
+
Classical protein sequence descriptors for machine learning.
|
|
10
|
+
|
|
11
|
+
Roxy computes classical numerical descriptors from amino-acid sequences and
|
|
12
|
+
returns tabular features as `polars.DataFrame` objects.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install roxylib
|
|
18
|
+
# or with uv:
|
|
19
|
+
uv add roxylib
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from roxy import read_fasta, DESCRIPTOR_REGISTRY
|
|
26
|
+
|
|
27
|
+
# Load sequences from FASTA
|
|
28
|
+
records = read_fasta("sequences.fasta") # [(id, seq), ...]
|
|
29
|
+
sequences = [seq for _, seq in records]
|
|
30
|
+
ids = [seq_id for seq_id, _ in records]
|
|
31
|
+
|
|
32
|
+
descriptor = DESCRIPTOR_REGISTRY["aac"]()
|
|
33
|
+
features = descriptor.compute(sequences, ids=ids) # polars.DataFrame
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For direct Python use, descriptors are importable by family:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from roxy.descriptors.aaindex import AAIndexDescriptor
|
|
40
|
+
from roxy.descriptors.composition import KmerFullAlphabetDescriptor
|
|
41
|
+
from roxy.descriptors.physicochemical import ChargeDescriptor
|
|
42
|
+
|
|
43
|
+
kmer = KmerFullAlphabetDescriptor(k=2)
|
|
44
|
+
aaindex = AAIndexDescriptor()
|
|
45
|
+
charge = ChargeDescriptor()
|
|
46
|
+
|
|
47
|
+
kmer_features = kmer.compute(["ACDEFGHIK"])
|
|
48
|
+
aaindex_features = aaindex.compute(["ACDEFGHIK"])
|
|
49
|
+
charge_features = charge.compute(["ACDEFGHIK"])
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## CLI
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
roxy --help
|
|
56
|
+
roxy --version
|
|
57
|
+
|
|
58
|
+
# List and inspect descriptors
|
|
59
|
+
roxy list
|
|
60
|
+
roxy list --family composition
|
|
61
|
+
roxy describe aac
|
|
62
|
+
|
|
63
|
+
# Compute descriptors from FASTA, CSV, or Parquet input
|
|
64
|
+
roxy compute sequences.fasta -d aac -d charge -o features.csv
|
|
65
|
+
roxy compute sequences.fasta -f composition -o composition.parquet
|
|
66
|
+
roxy compute sequences.csv -d aac --seq-col sequence --id-col id -o features.csv
|
|
67
|
+
roxy compute sequences.fasta --all -o all_features.parquet
|
|
68
|
+
|
|
69
|
+
# Generate and use a YAML config with descriptor parameters
|
|
70
|
+
roxy init-config -d aac -d charge -o roxy.yaml
|
|
71
|
+
roxy init-config -f composition -o composition.yaml
|
|
72
|
+
roxy init-config --all -o all_descriptors.yaml
|
|
73
|
+
roxy compute sequences.fasta --config roxy.yaml -o configured_features.csv
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`roxy compute` requires exactly one descriptor selector: `--config`, `--all`,
|
|
77
|
+
`--descriptor/-d`, or `--family/-f`. CSV and Parquet inputs use `sequence` as
|
|
78
|
+
the default sequence column; pass `--seq-col` and `--id-col` when needed.
|
|
79
|
+
|
|
80
|
+
## Examples
|
|
81
|
+
|
|
82
|
+
The repository ships a few plain Python scripts under [`examples/`](examples):
|
|
83
|
+
|
|
84
|
+
- `examples/basic_api.py` for direct descriptor use from Python
|
|
85
|
+
- `examples/configured_descriptors.py` for parameterized descriptor instances
|
|
86
|
+
- `examples/cli_roundtrip.py` for an end-to-end CLI config and compute flow
|
|
87
|
+
|
|
88
|
+
Run them with:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
bash examples/run_ci_examples.sh
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Descriptor Families
|
|
95
|
+
|
|
96
|
+
Registry keys are the names used by `roxy compute -d`, config files, and output
|
|
97
|
+
column prefixes.
|
|
98
|
+
|
|
99
|
+
| Family | Descriptor keys |
|
|
100
|
+
|-----------------|---------------------------------------------------------------------------------------|
|
|
101
|
+
| aaindex | `aaindex` |
|
|
102
|
+
| autocorrelation | `autocorrelation` |
|
|
103
|
+
| complexity | `entropy_complexity`, `local_repetition`, `run_blockiness` |
|
|
104
|
+
| composition | `aac`, `compositional_bias`, `dpc`, `grouped`, `kmer_full_alphabet` |
|
|
105
|
+
| ctd | `ctd_classic`, `distribution` |
|
|
106
|
+
| hybrid | `family_summary` |
|
|
107
|
+
| motif | `functional_residue_content`, `pattern`, `spacing`, `user_regex` |
|
|
108
|
+
| physicochemical | `charge`, `global_basic`, `hydrophobicity`, `order_disorder`, `structural_propensity` |
|
|
109
|
+
| positional | `normalized`, `sliding_window`, `terminal` |
|
|
110
|
+
| pseudo | `pseaac`, `qso`, `sequence_order` |
|
|
111
|
+
|
|
112
|
+
## Development
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
uv sync
|
|
116
|
+
uv run pytest -q
|
|
117
|
+
uv run task lint
|
|
118
|
+
uv run roxy --help
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Related Projects
|
|
122
|
+
|
|
123
|
+
- [Sylphy](https://github.com/kren-ai-lab/sylphy) — sequence encoders and pretrained model embeddings
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Basic Python API example for Roxy."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from roxy import DESCRIPTOR_REGISTRY
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main() -> None:
|
|
9
|
+
"""Compute a simple descriptor block from Python."""
|
|
10
|
+
sequences = [
|
|
11
|
+
"MKWVTFISLLFLFSSAYSRGVFRR",
|
|
12
|
+
"GAVLKVLTTGLPALISWIKRKRQQ",
|
|
13
|
+
"DDDEEEGGGSSSNNNQQQ",
|
|
14
|
+
]
|
|
15
|
+
ids = ["albumin_like", "signal_peptide_like", "acidic_low_complexity"]
|
|
16
|
+
|
|
17
|
+
descriptor = DESCRIPTOR_REGISTRY["aac"]()
|
|
18
|
+
features = descriptor.compute(sequences, ids=ids)
|
|
19
|
+
|
|
20
|
+
assert features.height == 3
|
|
21
|
+
assert "id" in features.columns
|
|
22
|
+
assert "aac_length" in features.columns
|
|
23
|
+
assert "aac_freq_A" in features.columns
|
|
24
|
+
|
|
25
|
+
print("basic_api.py")
|
|
26
|
+
print(features.select(["id", "aac_length", "aac_freq_A", "aac_freq_K"]))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == "__main__":
|
|
30
|
+
main()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""CLI example that writes a config and computes features from FASTA."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
import tempfile
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import polars as pl
|
|
10
|
+
|
|
11
|
+
from roxy import read_fasta
|
|
12
|
+
|
|
13
|
+
FASTA_TEXT = """>seq1
|
|
14
|
+
MKWVTFISLLFLFSSAYSRGVFRR
|
|
15
|
+
>seq2
|
|
16
|
+
GAVLKVLTTGLPALISWIKRKRQQ
|
|
17
|
+
>seq3
|
|
18
|
+
DDDEEEGGGSSSNNNQQQ
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _run(*args: str, cwd: Path) -> subprocess.CompletedProcess[str]:
|
|
23
|
+
return subprocess.run(
|
|
24
|
+
args,
|
|
25
|
+
cwd=cwd,
|
|
26
|
+
check=True,
|
|
27
|
+
capture_output=True,
|
|
28
|
+
text=True,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def main() -> None:
|
|
33
|
+
"""Exercise `roxy init-config` and `roxy compute` end to end."""
|
|
34
|
+
repo_root = Path(__file__).resolve().parents[1]
|
|
35
|
+
|
|
36
|
+
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
37
|
+
tmp_path = Path(tmp_dir)
|
|
38
|
+
fasta_path = tmp_path / "toy_sequences.fasta"
|
|
39
|
+
config_path = tmp_path / "toy_config.yaml"
|
|
40
|
+
output_path = tmp_path / "toy_features.csv"
|
|
41
|
+
|
|
42
|
+
fasta_path.write_text(FASTA_TEXT, encoding="utf-8")
|
|
43
|
+
|
|
44
|
+
_run(
|
|
45
|
+
"uv",
|
|
46
|
+
"run",
|
|
47
|
+
"roxy",
|
|
48
|
+
"init-config",
|
|
49
|
+
"-d",
|
|
50
|
+
"aac",
|
|
51
|
+
"-d",
|
|
52
|
+
"charge",
|
|
53
|
+
"-o",
|
|
54
|
+
str(config_path),
|
|
55
|
+
cwd=repo_root,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
config_text = config_path.read_text(encoding="utf-8")
|
|
59
|
+
config_text = config_text.replace("include_counts: true", "include_counts: false")
|
|
60
|
+
config_path.write_text(config_text, encoding="utf-8")
|
|
61
|
+
|
|
62
|
+
_run(
|
|
63
|
+
"uv",
|
|
64
|
+
"run",
|
|
65
|
+
"roxy",
|
|
66
|
+
"compute",
|
|
67
|
+
str(fasta_path),
|
|
68
|
+
"--config",
|
|
69
|
+
str(config_path),
|
|
70
|
+
"-o",
|
|
71
|
+
str(output_path),
|
|
72
|
+
"--no-progress",
|
|
73
|
+
cwd=repo_root,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
records = read_fasta(fasta_path)
|
|
77
|
+
df = pl.read_csv(output_path)
|
|
78
|
+
|
|
79
|
+
assert len(records) == 3
|
|
80
|
+
assert df.height == 3
|
|
81
|
+
assert "length" in df.columns
|
|
82
|
+
assert "aac_freq_A" in df.columns
|
|
83
|
+
assert "aac_count_A" not in df.columns
|
|
84
|
+
assert "charge_net_charge_ph5p0" in df.columns
|
|
85
|
+
|
|
86
|
+
print("cli_roundtrip.py")
|
|
87
|
+
print(df.select(["id", "length", "aac_freq_A", "charge_net_charge_ph5p0"]))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if __name__ == "__main__":
|
|
91
|
+
main()
|