rolypoly-tk 0.7.2__tar.gz → 0.7.4__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.
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/PKG-INFO +32 -26
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/README.md +29 -23
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/pyproject.toml +14 -2
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/__init__.py +1 -1
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/annotation/annotate.py +9 -1
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/annotation/annotate_RNA.py +9 -4
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/assembly/assemble.py +10 -1
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/assembly/filter_contigs.py +7 -1
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/bining/binit.py +6 -1
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/bining/correlate.py +8 -1
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/identify_virus/search_viruses.py +7 -1
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/misc/fastx_stats.py +4 -2
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/reads/filter_reads.py +8 -2
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/reads/shrink_reads.py +7 -5
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/rolypoly.py +4 -3
- rolypoly_tk-0.7.2/rolypoly/commands/host/classify.py +0 -47
- rolypoly_tk-0.7.2/rolypoly/commands/misc/quick_taxonomy.py +0 -372
- rolypoly_tk-0.7.2/rolypoly/utils/logging/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/.gitignore +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/LICENSE +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/annotation/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/annotation/annotate_prot.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/annotation/resolve_hits.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/assembly/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/assembly/co_assembly.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/assembly/extend.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/assembly/refinement.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/bining/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/bining/cluster.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/bining/termini.py +0 -0
- {rolypoly_tk-0.7.2/rolypoly/commands/host → rolypoly_tk-0.7.4/rolypoly/commands/identify_virus}/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/identify_virus/marker_search.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/identify_virus/rdrp_motif_search.py +0 -0
- {rolypoly_tk-0.7.2/rolypoly/commands/identify_virus → rolypoly_tk-0.7.4/rolypoly/commands/misc}/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/misc/add_command.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/misc/build_data.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/misc/end_2_end.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/misc/fastx_calc.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/misc/fetch_sra_fastq.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/misc/get_external_data.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/misc/rename_seqs.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/reads/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/reads/mask_dna.py +0 -0
- {rolypoly_tk-0.7.2/rolypoly/commands/misc → rolypoly_tk-0.7.4/rolypoly/commands/virotype}/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/virotype/draw_rdrp_msa.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/virotype/predict_characteristics.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/virotype/summarize.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/virotype/visualize.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/rpconfig.json +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/__init__.py +0 -0
- {rolypoly_tk-0.7.2/rolypoly/commands/virotype → rolypoly_tk-0.7.4/rolypoly/utils/benchmarking}/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/benchmarking/get_data.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/alignments.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/clustering.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/dotplot.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/genome_fetch.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/interval_ops.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/library_detection.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/polars_fastx.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/sequences.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/translation.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/bio/trees.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/lazy_group.py +0 -0
- {rolypoly_tk-0.7.2/rolypoly/utils/benchmarking → rolypoly_tk-0.7.4/rolypoly/utils/logging}/__init__.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/logging/all_used_tools_dbs_citations.json +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/logging/citation_reminder.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/logging/config.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/logging/loggit.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/logging/output_tracker.py +0 -0
- {rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/various.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rolypoly_tk
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.4
|
|
4
4
|
Summary: RNA virus analysis toolkit
|
|
5
5
|
Project-URL: Source, https://github.com/UriNeri/rolypoly
|
|
6
|
-
Project-URL: Documentation, https://
|
|
6
|
+
Project-URL: Documentation, https://urineri.github.io/rolypoly/
|
|
7
7
|
Project-URL: pypi, https://pypi.org/project/rolypoly-tk/
|
|
8
8
|
Author: Lander De Coninck
|
|
9
9
|
Author-email: Uri Neri <uneri@lbl.gov>, Dimitris Karapliafis <dimitris.karapliafis@atwur.nl>, Brian Bushnell <bbushnell@lbl.gov>, Frederik Schulz <fschulz@lbl.gov>, Antonio Camargo <antoniop.camargo@lbl.gov>, Andrei Stecca Steindorff <andreiss@jgi.doe.gov>, Clement Coclet <cclement@jgi.doe.gov>, David Parker <dparker@carnegiescience.edu>, Simon Roux <sroux@lbl.gov>
|
|
@@ -682,7 +682,7 @@ License: GNU GENERAL PUBLIC LICENSE
|
|
|
682
682
|
Public License instead of this License. But first, please read
|
|
683
683
|
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
684
684
|
License-File: LICENSE
|
|
685
|
-
Requires-Python:
|
|
685
|
+
Requires-Python: <3.14,>=3.10
|
|
686
686
|
Requires-Dist: bbmapy<0.0.58,>=0.0.56
|
|
687
687
|
Requires-Dist: genomicranges<0.8,>=0.7.3
|
|
688
688
|
Requires-Dist: intervaltree<4,>=3.1.0
|
|
@@ -708,16 +708,18 @@ Requires-Dist: viennarna<3,>=2.7.0
|
|
|
708
708
|
Requires-Dist: xxhash<4,>=3.6.0
|
|
709
709
|
Description-Content-Type: text/markdown
|
|
710
710
|
|
|
711
|
-

|
|
712
712
|
|
|
713
713
|
# RolyPoly
|
|
714
714
|
|
|
715
|
+
[](https://pypi.org/project/rolypoly-tk/) [](https://pypi.org/project/rolypoly-tk/) [](https://pepy.tech/projects/rolypoly-tk) [](LICENSE) [](https://urineri.github.io/rolypoly/)
|
|
716
|
+
|
|
715
717
|
RolyPoly is an RNA virus analysis toolkit, meant to be a "swiss-army knife" for RNA virus discovery and characterization by including a variety of commands, wrappers, parsers, automations, and some "quality of life" features for any many of a virus investigation process (from raw read processing to genome annotation). While it includes an "end-2-end" command that employs an entire pipeline, the main goals of rolypoly are:
|
|
716
718
|
- Help non-computational researchers take a deep dive into their data without compromising on using tools that are non-techie friendly.
|
|
717
719
|
- Help (software) developers of virus analysis pipeline "plug" holes missing from their framework, by using specific RolyPoly commands to add features to their existing code base.
|
|
718
720
|
|
|
719
721
|
## Note - Rolypoly is still under development (contributions welcome!)
|
|
720
|
-
RolyPoly is an open, still in progress project - I aim to summarise the main functionality into a manuscript ~
|
|
722
|
+
RolyPoly is an open, still in progress project - I aim to summarise the main functionality into a manuscript ~mid 2026. Pull requests and contributions are welcome and will be considered (see [CONTRIBUTING.md](CONTRIBUTING.md)).
|
|
721
723
|
This also means that there are bugs, verbose logging even for non debug mode, and some place holders and TODOs here and there.
|
|
722
724
|
|
|
723
725
|
## Installation
|
|
@@ -726,23 +728,27 @@ This also means that there are bugs, verbose logging even for non debug mode, an
|
|
|
726
728
|
**Recommended for most users** who want a "just works" solution and primarily intend to use rolypoly as a CLI tool in an independent environment.
|
|
727
729
|
|
|
728
730
|
We hope to have rolypoly available from bioconda in the near future.
|
|
729
|
-
In the meantime, it can be installed with the [`quick_setup.sh`](https://
|
|
731
|
+
In the meantime, it can be installed with the [`quick_setup.sh`](https://raw.githubusercontent.com/UriNeri/rolypoly/main/src/setup/quick_setup.sh) script, which is Conda/Mamba-based (uses `mamba` or `micromamba`) and also fetches the pre-generated data rolypoly requires.
|
|
730
732
|
|
|
731
733
|
```bash
|
|
732
|
-
curl -O https://
|
|
734
|
+
curl -O https://raw.githubusercontent.com/UriNeri/rolypoly/main/src/setup/quick_setup.sh && \
|
|
733
735
|
bash quick_setup.sh
|
|
734
736
|
```
|
|
735
737
|
|
|
736
738
|
#### Quick Setup - Additional Options
|
|
737
|
-
You can specify custom paths for the code, databases, and
|
|
739
|
+
You can specify custom paths for the code, databases, and Conda/Mamba environment location (this is also how you "name" the environment by choosing its path):
|
|
738
740
|
```bash
|
|
739
741
|
bash quick_setup.sh /path/to/conda/env /path/to/install/rolypoly_code /path/to/store/databases /path/to/logfile
|
|
740
742
|
```
|
|
743
|
+
Example with an explicit environment path:
|
|
744
|
+
```bash
|
|
745
|
+
bash quick_setup.sh "$HOME/mamba_envs/rolypoly"
|
|
746
|
+
```
|
|
741
747
|
By default if no positional arguments are supplied, rolypoly is installed into the session current folder (path the quick_setup.sh is called from):
|
|
742
748
|
- database in `./rolypoly/data/`
|
|
743
749
|
- code in `./rolypoly/code/ `
|
|
744
750
|
- conda environment in `./rolypoly/env/`
|
|
745
|
-
- log file in `./RolyPoly_quick_setup.log`
|
|
751
|
+
- log file in `./rolypoly/RolyPoly_quick_setup.log`
|
|
746
752
|
|
|
747
753
|
|
|
748
754
|
|
|
@@ -754,7 +760,7 @@ By default if no positional arguments are supplied, rolypoly is installed into t
|
|
|
754
760
|
curl -fsSL https://pixi.sh/install.sh | bash
|
|
755
761
|
|
|
756
762
|
# Clone the repository
|
|
757
|
-
git clone https://
|
|
763
|
+
git clone https://github.com/UriNeri/rolypoly.git
|
|
758
764
|
cd rolypoly
|
|
759
765
|
|
|
760
766
|
# Install for specific functionality (examples):
|
|
@@ -794,11 +800,11 @@ Legend:
|
|
|
794
800
|
|
|
795
801
|
#### Raw-Reads
|
|
796
802
|
- ✅ [`filter-reads`](https://urineri.github.io/rolypoly/commands/read_processing) — Host/rRNA/adapters/artifact filtering and QC (bbmap, falco, etc.)
|
|
797
|
-
- ✅ [`shrink-reads`](https://urineri.github.io/rolypoly/commands/
|
|
798
|
-
- ✅ [`mask-dna`](https://urineri.github.io/rolypoly/commands/
|
|
803
|
+
- ✅ [`shrink-reads`](https://urineri.github.io/rolypoly/commands/read_processing) — Downsample or subsample reads. Useful for testing or normalizing coverage across samples.
|
|
804
|
+
- ✅ [`mask-dna`](https://urineri.github.io/rolypoly/commands/read_processing) — Mask DNA regions in RNA-seq reads (bbmap, seqkit). Useful for avoiding mis-filtering of RNA virus reads in because of potential matches to EVEs.
|
|
799
805
|
|
|
800
806
|
#### Annotation
|
|
801
|
-
- ✅ [`annotate`](https://urineri.github.io/rolypoly/commands/annotate) — Genome feature annotation (wraps the rna and prot commands)
|
|
807
|
+
- ✅ [`annotate`](https://urineri.github.io/rolypoly/commands/annotate_rna/#annotate-rna) — Genome feature annotation (wraps the rna and prot commands)
|
|
802
808
|
- ✅ [`annotate-rna`](https://urineri.github.io/rolypoly/commands/annotate_rna) — RNA secondary structure labelling and ribozyme detection (Infernal, ViennaRNA/linearfold, cmsearch on Rfam...)
|
|
803
809
|
- 🧪 [`annotate-prot`](https://urineri.github.io/rolypoly/commands/annotate_prot) — Gene calling and Protein domain annotation and functional prediction (HMMER, Pfam, custom).
|
|
804
810
|
|
|
@@ -809,22 +815,22 @@ Legend:
|
|
|
809
815
|
#### RNA Virus Identification
|
|
810
816
|
- ✅ [`marker-search`](https://urineri.github.io/rolypoly/commands/marker_search) — Search for viral markers (mainly RdRps, genomad VVs, or user-provided), using profile-based methods (HMMER / MMseqs2).
|
|
811
817
|
- ✅ [`virus-mapping`](https://urineri.github.io/rolypoly/commands/search_viruses) — Map and identify viruses using nucleic acid search (MMseqs2).
|
|
812
|
-
- ✅ `rdrp-motif-search` — Search RdRp motifs (A/B/C/D) in nucleotide or amino acid sequences.
|
|
818
|
+
- ✅ [`rdrp-motif-search`](https://urineri.github.io/rolypoly/commands/rdrp_motif_search) — Search RdRp motifs (A/B/C/D) in nucleotide or amino acid sequences.
|
|
813
819
|
|
|
814
820
|
#### Bining / Clustering
|
|
815
|
-
- 🧪 `cluster` — Average Nucleic identity (ANI) based contig
|
|
816
|
-
- 🧪 `extend` — Extend sequences by pile-up/assembly. Useful for combining assemblies of with low abundance viruses, or those with high microdiversity, at the cost of worse strain/sub-species resolution (i.e. can condense to a
|
|
817
|
-
- 🧪 `termini` — Shared termini grouping and motif reporting. Writes assignments + groups tables (TSV/CSV/Parquet/JSONL) and motif FASTA by default.
|
|
818
|
-
- 🧪 `correlate` —
|
|
819
|
-
- 🤔 `binit` — Combines the above commands with sample information and genome attributes (e.g. require a shared termini AND protein complementarity, like CP + RdRp). See [notebooks/Exprimental/partiti_usecase/partiti_segment_workflow_experimental.ipynb](notebooks/Exprimental/partiti_usecase/partiti_segment_workflow_experimental.ipynb) for candidate workflow.
|
|
821
|
+
- 🧪 [`cluster`](https://urineri.github.io/rolypoly/commands/cluster) — Average Nucleic identity (ANI) based contig grouping. Supports several common backends and methods.
|
|
822
|
+
- 🧪 [`extend`](https://urineri.github.io/rolypoly/commands/extend) — Extend sequences by pile-up/assembly. Useful for combining assemblies of with low abundance viruses, or those with high microdiversity, at the cost of worse strain/sub-species resolution (i.e. can condense to a consensus).
|
|
823
|
+
- 🧪 [`termini`](https://urineri.github.io/rolypoly/commands/binning_termini) — Shared termini grouping and motif reporting. Writes assignments + groups tables (TSV/CSV/Parquet/JSONL) and motif FASTA by default.
|
|
824
|
+
- 🧪 [`correlate`](https://urineri.github.io/rolypoly/commands/binning_correlate) — Group contigs based on co-occurrence, co-abundance, minimal correlation (Spearman's) of these, or both.
|
|
825
|
+
- 🤔 [`binit`](https://urineri.github.io/rolypoly/commands/binit) — Combines the above commands with sample information and genome attributes (e.g. require a shared termini AND protein complementarity, like CP + RdRp). See [notebooks/Exprimental/partiti_usecase/partiti_segment_workflow_experimental.ipynb](notebooks/Exprimental/partiti_usecase/partiti_segment_workflow_experimental.ipynb) for candidate workflow.
|
|
820
826
|
|
|
821
827
|
#### Miscellaneous
|
|
822
|
-
- ✅ `roll` — Run an end-to-end pipeline (before v0.7.1, named `end2end`).
|
|
823
|
-
- ✅ `fetch-sra` — Download SRA fastq files (from ENA)
|
|
824
|
-
- ✅ `fastx-calc` — Calculate per-sequence metrics (length, GC content, hash, ...)
|
|
825
|
-
- ✅ `fastx-stats` — Calculate (-->aggregate) statistics for sequences (min, max, mean, median, ...) (input is file/s)
|
|
826
|
-
- ✅ `rename-seqs` — Rename sequences (add a prefix, suffix, hash, running number, etc.)
|
|
827
|
-
- 🚧 `quick-taxonomy` — Quick taxonomy assignment. Candidate workflows are [github.com/UriNeri/ictv-mmseqs2-protein-database](https://github.com/UriNeri/ictv-mmseqs2-protein-database) and [github.com/apcamargo/ictv-mmseqs2-protein-database](https://github.com/apcamargo/ictv-mmseqs2-protein-database)
|
|
828
|
+
- ✅ [`roll`](https://urineri.github.io/rolypoly/commands/end_to_end) — Run an end-to-end pipeline (before v0.7.1, named `end2end`).
|
|
829
|
+
- ✅ [`fetch-sra`](https://urineri.github.io/rolypoly/commands/misc) — Download SRA fastq files (from ENA)
|
|
830
|
+
- ✅ [`fastx-calc`](https://urineri.github.io/rolypoly/commands/misc) — Calculate per-sequence metrics (length, GC content, hash, ...)
|
|
831
|
+
- ✅ [`fastx-stats`](https://urineri.github.io/rolypoly/commands/misc) — Calculate (-->aggregate) statistics for sequences (min, max, mean, median, ...) (input is file/s)
|
|
832
|
+
- ✅ [`rename-seqs`](https://urineri.github.io/rolypoly/commands/misc) — Rename sequences (add a prefix, suffix, hash, running number, etc.)
|
|
833
|
+
- 🚧 [`quick-taxonomy`](https://urineri.github.io/rolypoly/commands/misc) — Quick taxonomy assignment. Candidate workflows are [github.com/UriNeri/ictv-mmseqs2-protein-database](https://github.com/UriNeri/ictv-mmseqs2-protein-database) and [github.com/apcamargo/ictv-mmseqs2-protein-database](https://github.com/apcamargo/ictv-mmseqs2-protein-database)
|
|
828
834
|
- 🤔 support for [genotate](https://github.com/deprekate/genotate) for gene prediction.
|
|
829
835
|
- 🤔 Genome refinement / strain de-entalgement / variant calling?
|
|
830
836
|
- 🤔 Virus feature prediction (+/-ssRNA/dsRNA, circular/linear, mono/poly-segmented, capsid type, etc.)
|
|
@@ -835,7 +841,7 @@ If you have suggestions for additional commands or features, or want to implemen
|
|
|
835
841
|
|
|
836
842
|
## Dependencies
|
|
837
843
|
|
|
838
|
-
**📦 Modular Installation Available**: RolyPoly supports both quick setup (one environment with all dependecies for all commands) and modular installation (command-specific environments). The modular approach is particularly useful for software developers who want to integrate specific rolypoly features with minimal dependency conflicts. See the [installation documentation](
|
|
844
|
+
**📦 Modular Installation Available**: RolyPoly supports both quick setup (one environment with all dependecies for all commands) and modular installation (command-specific environments). The modular approach is particularly useful for software developers who want to integrate specific rolypoly features with minimal dependency conflicts. See the [installation documentation](https://urineri.github.io/rolypoly/installation/) for details.
|
|
839
845
|
|
|
840
846
|
Not all 3rd party software is used by all the different commands. RolyPoly includes a "citation reminder" that will try to list all the external software used by a command. The "reminded citations" are pretty printed to console (stdout) and to a logfile. To shut off the terminal citation reminder printing, set `ROLYPOLY_REMIND_CITATIONS` to false in your `rpconfig.json` file.
|
|
841
847
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
# RolyPoly
|
|
4
4
|
|
|
5
|
+
[](https://pypi.org/project/rolypoly-tk/) [](https://pypi.org/project/rolypoly-tk/) [](https://pepy.tech/projects/rolypoly-tk) [](LICENSE) [](https://urineri.github.io/rolypoly/)
|
|
6
|
+
|
|
5
7
|
RolyPoly is an RNA virus analysis toolkit, meant to be a "swiss-army knife" for RNA virus discovery and characterization by including a variety of commands, wrappers, parsers, automations, and some "quality of life" features for any many of a virus investigation process (from raw read processing to genome annotation). While it includes an "end-2-end" command that employs an entire pipeline, the main goals of rolypoly are:
|
|
6
8
|
- Help non-computational researchers take a deep dive into their data without compromising on using tools that are non-techie friendly.
|
|
7
9
|
- Help (software) developers of virus analysis pipeline "plug" holes missing from their framework, by using specific RolyPoly commands to add features to their existing code base.
|
|
8
10
|
|
|
9
11
|
## Note - Rolypoly is still under development (contributions welcome!)
|
|
10
|
-
RolyPoly is an open, still in progress project - I aim to summarise the main functionality into a manuscript ~
|
|
12
|
+
RolyPoly is an open, still in progress project - I aim to summarise the main functionality into a manuscript ~mid 2026. Pull requests and contributions are welcome and will be considered (see [CONTRIBUTING.md](CONTRIBUTING.md)).
|
|
11
13
|
This also means that there are bugs, verbose logging even for non debug mode, and some place holders and TODOs here and there.
|
|
12
14
|
|
|
13
15
|
## Installation
|
|
@@ -16,23 +18,27 @@ This also means that there are bugs, verbose logging even for non debug mode, an
|
|
|
16
18
|
**Recommended for most users** who want a "just works" solution and primarily intend to use rolypoly as a CLI tool in an independent environment.
|
|
17
19
|
|
|
18
20
|
We hope to have rolypoly available from bioconda in the near future.
|
|
19
|
-
In the meantime, it can be installed with the [`quick_setup.sh`](https://
|
|
21
|
+
In the meantime, it can be installed with the [`quick_setup.sh`](https://raw.githubusercontent.com/UriNeri/rolypoly/main/src/setup/quick_setup.sh) script, which is Conda/Mamba-based (uses `mamba` or `micromamba`) and also fetches the pre-generated data rolypoly requires.
|
|
20
22
|
|
|
21
23
|
```bash
|
|
22
|
-
curl -O https://
|
|
24
|
+
curl -O https://raw.githubusercontent.com/UriNeri/rolypoly/main/src/setup/quick_setup.sh && \
|
|
23
25
|
bash quick_setup.sh
|
|
24
26
|
```
|
|
25
27
|
|
|
26
28
|
#### Quick Setup - Additional Options
|
|
27
|
-
You can specify custom paths for the code, databases, and
|
|
29
|
+
You can specify custom paths for the code, databases, and Conda/Mamba environment location (this is also how you "name" the environment by choosing its path):
|
|
28
30
|
```bash
|
|
29
31
|
bash quick_setup.sh /path/to/conda/env /path/to/install/rolypoly_code /path/to/store/databases /path/to/logfile
|
|
30
32
|
```
|
|
33
|
+
Example with an explicit environment path:
|
|
34
|
+
```bash
|
|
35
|
+
bash quick_setup.sh "$HOME/mamba_envs/rolypoly"
|
|
36
|
+
```
|
|
31
37
|
By default if no positional arguments are supplied, rolypoly is installed into the session current folder (path the quick_setup.sh is called from):
|
|
32
38
|
- database in `./rolypoly/data/`
|
|
33
39
|
- code in `./rolypoly/code/ `
|
|
34
40
|
- conda environment in `./rolypoly/env/`
|
|
35
|
-
- log file in `./RolyPoly_quick_setup.log`
|
|
41
|
+
- log file in `./rolypoly/RolyPoly_quick_setup.log`
|
|
36
42
|
|
|
37
43
|
|
|
38
44
|
|
|
@@ -44,7 +50,7 @@ By default if no positional arguments are supplied, rolypoly is installed into t
|
|
|
44
50
|
curl -fsSL https://pixi.sh/install.sh | bash
|
|
45
51
|
|
|
46
52
|
# Clone the repository
|
|
47
|
-
git clone https://
|
|
53
|
+
git clone https://github.com/UriNeri/rolypoly.git
|
|
48
54
|
cd rolypoly
|
|
49
55
|
|
|
50
56
|
# Install for specific functionality (examples):
|
|
@@ -84,11 +90,11 @@ Legend:
|
|
|
84
90
|
|
|
85
91
|
#### Raw-Reads
|
|
86
92
|
- ✅ [`filter-reads`](https://urineri.github.io/rolypoly/commands/read_processing) — Host/rRNA/adapters/artifact filtering and QC (bbmap, falco, etc.)
|
|
87
|
-
- ✅ [`shrink-reads`](https://urineri.github.io/rolypoly/commands/
|
|
88
|
-
- ✅ [`mask-dna`](https://urineri.github.io/rolypoly/commands/
|
|
93
|
+
- ✅ [`shrink-reads`](https://urineri.github.io/rolypoly/commands/read_processing) — Downsample or subsample reads. Useful for testing or normalizing coverage across samples.
|
|
94
|
+
- ✅ [`mask-dna`](https://urineri.github.io/rolypoly/commands/read_processing) — Mask DNA regions in RNA-seq reads (bbmap, seqkit). Useful for avoiding mis-filtering of RNA virus reads in because of potential matches to EVEs.
|
|
89
95
|
|
|
90
96
|
#### Annotation
|
|
91
|
-
- ✅ [`annotate`](https://urineri.github.io/rolypoly/commands/annotate) — Genome feature annotation (wraps the rna and prot commands)
|
|
97
|
+
- ✅ [`annotate`](https://urineri.github.io/rolypoly/commands/annotate_rna/#annotate-rna) — Genome feature annotation (wraps the rna and prot commands)
|
|
92
98
|
- ✅ [`annotate-rna`](https://urineri.github.io/rolypoly/commands/annotate_rna) — RNA secondary structure labelling and ribozyme detection (Infernal, ViennaRNA/linearfold, cmsearch on Rfam...)
|
|
93
99
|
- 🧪 [`annotate-prot`](https://urineri.github.io/rolypoly/commands/annotate_prot) — Gene calling and Protein domain annotation and functional prediction (HMMER, Pfam, custom).
|
|
94
100
|
|
|
@@ -99,22 +105,22 @@ Legend:
|
|
|
99
105
|
#### RNA Virus Identification
|
|
100
106
|
- ✅ [`marker-search`](https://urineri.github.io/rolypoly/commands/marker_search) — Search for viral markers (mainly RdRps, genomad VVs, or user-provided), using profile-based methods (HMMER / MMseqs2).
|
|
101
107
|
- ✅ [`virus-mapping`](https://urineri.github.io/rolypoly/commands/search_viruses) — Map and identify viruses using nucleic acid search (MMseqs2).
|
|
102
|
-
- ✅ `rdrp-motif-search` — Search RdRp motifs (A/B/C/D) in nucleotide or amino acid sequences.
|
|
108
|
+
- ✅ [`rdrp-motif-search`](https://urineri.github.io/rolypoly/commands/rdrp_motif_search) — Search RdRp motifs (A/B/C/D) in nucleotide or amino acid sequences.
|
|
103
109
|
|
|
104
110
|
#### Bining / Clustering
|
|
105
|
-
- 🧪 `cluster` — Average Nucleic identity (ANI) based contig
|
|
106
|
-
- 🧪 `extend` — Extend sequences by pile-up/assembly. Useful for combining assemblies of with low abundance viruses, or those with high microdiversity, at the cost of worse strain/sub-species resolution (i.e. can condense to a
|
|
107
|
-
- 🧪 `termini` — Shared termini grouping and motif reporting. Writes assignments + groups tables (TSV/CSV/Parquet/JSONL) and motif FASTA by default.
|
|
108
|
-
- 🧪 `correlate` —
|
|
109
|
-
- 🤔 `binit` — Combines the above commands with sample information and genome attributes (e.g. require a shared termini AND protein complementarity, like CP + RdRp). See [notebooks/Exprimental/partiti_usecase/partiti_segment_workflow_experimental.ipynb](notebooks/Exprimental/partiti_usecase/partiti_segment_workflow_experimental.ipynb) for candidate workflow.
|
|
111
|
+
- 🧪 [`cluster`](https://urineri.github.io/rolypoly/commands/cluster) — Average Nucleic identity (ANI) based contig grouping. Supports several common backends and methods.
|
|
112
|
+
- 🧪 [`extend`](https://urineri.github.io/rolypoly/commands/extend) — Extend sequences by pile-up/assembly. Useful for combining assemblies of with low abundance viruses, or those with high microdiversity, at the cost of worse strain/sub-species resolution (i.e. can condense to a consensus).
|
|
113
|
+
- 🧪 [`termini`](https://urineri.github.io/rolypoly/commands/binning_termini) — Shared termini grouping and motif reporting. Writes assignments + groups tables (TSV/CSV/Parquet/JSONL) and motif FASTA by default.
|
|
114
|
+
- 🧪 [`correlate`](https://urineri.github.io/rolypoly/commands/binning_correlate) — Group contigs based on co-occurrence, co-abundance, minimal correlation (Spearman's) of these, or both.
|
|
115
|
+
- 🤔 [`binit`](https://urineri.github.io/rolypoly/commands/binit) — Combines the above commands with sample information and genome attributes (e.g. require a shared termini AND protein complementarity, like CP + RdRp). See [notebooks/Exprimental/partiti_usecase/partiti_segment_workflow_experimental.ipynb](notebooks/Exprimental/partiti_usecase/partiti_segment_workflow_experimental.ipynb) for candidate workflow.
|
|
110
116
|
|
|
111
117
|
#### Miscellaneous
|
|
112
|
-
- ✅ `roll` — Run an end-to-end pipeline (before v0.7.1, named `end2end`).
|
|
113
|
-
- ✅ `fetch-sra` — Download SRA fastq files (from ENA)
|
|
114
|
-
- ✅ `fastx-calc` — Calculate per-sequence metrics (length, GC content, hash, ...)
|
|
115
|
-
- ✅ `fastx-stats` — Calculate (-->aggregate) statistics for sequences (min, max, mean, median, ...) (input is file/s)
|
|
116
|
-
- ✅ `rename-seqs` — Rename sequences (add a prefix, suffix, hash, running number, etc.)
|
|
117
|
-
- 🚧 `quick-taxonomy` — Quick taxonomy assignment. Candidate workflows are [github.com/UriNeri/ictv-mmseqs2-protein-database](https://github.com/UriNeri/ictv-mmseqs2-protein-database) and [github.com/apcamargo/ictv-mmseqs2-protein-database](https://github.com/apcamargo/ictv-mmseqs2-protein-database)
|
|
118
|
+
- ✅ [`roll`](https://urineri.github.io/rolypoly/commands/end_to_end) — Run an end-to-end pipeline (before v0.7.1, named `end2end`).
|
|
119
|
+
- ✅ [`fetch-sra`](https://urineri.github.io/rolypoly/commands/misc) — Download SRA fastq files (from ENA)
|
|
120
|
+
- ✅ [`fastx-calc`](https://urineri.github.io/rolypoly/commands/misc) — Calculate per-sequence metrics (length, GC content, hash, ...)
|
|
121
|
+
- ✅ [`fastx-stats`](https://urineri.github.io/rolypoly/commands/misc) — Calculate (-->aggregate) statistics for sequences (min, max, mean, median, ...) (input is file/s)
|
|
122
|
+
- ✅ [`rename-seqs`](https://urineri.github.io/rolypoly/commands/misc) — Rename sequences (add a prefix, suffix, hash, running number, etc.)
|
|
123
|
+
- 🚧 [`quick-taxonomy`](https://urineri.github.io/rolypoly/commands/misc) — Quick taxonomy assignment. Candidate workflows are [github.com/UriNeri/ictv-mmseqs2-protein-database](https://github.com/UriNeri/ictv-mmseqs2-protein-database) and [github.com/apcamargo/ictv-mmseqs2-protein-database](https://github.com/apcamargo/ictv-mmseqs2-protein-database)
|
|
118
124
|
- 🤔 support for [genotate](https://github.com/deprekate/genotate) for gene prediction.
|
|
119
125
|
- 🤔 Genome refinement / strain de-entalgement / variant calling?
|
|
120
126
|
- 🤔 Virus feature prediction (+/-ssRNA/dsRNA, circular/linear, mono/poly-segmented, capsid type, etc.)
|
|
@@ -125,7 +131,7 @@ If you have suggestions for additional commands or features, or want to implemen
|
|
|
125
131
|
|
|
126
132
|
## Dependencies
|
|
127
133
|
|
|
128
|
-
**📦 Modular Installation Available**: RolyPoly supports both quick setup (one environment with all dependecies for all commands) and modular installation (command-specific environments). The modular approach is particularly useful for software developers who want to integrate specific rolypoly features with minimal dependency conflicts. See the [installation documentation](
|
|
134
|
+
**📦 Modular Installation Available**: RolyPoly supports both quick setup (one environment with all dependecies for all commands) and modular installation (command-specific environments). The modular approach is particularly useful for software developers who want to integrate specific rolypoly features with minimal dependency conflicts. See the [installation documentation](https://urineri.github.io/rolypoly/installation/) for details.
|
|
129
135
|
|
|
130
136
|
Not all 3rd party software is used by all the different commands. RolyPoly includes a "citation reminder" that will try to list all the external software used by a command. The "reminded citations" are pretty printed to console (stdout) and to a logfile. To shut off the terminal citation reminder printing, set `ROLYPOLY_REMIND_CITATIONS` to false in your `rpconfig.json` file.
|
|
131
137
|
|
|
@@ -16,7 +16,7 @@ authors = [
|
|
|
16
16
|
|
|
17
17
|
description = "RNA virus analysis toolkit"
|
|
18
18
|
readme = "README.md"
|
|
19
|
-
requires-python = ">=3.10"
|
|
19
|
+
requires-python = ">=3.10,<3.14"
|
|
20
20
|
license = { file = "LICENSE" }
|
|
21
21
|
# License-File = "license"
|
|
22
22
|
dependencies = [
|
|
@@ -47,7 +47,7 @@ dependencies = [
|
|
|
47
47
|
|
|
48
48
|
[project.urls]
|
|
49
49
|
Source = "https://github.com/UriNeri/rolypoly"
|
|
50
|
-
Documentation = "https://
|
|
50
|
+
Documentation = "https://urineri.github.io/rolypoly/"
|
|
51
51
|
pypi = "https://pypi.org/project/rolypoly-tk/"
|
|
52
52
|
|
|
53
53
|
[project.scripts]
|
|
@@ -160,6 +160,13 @@ aria2 = ">=1.37.0,<2"
|
|
|
160
160
|
[tool.pixi.feature.dev.pypi-dependencies]
|
|
161
161
|
lets-plot = ">=4.8.2,<5"
|
|
162
162
|
|
|
163
|
+
[tool.pixi.feature.docs.pypi-dependencies]
|
|
164
|
+
mkdocs = "*"
|
|
165
|
+
mkdocs-material = "*"
|
|
166
|
+
mkdocs-mermaid2-plugin = "*"
|
|
167
|
+
mkdocstrings = "*"
|
|
168
|
+
mkdocstrings-python = "*"
|
|
169
|
+
|
|
163
170
|
[tool.pixi.feature.py310.dependencies]
|
|
164
171
|
python = "~=3.10.0"
|
|
165
172
|
|
|
@@ -193,6 +200,7 @@ dev = { features = [
|
|
|
193
200
|
"format",
|
|
194
201
|
"publish",
|
|
195
202
|
"dev",
|
|
203
|
+
"docs",
|
|
196
204
|
] }
|
|
197
205
|
|
|
198
206
|
# Specific command group environments for targeted installations
|
|
@@ -234,6 +242,10 @@ test-import = "python -c 'import rolypoly; print(rolypoly.__version__)'"
|
|
|
234
242
|
test-cli = "pytest -q src/tests/test_cli_contracts.py"
|
|
235
243
|
bump-commit-publish = "bash src/setup/bump_commit_publish.sh"
|
|
236
244
|
|
|
245
|
+
[tool.pixi.feature.docs.tasks]
|
|
246
|
+
docs-serve = "mkdocs serve -f docs/mkdocs.yml"
|
|
247
|
+
docs-build = "mkdocs build -f docs/mkdocs.yml"
|
|
248
|
+
|
|
237
249
|
[tool.ruff]
|
|
238
250
|
exclude = [
|
|
239
251
|
".bzr",
|
|
@@ -177,7 +177,15 @@ def annotate(
|
|
|
177
177
|
log_level,
|
|
178
178
|
search_tool,
|
|
179
179
|
):
|
|
180
|
-
"""
|
|
180
|
+
"""Run combined RNA + protein annotation on nucleotide viral sequences.
|
|
181
|
+
|
|
182
|
+
This command orchestrates `annotate-rna` and `annotate-prot` into a single
|
|
183
|
+
workflow and writes results into `rna_annotation/` and
|
|
184
|
+
`protein_annotation/` subdirectories under the selected output path.
|
|
185
|
+
|
|
186
|
+
Use `--skip-steps` to disable specific stages and `--override-parameters`
|
|
187
|
+
to forward JSON overrides to sub-tools.
|
|
188
|
+
"""
|
|
181
189
|
import json
|
|
182
190
|
|
|
183
191
|
from rolypoly.utils.logging.loggit import log_start_info
|
|
@@ -228,10 +228,15 @@ def annotate_RNA(
|
|
|
228
228
|
resolve_mode,
|
|
229
229
|
min_overlap_positions,
|
|
230
230
|
):
|
|
231
|
-
"""
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
231
|
+
"""Annotate RNA structural features and motifs on viral nucleotide inputs.
|
|
232
|
+
|
|
233
|
+
The default pipeline runs secondary-structure prediction, ribozyme/CM
|
|
234
|
+
search, and tRNA detection, while optional modules can add IRES and motif
|
|
235
|
+
analyses depending on selected tools and skip settings.
|
|
236
|
+
|
|
237
|
+
Use `--skip-steps` to disable modules and `--override-parameters` to pass
|
|
238
|
+
tool-specific tuning values for individual stages.
|
|
239
|
+
"""
|
|
235
240
|
import json
|
|
236
241
|
|
|
237
242
|
config = RNAAnnotationConfig(
|
|
@@ -530,7 +530,16 @@ def assembly(
|
|
|
530
530
|
overwrite,
|
|
531
531
|
log_level,
|
|
532
532
|
):
|
|
533
|
-
"""
|
|
533
|
+
"""Assemble reads/contigs with one or more backends and optional post-processing.
|
|
534
|
+
|
|
535
|
+
Inputs can be provided explicitly (`--paired-end`, `--single-end`,
|
|
536
|
+
`--merged`, `--long-read`, `--raw-fasta`) and/or discovered from
|
|
537
|
+
`--input-dir`.
|
|
538
|
+
|
|
539
|
+
Selected assembler outputs are normalized and optionally post-processed
|
|
540
|
+
(for example `rmdup` or `linclust`) before writing final contigs and run
|
|
541
|
+
metadata to the output directory.
|
|
542
|
+
"""
|
|
534
543
|
import shutil
|
|
535
544
|
|
|
536
545
|
import polars as pl
|
|
@@ -167,7 +167,13 @@ def filter_contigs(
|
|
|
167
167
|
log_level,
|
|
168
168
|
):
|
|
169
169
|
"""
|
|
170
|
-
Filter contigs
|
|
170
|
+
Filter contigs against user-supplied host/contamination references.
|
|
171
|
+
|
|
172
|
+
Depending on `--mode`, the command applies nucleotide filtering, protein
|
|
173
|
+
filtering, or both, using two-stage rule sets (`filter1_*` and
|
|
174
|
+
`filter2_*`) to retain likely non-host contigs.
|
|
175
|
+
|
|
176
|
+
Host references can be masked first (default) unless `--dont-mask` is set.
|
|
171
177
|
"""
|
|
172
178
|
from rolypoly.utils.logging.citation_reminder import remind_citations
|
|
173
179
|
from rolypoly.utils.logging.loggit import log_start_info
|
|
@@ -432,7 +432,12 @@ def binit(
|
|
|
432
432
|
log_file: Path | None,
|
|
433
433
|
log_level: str,
|
|
434
434
|
) -> None:
|
|
435
|
-
"""Run
|
|
435
|
+
"""Run an integrated segment-binning workflow over RdRp and CP contigs.
|
|
436
|
+
|
|
437
|
+
The workflow chains cluster, correlate, extend, and termini steps, then
|
|
438
|
+
joins their outputs to report candidate segment pairs with supporting
|
|
439
|
+
evidence from abundance/correlation and termini/motif consistency.
|
|
440
|
+
"""
|
|
436
441
|
logger = setup_logging(log_file, log_level)
|
|
437
442
|
log_start_info(logger, locals())
|
|
438
443
|
|
|
@@ -296,7 +296,14 @@ def correlate(
|
|
|
296
296
|
log_file,
|
|
297
297
|
log_level,
|
|
298
298
|
):
|
|
299
|
-
"""
|
|
299
|
+
"""Group contigs by cross-sample association patterns.
|
|
300
|
+
|
|
301
|
+
Supports correlation-based edges, co-occurrence-based edges, or both,
|
|
302
|
+
with prevalence and shared-sample thresholds to reduce spurious links.
|
|
303
|
+
|
|
304
|
+
Writes pairwise edge tables and connected-component style groups using the
|
|
305
|
+
selected output prefix.
|
|
306
|
+
"""
|
|
300
307
|
logger = setup_logging(log_file, log_level)
|
|
301
308
|
log_start_info(logger, locals())
|
|
302
309
|
|
|
@@ -48,7 +48,13 @@ tools = []
|
|
|
48
48
|
def virus_mapping(
|
|
49
49
|
threads, memory, output, keep_tmp, db, db_path, log_file, log_level, input
|
|
50
50
|
):
|
|
51
|
-
"""
|
|
51
|
+
"""Search nucleotide reads/contigs against virus reference databases.
|
|
52
|
+
|
|
53
|
+
Input can be FASTA/FASTQ or an existing MMseqs2 database. The command
|
|
54
|
+
converts sequence inputs to MMseqs2 format as needed and runs searches
|
|
55
|
+
against built-in viral databases (`RVMT`, `NCBI_Ribovirus`, or `all`) or a
|
|
56
|
+
user-supplied target via `--db other --db-path`.
|
|
57
|
+
"""
|
|
52
58
|
import shutil
|
|
53
59
|
import subprocess
|
|
54
60
|
|
|
@@ -82,8 +82,10 @@ def fastx_stats(
|
|
|
82
82
|
"""
|
|
83
83
|
Calculate aggregate statistics for sequences (min, max, mean, median, etc.).
|
|
84
84
|
|
|
85
|
-
This command computes
|
|
86
|
-
|
|
85
|
+
This command computes dataset-level summaries across sequences in one or
|
|
86
|
+
more FASTA/FASTQ inputs, including count, length, and composition fields.
|
|
87
|
+
|
|
88
|
+
For per-sequence annotations instead of aggregates, use `fastx-calc`.
|
|
87
89
|
"""
|
|
88
90
|
from rolypoly.utils.bio.polars_fastx import (
|
|
89
91
|
compute_aggregate_stats,
|
|
@@ -463,8 +463,14 @@ def filter_reads(
|
|
|
463
463
|
temp_dir,
|
|
464
464
|
):
|
|
465
465
|
"""
|
|
466
|
-
Process RNA-seq
|
|
467
|
-
|
|
466
|
+
Process RNA-seq Illumina reads through the read-cleaning pipeline.
|
|
467
|
+
|
|
468
|
+
The workflow combines host/contaminant removal, optional fetched-reference
|
|
469
|
+
filtering, adapter/quality trimming, and optional error correction based on
|
|
470
|
+
configured steps and speed presets.
|
|
471
|
+
|
|
472
|
+
Input can be a single file, paired files, or a directory of FASTQ files.
|
|
473
|
+
Use `--skip-steps` and `--override-parameters` to tailor the workflow.
|
|
468
474
|
"""
|
|
469
475
|
from rolypoly.utils.logging.citation_reminder import remind_citations
|
|
470
476
|
from rolypoly.utils.logging.loggit import log_start_info
|
|
@@ -65,11 +65,13 @@ def shrink_reads(
|
|
|
65
65
|
log_level,
|
|
66
66
|
):
|
|
67
67
|
"""
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
Subset FASTQ reads by count or fraction for lightweight test datasets.
|
|
69
|
+
|
|
70
|
+
Supports deterministic head-style subsampling (`first_n`) and random
|
|
71
|
+
sampling (`random`) for single-end, interleaved, and paired-end layouts.
|
|
72
|
+
|
|
73
|
+
This command is intended for quick dry runs and resource-reduced tests,
|
|
74
|
+
not as a full read-normalization strategy.
|
|
73
75
|
"""
|
|
74
76
|
# Initialise logger
|
|
75
77
|
logger = setup_logging(log_file=log_file, log_level=log_level)
|
|
@@ -109,7 +109,6 @@ CONTEXT_SETTINGS = dict(
|
|
|
109
109
|
"fastx-stats": "rolypoly.commands.misc.fastx_stats.fastx_stats",
|
|
110
110
|
"fastx-calc": "rolypoly.commands.misc.fastx_calc.fastx_calc",
|
|
111
111
|
"rename-seqs": "rolypoly.commands.misc.rename_seqs.rename_seqs",
|
|
112
|
-
"quick-taxonomy": "rolypoly.commands.misc.quick_taxonomy.quick_taxonomy",
|
|
113
112
|
"help": "rolypoly.rolypoly.rolypoly",
|
|
114
113
|
},
|
|
115
114
|
},
|
|
@@ -126,7 +125,6 @@ CONTEXT_SETTINGS = dict(
|
|
|
126
125
|
# "name": "Characterisation",
|
|
127
126
|
# "commands": {
|
|
128
127
|
# "characterise": "hidden:rolypoly.commands.virotype.predict_characteristics.predict_characteristics",
|
|
129
|
-
# "predict-host": "hidden:rolypoly.commands.host.classify.predict_host_range",
|
|
130
128
|
# # Commenting out unimplemented/broken commands
|
|
131
129
|
# # "summarize": "rolypoly.commands.virotype.summarize.summarize"
|
|
132
130
|
# },
|
|
@@ -156,7 +154,10 @@ def rolypoly():
|
|
|
156
154
|
)
|
|
157
155
|
def version(log_level):
|
|
158
156
|
"""
|
|
159
|
-
Print code
|
|
157
|
+
Print RolyPoly code and data version details.
|
|
158
|
+
|
|
159
|
+
This is a command-form wrapper around top-level `--version` output, useful
|
|
160
|
+
in scripted workflows that call `rolypoly version` explicitly.
|
|
160
161
|
"""
|
|
161
162
|
setup_logging(None, log_level)
|
|
162
163
|
# click wrapper for version/data information, so it could be called vai rolypoly version (on top of rolypoly --version)
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This is a place holder script.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
|
|
7
|
-
import rich_click as click
|
|
8
|
-
|
|
9
|
-
# from rich.console import Console
|
|
10
|
-
|
|
11
|
-
# console = Console()
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@click.command()
|
|
15
|
-
@click.option(
|
|
16
|
-
"-i",
|
|
17
|
-
"--input",
|
|
18
|
-
required=True,
|
|
19
|
-
help="Input directory containing rolypoly's virus identification and annotation results",
|
|
20
|
-
)
|
|
21
|
-
@click.option(
|
|
22
|
-
"-o",
|
|
23
|
-
"--output",
|
|
24
|
-
default=lambda: f"{os.getcwd()}_predict_host_range.tsv",
|
|
25
|
-
help="output path",
|
|
26
|
-
)
|
|
27
|
-
@click.option("-t", "--threads", default=1, help="Number of threads")
|
|
28
|
-
@click.option(
|
|
29
|
-
"-g",
|
|
30
|
-
"--log-file",
|
|
31
|
-
default=lambda: f"{os.getcwd()}/predict_host_range_logfile.txt",
|
|
32
|
-
help="Path to log file",
|
|
33
|
-
)
|
|
34
|
-
@click.option(
|
|
35
|
-
"-ll", "--log-level", hidden=True, default="INFO", help="Log level"
|
|
36
|
-
)
|
|
37
|
-
def predict_host_range(input, output, threads, log_file, log_level):
|
|
38
|
-
"""WIP WIP WIP Predict a viral seq host range - caution! this is not definitive"""
|
|
39
|
-
from rolypoly.utils.logging.loggit import setup_logging
|
|
40
|
-
|
|
41
|
-
logger = setup_logging(log_file, log_level)
|
|
42
|
-
logger.info("Starting to predict ")
|
|
43
|
-
logger.info("Sorry! command not yet implemented!")
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if __name__ == "main":
|
|
47
|
-
predict_host_range()
|
|
@@ -1,372 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
this script is a place holder
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
|
|
7
|
-
import rich_click as click
|
|
8
|
-
from rich.console import Console
|
|
9
|
-
|
|
10
|
-
from rolypoly.utils.logging.citation_reminder import remind_citations
|
|
11
|
-
|
|
12
|
-
console = Console()
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def parse_marker_results(marker_file):
|
|
16
|
-
"""Parse marker search results file.
|
|
17
|
-
|
|
18
|
-
Args:
|
|
19
|
-
marker_file (str): Path to marker search results
|
|
20
|
-
|
|
21
|
-
Returns:
|
|
22
|
-
pl.DataFrame: DataFrame with marker results
|
|
23
|
-
"""
|
|
24
|
-
import json
|
|
25
|
-
|
|
26
|
-
import polars as pl
|
|
27
|
-
|
|
28
|
-
if marker_file.endswith(".tsv"):
|
|
29
|
-
return pl.read_csv(marker_file, separator="\t")
|
|
30
|
-
elif marker_file.endswith(".json"):
|
|
31
|
-
with open(marker_file) as f:
|
|
32
|
-
data = json.load(f)
|
|
33
|
-
return pl.DataFrame(data)
|
|
34
|
-
else:
|
|
35
|
-
raise ValueError(f"Unsupported file format for {marker_file}")
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def run_genomad_hmm_search(input_fasta, output_dir, threads, logger):
|
|
39
|
-
"""Run genomad RNA viral HMM search.
|
|
40
|
-
|
|
41
|
-
Args:
|
|
42
|
-
input_fasta (str): Path to input fasta file
|
|
43
|
-
output_dir (Path): Output directory
|
|
44
|
-
threads (int): Number of threads to use
|
|
45
|
-
logger (Logger): Logger object
|
|
46
|
-
|
|
47
|
-
Returns:
|
|
48
|
-
pl.DataFrame: DataFrame with HMM search results
|
|
49
|
-
"""
|
|
50
|
-
import os
|
|
51
|
-
|
|
52
|
-
import polars as pl
|
|
53
|
-
|
|
54
|
-
from rolypoly.utils.bio.alignments import search_hmmdb
|
|
55
|
-
|
|
56
|
-
hmm_db = (
|
|
57
|
-
Path(os.environ["ROLYPOLY_DATA"])
|
|
58
|
-
/ "hmmdbs"
|
|
59
|
-
/ "genomad_rna_viral_markers.hmm"
|
|
60
|
-
)
|
|
61
|
-
output_file = output_dir / "genomad_hmm_results.txt"
|
|
62
|
-
|
|
63
|
-
# Use existing HMM search functionality
|
|
64
|
-
try:
|
|
65
|
-
search_hmmdb(
|
|
66
|
-
amino_file=input_fasta,
|
|
67
|
-
db_path=str(hmm_db),
|
|
68
|
-
output=str(output_file),
|
|
69
|
-
threads=threads,
|
|
70
|
-
logger=logger,
|
|
71
|
-
output_format="tblout",
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
# Parse results
|
|
75
|
-
results = []
|
|
76
|
-
with open(output_file) as f:
|
|
77
|
-
for line in f:
|
|
78
|
-
if line.startswith("#"):
|
|
79
|
-
continue
|
|
80
|
-
parts = line.split()
|
|
81
|
-
if len(parts) >= 5:
|
|
82
|
-
results.append(
|
|
83
|
-
{
|
|
84
|
-
"query": parts[0],
|
|
85
|
-
"target": parts[2],
|
|
86
|
-
"evalue": float(parts[4]),
|
|
87
|
-
"score": float(parts[5]),
|
|
88
|
-
}
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
return pl.DataFrame(results)
|
|
92
|
-
except Exception as e:
|
|
93
|
-
logger.error(f"HMM search failed: {e}")
|
|
94
|
-
return pl.DataFrame()
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def assign_taxonomy(sequence_id, markers, hmm_results, min_score=50):
|
|
98
|
-
"""Assign taxonomy based on marker and HMM results.
|
|
99
|
-
|
|
100
|
-
Args:
|
|
101
|
-
sequence_id (str): Sequence identifier
|
|
102
|
-
markers (pl.DataFrame): Marker search results
|
|
103
|
-
hmm_results (pl.DataFrame): HMM search results
|
|
104
|
-
min_score (float): Minimum score threshold
|
|
105
|
-
|
|
106
|
-
Returns:
|
|
107
|
-
dict: Taxonomy assignment
|
|
108
|
-
"""
|
|
109
|
-
import polars as pl
|
|
110
|
-
|
|
111
|
-
# Filter results by score
|
|
112
|
-
seq_markers = markers.filter(pl.col("query") == sequence_id)
|
|
113
|
-
seq_hmms = hmm_results.filter(
|
|
114
|
-
(pl.col("query") == sequence_id) & (pl.col("score") >= min_score)
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
# Initialize taxonomy assignment
|
|
118
|
-
tax = {
|
|
119
|
-
"sequence_id": sequence_id,
|
|
120
|
-
"confidence": 0.0,
|
|
121
|
-
"taxonomy": "Unknown",
|
|
122
|
-
"evidence": [],
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
# Look for RdRP markers first (highest confidence)
|
|
126
|
-
rdrp_markers = seq_markers.filter(
|
|
127
|
-
pl.col("target").str.contains("RdRP|RdRp|rdrp")
|
|
128
|
-
)
|
|
129
|
-
if not rdrp_markers.is_empty():
|
|
130
|
-
best_hit = rdrp_markers.sort("score", descending=True).row(0)
|
|
131
|
-
tax["taxonomy"] = (
|
|
132
|
-
best_hit["taxonomy"] if "taxonomy" in best_hit else "RNA virus"
|
|
133
|
-
)
|
|
134
|
-
tax["confidence"] = min(1.0, best_hit["score"] / 100)
|
|
135
|
-
tax["evidence"].append(f"RdRP marker: {best_hit['target']}")
|
|
136
|
-
|
|
137
|
-
# Check genomad HMM results
|
|
138
|
-
if not seq_hmms.is_empty():
|
|
139
|
-
hmm_hits = seq_hmms.sort("score", descending=True)
|
|
140
|
-
for hit in hmm_hits.iter_rows():
|
|
141
|
-
tax["evidence"].append(f"RNA viral marker: {hit['target']}")
|
|
142
|
-
if (
|
|
143
|
-
tax["confidence"] < 0.8
|
|
144
|
-
): # Only update if current confidence is low
|
|
145
|
-
tax["confidence"] = min(0.8, hit["score"] / 100)
|
|
146
|
-
|
|
147
|
-
# Check other viral markers
|
|
148
|
-
other_markers = seq_markers.filter(
|
|
149
|
-
~pl.col("target").str.contains("RdRP|RdRp|rdrp")
|
|
150
|
-
)
|
|
151
|
-
if not other_markers.is_empty():
|
|
152
|
-
for hit in other_markers.iter_rows():
|
|
153
|
-
tax["evidence"].append(f"Other marker: {hit['target']}")
|
|
154
|
-
if (
|
|
155
|
-
tax["confidence"] < 0.6
|
|
156
|
-
): # Only update if current confidence is low
|
|
157
|
-
tax["confidence"] = min(0.6, hit["score"] / 100)
|
|
158
|
-
|
|
159
|
-
return tax
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def summarize_taxonomy(assignments):
|
|
163
|
-
"""Generate taxonomy summary statistics.
|
|
164
|
-
|
|
165
|
-
Args:
|
|
166
|
-
assignments (list): List of taxonomy assignments
|
|
167
|
-
|
|
168
|
-
Returns:
|
|
169
|
-
dict: Summary statistics
|
|
170
|
-
"""
|
|
171
|
-
from collections import defaultdict
|
|
172
|
-
|
|
173
|
-
total = len(assignments)
|
|
174
|
-
assigned = sum(1 for a in assignments if a["taxonomy"] != "Unknown")
|
|
175
|
-
|
|
176
|
-
# Count taxonomy levels
|
|
177
|
-
tax_counts = defaultdict(int)
|
|
178
|
-
confidence_sum = 0
|
|
179
|
-
|
|
180
|
-
for assign in assignments:
|
|
181
|
-
if assign["taxonomy"] != "Unknown":
|
|
182
|
-
tax_counts[assign["taxonomy"]] += 1
|
|
183
|
-
confidence_sum += assign["confidence"]
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
"total_sequences": total,
|
|
187
|
-
"assigned_sequences": assigned,
|
|
188
|
-
"percent_assigned": (assigned / total * 100) if total > 0 else 0,
|
|
189
|
-
"mean_confidence": confidence_sum / assigned if assigned > 0 else 0,
|
|
190
|
-
"taxonomy_distribution": dict(tax_counts),
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
@click.command()
|
|
195
|
-
@click.option("-i", "--input", required=True, help="Input file or directory")
|
|
196
|
-
@click.option("-o", "--output", default="output", help="Output directory")
|
|
197
|
-
@click.option("-t", "--threads", default=1, help="Number of threads")
|
|
198
|
-
@click.option("--log-file", default="command.log", help="Path to log file")
|
|
199
|
-
@click.option(
|
|
200
|
-
"-ll", "--log-level", hidden=True, default="INFO", help="Log level"
|
|
201
|
-
)
|
|
202
|
-
@click.option("--marker_results", default=None, type=str, help="marker_results")
|
|
203
|
-
@click.option(
|
|
204
|
-
"--format",
|
|
205
|
-
default="text",
|
|
206
|
-
type=click.Choice(["text", "json", "tsv"]),
|
|
207
|
-
help="format",
|
|
208
|
-
)
|
|
209
|
-
@click.option("--min_score", default=50.0, type=float, help="min_score")
|
|
210
|
-
@click.option("--summarize", default=True, type=bool, help="summarize")
|
|
211
|
-
def quick_taxonomy(
|
|
212
|
-
input,
|
|
213
|
-
output,
|
|
214
|
-
threads,
|
|
215
|
-
log_file,
|
|
216
|
-
log_level,
|
|
217
|
-
marker_results,
|
|
218
|
-
format,
|
|
219
|
-
min_score,
|
|
220
|
-
summarize,
|
|
221
|
-
):
|
|
222
|
-
"""
|
|
223
|
-
Rapid taxonomy assignment for viral sequences using marker search results and genomad RNA viral HMMs
|
|
224
|
-
"""
|
|
225
|
-
import json
|
|
226
|
-
|
|
227
|
-
import polars as pl
|
|
228
|
-
from needletail import parse_fastx_file
|
|
229
|
-
from rich.table import Table
|
|
230
|
-
|
|
231
|
-
from rolypoly.utils.logging.loggit import log_start_info, setup_logging
|
|
232
|
-
|
|
233
|
-
logger = setup_logging(log_file, log_level)
|
|
234
|
-
log_start_info(logger, locals())
|
|
235
|
-
|
|
236
|
-
# Create output directory
|
|
237
|
-
output_path = Path(output)
|
|
238
|
-
output_path.mkdir(parents=True, exist_ok=True)
|
|
239
|
-
|
|
240
|
-
sequences = []
|
|
241
|
-
for record in parse_fastx_file(input):
|
|
242
|
-
sequences.append({"id": record.id, "seq": record.seq}) # type: ignore
|
|
243
|
-
|
|
244
|
-
if not sequences:
|
|
245
|
-
logger.error(f"No sequences found in {input}")
|
|
246
|
-
return
|
|
247
|
-
|
|
248
|
-
# Parse marker results if provided
|
|
249
|
-
markers_df = None
|
|
250
|
-
if marker_results:
|
|
251
|
-
try:
|
|
252
|
-
markers_df = parse_marker_results(marker_results)
|
|
253
|
-
except Exception as e:
|
|
254
|
-
logger.warning(f"Error parsing marker results: {e}")
|
|
255
|
-
|
|
256
|
-
# Run genomad HMM search
|
|
257
|
-
logger.info("Running genomad RNA viral HMM search...")
|
|
258
|
-
hmm_results = run_genomad_hmm_search(input, output_path, threads, logger)
|
|
259
|
-
|
|
260
|
-
# Assign taxonomy
|
|
261
|
-
logger.info("Assigning taxonomy...")
|
|
262
|
-
assignments = []
|
|
263
|
-
for seq in sequences:
|
|
264
|
-
tax = assign_taxonomy(
|
|
265
|
-
seq["id"],
|
|
266
|
-
markers_df if markers_df is not None else pl.DataFrame(),
|
|
267
|
-
hmm_results,
|
|
268
|
-
min_score,
|
|
269
|
-
)
|
|
270
|
-
assignments.append(tax)
|
|
271
|
-
|
|
272
|
-
# Generate summary if requested
|
|
273
|
-
if summarize:
|
|
274
|
-
summary = summarize_taxonomy(assignments)
|
|
275
|
-
|
|
276
|
-
# Output results based on format
|
|
277
|
-
if format == "json":
|
|
278
|
-
results = {
|
|
279
|
-
"assignments": assignments,
|
|
280
|
-
"summary": summary if summarize else None,
|
|
281
|
-
}
|
|
282
|
-
with open(output_path / "taxonomy_assignments.json", "w") as f:
|
|
283
|
-
json.dump(results, f, indent=2)
|
|
284
|
-
|
|
285
|
-
elif format == "tsv":
|
|
286
|
-
# Flatten assignments for TSV
|
|
287
|
-
flat_assignments = []
|
|
288
|
-
for assign in assignments:
|
|
289
|
-
flat_assign = {
|
|
290
|
-
"sequence_id": assign["sequence_id"],
|
|
291
|
-
"taxonomy": assign["taxonomy"],
|
|
292
|
-
"confidence": assign["confidence"],
|
|
293
|
-
"evidence": ";".join(assign["evidence"]),
|
|
294
|
-
}
|
|
295
|
-
flat_assignments.append(flat_assign)
|
|
296
|
-
|
|
297
|
-
pl.DataFrame(flat_assignments).write_csv(
|
|
298
|
-
output_path / "taxonomy_assignments.tsv", separator="\t"
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
if summarize:
|
|
302
|
-
with open(output_path / "taxonomy_summary.tsv", "w") as f:
|
|
303
|
-
for k, v in summary.items():
|
|
304
|
-
if k != "taxonomy_distribution":
|
|
305
|
-
f.write(f"{k}\t{v}\n")
|
|
306
|
-
f.write("\nTaxonomy distribution:\n")
|
|
307
|
-
for tax, count in summary["taxonomy_distribution"].items():
|
|
308
|
-
f.write(f"{tax}\t{count}\n")
|
|
309
|
-
|
|
310
|
-
else: # text format
|
|
311
|
-
# Create assignments table
|
|
312
|
-
assign_table = Table(title="Taxonomy Assignments")
|
|
313
|
-
assign_table.add_column("Sequence ID")
|
|
314
|
-
assign_table.add_column("Taxonomy")
|
|
315
|
-
assign_table.add_column("Confidence")
|
|
316
|
-
assign_table.add_column("Evidence")
|
|
317
|
-
|
|
318
|
-
for assign in assignments:
|
|
319
|
-
assign_table.add_row(
|
|
320
|
-
assign["sequence_id"],
|
|
321
|
-
assign["taxonomy"],
|
|
322
|
-
f"{assign['confidence']:.2f}",
|
|
323
|
-
"\n".join(assign["evidence"]),
|
|
324
|
-
)
|
|
325
|
-
|
|
326
|
-
console.print(assign_table)
|
|
327
|
-
|
|
328
|
-
if summarize:
|
|
329
|
-
# Create summary table
|
|
330
|
-
summary_table = Table(title="Taxonomy Summary")
|
|
331
|
-
summary_table.add_column("Metric")
|
|
332
|
-
summary_table.add_column("Value")
|
|
333
|
-
|
|
334
|
-
for k, v in summary.items():
|
|
335
|
-
if k != "taxonomy_distribution":
|
|
336
|
-
summary_table.add_row(
|
|
337
|
-
k, f"{v:.1f}" if isinstance(v, float) else str(v)
|
|
338
|
-
)
|
|
339
|
-
|
|
340
|
-
console.print(summary_table)
|
|
341
|
-
|
|
342
|
-
# Create taxonomy distribution table
|
|
343
|
-
dist_table = Table(title="Taxonomy Distribution")
|
|
344
|
-
dist_table.add_column("Taxonomy")
|
|
345
|
-
dist_table.add_column("Count")
|
|
346
|
-
dist_table.add_column("Percentage")
|
|
347
|
-
|
|
348
|
-
total = sum(summary["taxonomy_distribution"].values())
|
|
349
|
-
for tax, count in summary["taxonomy_distribution"].items():
|
|
350
|
-
dist_table.add_row(
|
|
351
|
-
tax, str(count), f"{count / total * 100:.1f}%"
|
|
352
|
-
)
|
|
353
|
-
|
|
354
|
-
console.print(dist_table)
|
|
355
|
-
|
|
356
|
-
# Save to file
|
|
357
|
-
with open(output_path / "taxonomy_assignments.txt", "w") as f:
|
|
358
|
-
file_console = Console(file=f)
|
|
359
|
-
file_console.print(assign_table)
|
|
360
|
-
if summarize:
|
|
361
|
-
file_console.print("\n")
|
|
362
|
-
file_console.print(summary_table)
|
|
363
|
-
file_console.print("\n")
|
|
364
|
-
file_console.print(dist_table)
|
|
365
|
-
|
|
366
|
-
logger.info("quick-taxonomy completed successfully!")
|
|
367
|
-
tools = ["HMMER", "geNomad"]
|
|
368
|
-
remind_citations(tools)
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if __name__ == "__main__":
|
|
372
|
-
quick_taxonomy()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/identify_virus/rdrp_motif_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/commands/virotype/predict_characteristics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rolypoly_tk-0.7.2 → rolypoly_tk-0.7.4}/rolypoly/utils/logging/all_used_tools_dbs_citations.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|