From 9bfcaffb1be9e4162929b5511353abbe0f68eccb Mon Sep 17 00:00:00 2001 From: Tang Ziya Date: Fri, 23 Feb 2024 17:28:12 +0800 Subject: [PATCH] RENAME: argweavers 1. Rename the module to resolve several issues 2. Drop the bedops sort-bed. It sort the BED file in alphabet order on iter number instead of numerical --- .github/workflows/documentation.yml | 4 ++-- .gitignore | 2 +- README+s.md | 3 +-- argweaver/__init__.py | 10 ---------- argweavers.py | 9 --------- argweavers/__init__.py | 10 ++++++++++ argweaver/s.pyi => argweavers/argweavers.pyi | 0 {argweaver => argweavers}/bin.py | 0 {argweaver => argweavers}/io/__init__.py | 0 {argweaver => argweavers}/io/bed.py | 2 +- {argweaver => argweavers}/plot.py | 0 {argweaver => argweavers}/r.py | 2 +- {argweaver => argweavers}/scripts/smc2bed.py | 2 +- .../scripts/smc2bed_all.py | 16 ++++++++++------ {argweaver => argweavers}/utils.py | 0 docs/conf.py | 4 ++-- docs/installation.md | 11 +++++------ pyproject.toml | 17 ++++++++++------- src/lib.rs | 2 +- tests/conftest.py | 2 +- tests/test_basic.py | 4 ++-- tests/test_bin.py | 2 +- tests/test_io.py | 2 +- tests/test_plot.py | 2 +- tests/test_r.py | 2 +- tests/test_scripts.py | 4 ++-- tests/test_sites.py | 2 +- tests/test_utils.py | 2 +- 28 files changed, 56 insertions(+), 60 deletions(-) delete mode 100644 argweaver/__init__.py delete mode 100644 argweavers.py create mode 100644 argweavers/__init__.py rename argweaver/s.pyi => argweavers/argweavers.pyi (100%) rename {argweaver => argweavers}/bin.py (100%) rename {argweaver => argweavers}/io/__init__.py (100%) rename {argweaver => argweavers}/io/bed.py (96%) rename {argweaver => argweavers}/plot.py (100%) rename {argweaver => argweavers}/r.py (97%) rename {argweaver => argweavers}/scripts/smc2bed.py (93%) rename {argweaver => argweavers}/scripts/smc2bed_all.py (89%) rename {argweaver => argweavers}/utils.py (100%) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 47bb379f..878c0ba3 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -4,11 +4,11 @@ on: push: paths: - 'docs/**' - - 'argweaver/**' + - 'argweavers/**' pull_request: paths: - 'docs/**' - - 'argweaver/**' + - 'argweavers/**' workflow_dispatch: permissions: diff --git a/.gitignore b/.gitignore index edbffb8d..0069789f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,7 @@ __pycache__/ /requirements-dev.lock # maturin -/argweaver/*.so +/argweavers/*.so # test coverage /.coverage diff --git a/README+s.md b/README+s.md index d9f8358d..a682f7b0 100644 --- a/README+s.md +++ b/README+s.md @@ -5,8 +5,7 @@ 1. [rustup](https://rustup.rs/) 2. [CMake](https://cmake.org/) with any modern C++ compiler 3. [rye](https://rye-up.com) or [maturin](https://maturin.rs) for Python binding -4. [samtools](http://www.htslib.org/) and - [bedops](https://bedops.readthedocs.io/en/latest/) for `smc2bed-all` +4. [samtools](http://www.htslib.org/) for `smc2bed-all` ## Install diff --git a/argweaver/__init__.py b/argweaver/__init__.py deleted file mode 100644 index 171b3abd..00000000 --- a/argweaver/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from importlib.metadata import version - -from . import s -from .s import * # noqa: F403 - -__doc__ = s.__doc__ -__version__ = version("argweavers") - -if hasattr(s, "__all__"): - __all__ = s.__all__ diff --git a/argweavers.py b/argweavers.py deleted file mode 100644 index 028f52d2..00000000 --- a/argweavers.py +++ /dev/null @@ -1,9 +0,0 @@ -from importlib.metadata import version - -import argweaver.s - -__doc__ = argweaver.s.__doc__ -__version__ = version(__file__) - -if hasattr(argweaver.s, "__all__"): - __all__ = argweaver.s.__all__ diff --git a/argweavers/__init__.py b/argweavers/__init__.py new file mode 100644 index 00000000..65456d63 --- /dev/null +++ b/argweavers/__init__.py @@ -0,0 +1,10 @@ +from importlib.metadata import version + +from . import argweavers # make ruff happy +from .argweavers import * # noqa: F403 + +__doc__ = argweavers.__doc__ +__version__ = version(__package__) + +if hasattr(argweavers, "__all__"): + __all__ = argweavers.__all__ diff --git a/argweaver/s.pyi b/argweavers/argweavers.pyi similarity index 100% rename from argweaver/s.pyi rename to argweavers/argweavers.pyi diff --git a/argweaver/bin.py b/argweavers/bin.py similarity index 100% rename from argweaver/bin.py rename to argweavers/bin.py diff --git a/argweaver/io/__init__.py b/argweavers/io/__init__.py similarity index 100% rename from argweaver/io/__init__.py rename to argweavers/io/__init__.py diff --git a/argweaver/io/bed.py b/argweavers/io/bed.py similarity index 96% rename from argweaver/io/bed.py rename to argweavers/io/bed.py index 67ef4d52..5483c538 100644 --- a/argweaver/io/bed.py +++ b/argweavers/io/bed.py @@ -3,7 +3,7 @@ import pandas as pd -from argweaver.utils import parse_region +from argweavers.utils import parse_region __all__ = ["read_bed"] diff --git a/argweaver/plot.py b/argweavers/plot.py similarity index 100% rename from argweaver/plot.py rename to argweavers/plot.py diff --git a/argweaver/r.py b/argweavers/r.py similarity index 97% rename from argweaver/r.py rename to argweavers/r.py index 5bb3a305..c16ecdfc 100644 --- a/argweaver/r.py +++ b/argweavers/r.py @@ -5,7 +5,7 @@ from rpy2.robjects import pandas2ri from rpy2.robjects.packages import importr -from argweaver.utils import parse_region +from argweavers.utils import parse_region if typing.TYPE_CHECKING: from os import PathLike diff --git a/argweaver/scripts/smc2bed.py b/argweavers/scripts/smc2bed.py similarity index 93% rename from argweaver/scripts/smc2bed.py rename to argweavers/scripts/smc2bed.py index 5e43529f..e22ec40e 100644 --- a/argweaver/scripts/smc2bed.py +++ b/argweavers/scripts/smc2bed.py @@ -2,7 +2,7 @@ import sys from contextlib import redirect_stdout -from argweaver.s import smc2bed +from argweavers import smc2bed def main(args=None, capture_output=False): diff --git a/argweaver/scripts/smc2bed_all.py b/argweavers/scripts/smc2bed_all.py similarity index 89% rename from argweaver/scripts/smc2bed_all.py rename to argweavers/scripts/smc2bed_all.py index be44d9c8..6216dfa7 100644 --- a/argweaver/scripts/smc2bed_all.py +++ b/argweavers/scripts/smc2bed_all.py @@ -1,10 +1,13 @@ import argparse import os import sys +from io import BytesIO from itertools import count -from argweaver.bin import require_executable -from argweaver.scripts.smc2bed import main as smc2bed +import pandas as pd + +from argweavers.bin import require_executable +from argweavers.scripts.smc2bed import main as smc2bed class MetavarFormatter(argparse.HelpFormatter): @@ -16,7 +19,6 @@ def _get_default_metavar_for_positional(self, action): def main(argv=None): - sort_bed = require_executable("sort-bed", "It is included in `bedops`") bgzip = require_executable("bgzip", "It is included in `samtools`") tabix = require_executable("tabix", "It is included in `samtools`") parser = argparse.ArgumentParser( @@ -93,14 +95,16 @@ def main(argv=None): sys.stderr.write(f"ended at sample={num}\n") break sys.stderr.write(f"{num} {file}\n") - print(os.stat(file).st_size) out += smc2bed( ["--sample", str(num), *regionarg, file], capture_output=True, ) - print(len(out)) num += interval - out = sort_bed(["-"], input=out, capture_output=True).stdout + bed = pd.read_table( + BytesIO(out), header=None, names=["chrom", "start", "end", "iter", "tree"] + ) + bed = bed.sort_values(["chrom", "start", "end", "iter"]) + out = bed.to_csv(index=False, header=False, sep="\t").encode("utf-8") with open(f"{baseout}.bed.gz", "wb") as f: bgzip(["-"], input=out, stdout=f) tabix(["-p", "bed", f"{baseout}.bed.gz"]) diff --git a/argweaver/utils.py b/argweavers/utils.py similarity index 100% rename from argweaver/utils.py rename to argweavers/utils.py diff --git a/docs/conf.py b/docs/conf.py index 514d1cb2..341a8330 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,10 +21,10 @@ ] autodoc2_module_all_regexes = [ - r"argweaver\..*", + r"argweavers\..*", ] autodoc2_packages = [ - "../argweaver", + "../argweavers", ] autodoc2_render_plugin = "myst" graphviz_output_format = "svg" diff --git a/docs/installation.md b/docs/installation.md index 0f389071..de2454d7 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -3,19 +3,18 @@ ## Pre-requisites 1. [rustup](https://rustup.rs/) -2. (Optional) [samtools](http://www.htslib.org/) and - [bedops](https://bedops.readthedocs.io/en/latest/) for executing `smc2bed-all` +2. (Optional) [samtools](http://www.htslib.org/) for executing `smc2bed-all` 3. (Optional) R for plotting ```bash # Install rustup curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -# If you are using macOS, you can install samtools and bedops using homebrew -brew install samtools bedops -# Otherwise, install miniconda for samtools and bedops +# If you are using macOS, you can install samtools using homebrew +brew install samtools +# Otherwise, install miniconda for samtools wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh -conda install -c bioconda samtools bedops +conda install -c bioconda samtools # Install R sudo apt-get install r-base # Or diff --git a/pyproject.toml b/pyproject.toml index 7656d6b7..28a090f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,11 +38,11 @@ dependencies = [ ] [project.scripts] -arg-likelihood = "argweaver.bin:arg_likelihood" -arg-sample = "argweaver.bin:arg_sample" -arg-summarize = "argweaver.bin:arg_summarize" -smc2bed = "argweaver.scripts.smc2bed:main" -smc2bed-all = "argweaver.scripts.smc2bed_all:main" +arg-likelihood = "argweavers.bin:arg_likelihood" +arg-sample = "argweavers.bin:arg_sample" +arg-summarize = "argweavers.bin:arg_summarize" +smc2bed = "argweavers.scripts.smc2bed:main" +smc2bed-all = "argweavers.scripts.smc2bed_all:main" [tool.rye] dev-dependencies = [ @@ -55,6 +55,7 @@ dev-dependencies = [ "myst-parser>=2.0.0", "sphinx-autodoc2>=0.5.0", "ipykernel>=6.29.2", + "cibuildwheel>=2.16.5", ] [tool.rye.scripts] cov-report = { chain = ["htmlcov", "htmlcov-serve"] } @@ -63,7 +64,6 @@ htmlcov-serve = "python -m http.server --directory htmlcov" [tool.maturin] features = ["extension-module"] -module-name = "argweaver.s" include = ["bin/*"] [[tool.mypy.overrides]] @@ -78,7 +78,7 @@ target-version = "py38" [tool.pytest.ini_options] minversion = "7.0" -addopts = ["--cov=argweaver"] +addopts = ["--cov=argweavers"] [tool.coverage.report] exclude_also = [ @@ -86,3 +86,6 @@ exclude_also = [ "if __name__ == \"__main__\"", "class \\w+\\((argparse\\.)?HelpFormatter\\)", ] + +[tool.cibuildwheel] +skip = "pp*" diff --git a/src/lib.rs b/src/lib.rs index 94181221..e1db09c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,7 +54,7 @@ fn smc2bed(args: Option>) -> PyResult<()> { #[cfg(feature = "extension-module")] /// Ancestral recombination graph sampling method #[pymodule] -fn s(_py: Python, m: &PyModule) -> PyResult<()> { +fn argweavers(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_function(wrap_pyfunction!(sites::read_sites, m)?)?; m.add_function(wrap_pyfunction!(smc2bed, m)?)?; diff --git a/tests/conftest.py b/tests/conftest.py index f5dc11df..8ec048cb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,7 +3,7 @@ import pytest -from argweaver.scripts.smc2bed_all import main as smc2bed_all +from argweavers.scripts.smc2bed_all import main as smc2bed_all examples_dir = pathlib.Path(__file__).parent.parent / "examples" diff --git a/tests/test_basic.py b/tests/test_basic.py index a77a3acf..0acc6a6c 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -1,5 +1,5 @@ -import argweaver +import argweavers def test_basic(): - assert argweaver.__version__ == "0.9.0" + assert argweavers.__version__ == "0.9.0" diff --git a/tests/test_bin.py b/tests/test_bin.py index cd73ce5e..bd34203b 100644 --- a/tests/test_bin.py +++ b/tests/test_bin.py @@ -1,6 +1,6 @@ import pytest -from argweaver.bin import require_executable +from argweavers.bin import require_executable def test_require_executable(): diff --git a/tests/test_io.py b/tests/test_io.py index 38a5d96a..3f6b7162 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -1,4 +1,4 @@ -from argweaver.io import read_bed, subset_bed +from argweavers.io import read_bed, subset_bed def test_read_bed(bedfile): diff --git a/tests/test_plot.py b/tests/test_plot.py index e4ea5ed0..28289a3b 100644 --- a/tests/test_plot.py +++ b/tests/test_plot.py @@ -1,7 +1,7 @@ import matplotlib.pyplot as plt from matplotlib.testing.decorators import image_comparison -from argweaver.plot import plot_tree +from argweavers.plot import plot_tree @image_comparison(baseline_images=["test_plot_tree"], extensions=["png"]) diff --git a/tests/test_r.py b/tests/test_r.py index 3ef723bf..da6672f0 100644 --- a/tests/test_r.py +++ b/tests/test_r.py @@ -1,6 +1,6 @@ import pytest -from argweaver.r import plotTreesFromBed +from argweavers.r import plotTreesFromBed def test_plot_trees(bedfile): diff --git a/tests/test_scripts.py b/tests/test_scripts.py index c0129026..7073faed 100644 --- a/tests/test_scripts.py +++ b/tests/test_scripts.py @@ -1,6 +1,6 @@ import hashlib -from argweaver.scripts.smc2bed import main as smc2bed +from argweavers.scripts.smc2bed import main as smc2bed def sha256sum(path): @@ -18,5 +18,5 @@ def test_smc2bed(sim1_sample): def test_smc2bed_all(bedfile): - sha256 = "577951a303869a2ab3aaf99e500ff29ce5613c27ac1a7cbef7dbfa63524136c3" + sha256 = "94012cc3ecadddaf19f823ec361a72ac9b8073fe33dc75c1f731498c789d7023" assert sha256sum(bedfile) == sha256 diff --git a/tests/test_sites.py b/tests/test_sites.py index 62c55e2e..bdda2b22 100644 --- a/tests/test_sites.py +++ b/tests/test_sites.py @@ -1,4 +1,4 @@ -from argweaver import read_sites +from argweavers import read_sites def test_read_sites(): diff --git a/tests/test_utils.py b/tests/test_utils.py index fbf76437..6ca76e8f 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,6 +1,6 @@ import pytest -from argweaver.utils import parse_region +from argweavers.utils import parse_region def test_parse_region():