universalmotif 0.1.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.
- universalmotif-0.1.0/LICENSE +21 -0
- universalmotif-0.1.0/PKG-INFO +219 -0
- universalmotif-0.1.0/README.md +178 -0
- universalmotif-0.1.0/pyproject.toml +89 -0
- universalmotif-0.1.0/python/universalmotif/__init__.py +219 -0
- universalmotif-0.1.0/python/universalmotif/__main__.py +5 -0
- universalmotif-0.1.0/python/universalmotif/_analysis.py +407 -0
- universalmotif-0.1.0/python/universalmotif/_api.py +512 -0
- universalmotif-0.1.0/python/universalmotif/_biopython.py +183 -0
- universalmotif-0.1.0/python/universalmotif/_cli.py +1181 -0
- universalmotif-0.1.0/python/universalmotif/_compare.py +480 -0
- universalmotif-0.1.0/python/universalmotif/_core.pyi +531 -0
- universalmotif-0.1.0/python/universalmotif/_data.py +88 -0
- universalmotif-0.1.0/python/universalmotif/_deep.py +280 -0
- universalmotif-0.1.0/python/universalmotif/_display.py +195 -0
- universalmotif-0.1.0/python/universalmotif/_enrich.py +370 -0
- universalmotif-0.1.0/python/universalmotif/_genome.py +233 -0
- universalmotif-0.1.0/python/universalmotif/_genomic.py +574 -0
- universalmotif-0.1.0/python/universalmotif/_intervals.py +190 -0
- universalmotif-0.1.0/python/universalmotif/_io.py +619 -0
- universalmotif-0.1.0/python/universalmotif/_logo.py +221 -0
- universalmotif-0.1.0/python/universalmotif/_matches.py +231 -0
- universalmotif-0.1.0/python/universalmotif/_packed.py +131 -0
- universalmotif-0.1.0/python/universalmotif/_plot.py +885 -0
- universalmotif-0.1.0/python/universalmotif/_sequences.py +686 -0
- universalmotif-0.1.0/python/universalmotif/_utils.py +624 -0
- universalmotif-0.1.0/python/universalmotif/data/example.cisbp +55 -0
- universalmotif-0.1.0/python/universalmotif/data/example.jaspar +24 -0
- universalmotif-0.1.0/python/universalmotif/data/example.matrix +24 -0
- universalmotif-0.1.0/python/universalmotif/data/example.meme +56 -0
- universalmotif-0.1.0/python/universalmotif/data/example.motif +39 -0
- universalmotif-0.1.0/python/universalmotif/data/example.transfac +59 -0
- universalmotif-0.1.0/python/universalmotif/data/example.uniprobe +24 -0
- universalmotif-0.1.0/python/universalmotif/data/example_controls.fa.gz +0 -0
- universalmotif-0.1.0/python/universalmotif/data/example_motifs.transfac +179 -0
- universalmotif-0.1.0/python/universalmotif/data/example_targets.fa.gz +0 -0
- universalmotif-0.1.0/python/universalmotif/data/roboto.json +1 -0
- universalmotif-0.1.0/python/universalmotif/databases.py +513 -0
- universalmotif-0.1.0/python/universalmotif/py.typed +0 -0
- universalmotif-0.1.0/universalmotif-py/.gitignore +10 -0
- universalmotif-0.1.0/universalmotif-py/CHANGELOG.md +46 -0
- universalmotif-0.1.0/universalmotif-py/Cargo.lock +1106 -0
- universalmotif-0.1.0/universalmotif-py/Cargo.toml +25 -0
- universalmotif-0.1.0/universalmotif-py/LICENSE +21 -0
- universalmotif-0.1.0/universalmotif-py/README.md +178 -0
- universalmotif-0.1.0/universalmotif-py/src/analysis.rs +592 -0
- universalmotif-0.1.0/universalmotif-py/src/arrow.rs +66 -0
- universalmotif-0.1.0/universalmotif-py/src/enrichment.rs +259 -0
- universalmotif-0.1.0/universalmotif-py/src/genome.rs +63 -0
- universalmotif-0.1.0/universalmotif-py/src/genomic.rs +189 -0
- universalmotif-0.1.0/universalmotif-py/src/io.rs +293 -0
- universalmotif-0.1.0/universalmotif-py/src/lib.rs +682 -0
- universalmotif-0.1.0/universalmotif-py/src/packed.rs +127 -0
- universalmotif-0.1.0/universalmotif-py/src/plot.rs +74 -0
- universalmotif-0.1.0/universalmotif-py/src/sequences.rs +347 -0
- universalmotif-0.1.0/universalmotif-py/src/utils.rs +225 -0
- universalmotif-0.1.0/universalmotif-py/tests/conftest.py +133 -0
- universalmotif-0.1.0/universalmotif-py/tests/data/databases/h11.meme +44 -0
- universalmotif-0.1.0/universalmotif-py/tests/data/databases/h11_annotation.tsv +3 -0
- universalmotif-0.1.0/universalmotif-py/tests/data/databases/h12_annotation.jsonl +2 -0
- universalmotif-0.1.0/universalmotif-py/tests/data/databases/jaspar_page.txt +10 -0
- universalmotif-0.1.0/universalmotif-py/tests/data/databases/jaspar_records.json +204 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_alphabets.py +103 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_analysis.py +119 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_biopython.py +74 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_cli.py +291 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_compare.py +170 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_data.py +33 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_databases.py +154 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_deep.py +138 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_display.py +66 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_enrich.py +211 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_fixes.py +96 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_gapped.py +52 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_genome.py +168 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_genomic.py +216 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_intervals.py +107 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_io.py +203 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_matches.py +81 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_motif.py +187 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_packed.py +108 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_plot.py +190 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_reference.py +160 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_sequences.py +243 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_stub_doctests.py +35 -0
- universalmotif-0.1.0/universalmotif-py/tests/test_utils.py +235 -0
- universalmotif-0.1.0/universalmotif-py/uv.lock +5300 -0
- universalmotif-0.1.0/universalmotif-rs/CHANGELOG.md +35 -0
- universalmotif-0.1.0/universalmotif-rs/Cargo.lock +296 -0
- universalmotif-0.1.0/universalmotif-rs/Cargo.toml +26 -0
- universalmotif-0.1.0/universalmotif-rs/DIVERGENCES.md +147 -0
- universalmotif-0.1.0/universalmotif-rs/LICENSE +21 -0
- universalmotif-0.1.0/universalmotif-rs/README.md +108 -0
- universalmotif-0.1.0/universalmotif-rs/examples/bench.rs +406 -0
- universalmotif-0.1.0/universalmotif-rs/src/alphabet.rs +111 -0
- universalmotif-0.1.0/universalmotif-rs/src/background.rs +560 -0
- universalmotif-0.1.0/universalmotif-rs/src/cdf.rs +189 -0
- universalmotif-0.1.0/universalmotif-rs/src/cluster.rs +545 -0
- universalmotif-0.1.0/universalmotif-rs/src/compare.rs +941 -0
- universalmotif-0.1.0/universalmotif-rs/src/complexity.rs +242 -0
- universalmotif-0.1.0/universalmotif-rs/src/convert.rs +459 -0
- universalmotif-0.1.0/universalmotif-rs/src/coocc.rs +296 -0
- universalmotif-0.1.0/universalmotif-rs/src/create.rs +413 -0
- universalmotif-0.1.0/universalmotif-rs/src/dedup.rs +89 -0
- universalmotif-0.1.0/universalmotif-rs/src/enrich.rs +289 -0
- universalmotif-0.1.0/universalmotif-rs/src/error.rs +27 -0
- universalmotif-0.1.0/universalmotif-rs/src/finder.rs +904 -0
- universalmotif-0.1.0/universalmotif-rs/src/genome.rs +577 -0
- universalmotif-0.1.0/universalmotif-rs/src/io/cisbp.rs +167 -0
- universalmotif-0.1.0/universalmotif-rs/src/io/fasta.rs +322 -0
- universalmotif-0.1.0/universalmotif-rs/src/io/homer.rs +189 -0
- universalmotif-0.1.0/universalmotif-rs/src/io/jaspar.rs +150 -0
- universalmotif-0.1.0/universalmotif-rs/src/io/matrix.rs +242 -0
- universalmotif-0.1.0/universalmotif-rs/src/io/meme.rs +732 -0
- universalmotif-0.1.0/universalmotif-rs/src/io/mod.rs +170 -0
- universalmotif-0.1.0/universalmotif-rs/src/io/transfac.rs +185 -0
- universalmotif-0.1.0/universalmotif-rs/src/io/uniprobe.rs +125 -0
- universalmotif-0.1.0/universalmotif-rs/src/kmer.rs +453 -0
- universalmotif-0.1.0/universalmotif-rs/src/lib.rs +117 -0
- universalmotif-0.1.0/universalmotif-rs/src/mask.rs +109 -0
- universalmotif-0.1.0/universalmotif-rs/src/matrix.rs +151 -0
- universalmotif-0.1.0/universalmotif-rs/src/merge.rs +347 -0
- universalmotif-0.1.0/universalmotif-rs/src/metrics.rs +329 -0
- universalmotif-0.1.0/universalmotif-rs/src/motif.rs +918 -0
- universalmotif-0.1.0/universalmotif-rs/src/ops.rs +332 -0
- universalmotif-0.1.0/universalmotif-rs/src/packed.rs +671 -0
- universalmotif-0.1.0/universalmotif-rs/src/peaks.rs +261 -0
- universalmotif-0.1.0/universalmotif-rs/src/proximity.rs +736 -0
- universalmotif-0.1.0/universalmotif-rs/src/pvalue.rs +253 -0
- universalmotif-0.1.0/universalmotif-rs/src/ranges.rs +426 -0
- universalmotif-0.1.0/universalmotif-rs/src/sample.rs +255 -0
- universalmotif-0.1.0/universalmotif-rs/src/scan/gapped.rs +337 -0
- universalmotif-0.1.0/universalmotif-rs/src/scan/mod.rs +1859 -0
- universalmotif-0.1.0/universalmotif-rs/src/scoring.rs +370 -0
- universalmotif-0.1.0/universalmotif-rs/src/shuffle.rs +513 -0
- universalmotif-0.1.0/universalmotif-rs/src/stats.rs +302 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Benjamin Jean-Marie Tremblay
|
|
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.
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: universalmotif
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Programming Language :: Python :: 3
|
|
5
|
+
Classifier: Programming Language :: Rust
|
|
6
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
7
|
+
Requires-Dist: numpy>=1.24
|
|
8
|
+
Requires-Dist: polars>=1.0
|
|
9
|
+
Requires-Dist: anndata>=0.10 ; extra == 'anndata'
|
|
10
|
+
Requires-Dist: scipy>=1.11 ; extra == 'anndata'
|
|
11
|
+
Requires-Dist: pybigtools>=0.3 ; extra == 'bigwig'
|
|
12
|
+
Requires-Dist: biopython>=1.81 ; extra == 'biopython'
|
|
13
|
+
Requires-Dist: h5py>=3.0 ; extra == 'h5py'
|
|
14
|
+
Requires-Dist: pandas>=2.0 ; extra == 'pandas'
|
|
15
|
+
Requires-Dist: pyarrow>=14 ; extra == 'pandas'
|
|
16
|
+
Requires-Dist: matplotlib>=3.8 ; extra == 'plot'
|
|
17
|
+
Requires-Dist: polars-bio>=0.36 ; python_full_version >= '3.11' and python_full_version < '3.15' and extra == 'polars-bio'
|
|
18
|
+
Requires-Dist: pyranges1>=1.0 ; python_full_version >= '3.12' and extra == 'pyranges'
|
|
19
|
+
Requires-Dist: scipy>=1.11 ; extra == 'scipy'
|
|
20
|
+
Provides-Extra: anndata
|
|
21
|
+
Provides-Extra: bigwig
|
|
22
|
+
Provides-Extra: biopython
|
|
23
|
+
Provides-Extra: h5py
|
|
24
|
+
Provides-Extra: pandas
|
|
25
|
+
Provides-Extra: plot
|
|
26
|
+
Provides-Extra: polars-bio
|
|
27
|
+
Provides-Extra: pyranges
|
|
28
|
+
Provides-Extra: scipy
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Summary: Sequence motif manipulation and analysis, a Python port of universalmotif
|
|
31
|
+
Keywords: bioinformatics,motif,pwm,genomics
|
|
32
|
+
Author: Benjamin Jean-Marie Tremblay
|
|
33
|
+
License-Expression: MIT
|
|
34
|
+
Requires-Python: >=3.10
|
|
35
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
36
|
+
Project-URL: Changelog, https://bjmt.github.io/universalmotif-py/changelog/
|
|
37
|
+
Project-URL: Documentation, https://bjmt.github.io/universalmotif-py/
|
|
38
|
+
Project-URL: Issues, https://github.com/bjmt/universalmotif-py/issues
|
|
39
|
+
Project-URL: Repository, https://github.com/bjmt/universalmotif-py
|
|
40
|
+
|
|
41
|
+
# universalmotif (Python)
|
|
42
|
+
|
|
43
|
+
A Python package for working with sequence motifs: creating them, converting
|
|
44
|
+
between their representations, reading and writing them in the common file
|
|
45
|
+
formats, and using them to scan, compare and test sequences. It is a port of
|
|
46
|
+
the [universalmotif](https://bioconductor.org/packages/universalmotif/)
|
|
47
|
+
R/Bioconductor package, built on its Rust version,
|
|
48
|
+
[universalmotif-rs](https://github.com/bjmt/universalmotif-rs), which does
|
|
49
|
+
the heavy lifting, so most of it is quick and can use several threads.
|
|
50
|
+
Motifs are `Motif` objects, matrices come back as numpy arrays, and tables
|
|
51
|
+
come back as [polars](https://pola.rs/) DataFrames.
|
|
52
|
+
|
|
53
|
+
The [documentation](https://bjmt.github.io/universalmotif-py/) has guides
|
|
54
|
+
covering everything from motif basics to a full ChIP-seq analysis, and a
|
|
55
|
+
reference for every function. The package is at an early version, and its
|
|
56
|
+
interface may still change.
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
The package needs Python 3.10 or later and can be installed from PyPI:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
pip install universalmotif
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Wheels are built for Linux (x86_64 and aarch64), macOS (Intel and Apple
|
|
67
|
+
Silicon) and Windows (x86_64). Elsewhere pip builds the package from source,
|
|
68
|
+
which needs a [Rust toolchain](https://rustup.rs/).
|
|
69
|
+
|
|
70
|
+
The only required dependencies are numpy and polars. Everything else is an
|
|
71
|
+
optional extra, needed only by the functions that use it, so that for
|
|
72
|
+
example `pip install "universalmotif[plot]"` adds matplotlib for drawing
|
|
73
|
+
logos:
|
|
74
|
+
|
|
75
|
+
| Extra | Brings in | For |
|
|
76
|
+
| --- | --- | --- |
|
|
77
|
+
| `plot` | matplotlib | logos, trees and the other plots |
|
|
78
|
+
| `scipy` | SciPy | sparse motif match matrices |
|
|
79
|
+
| `anndata` | AnnData, SciPy | match matrices stored with single-cell ATAC data |
|
|
80
|
+
| `biopython` | Biopython | converting to and from `Bio.motifs` |
|
|
81
|
+
| `h5py` | h5py | reading TF-MoDISco results |
|
|
82
|
+
| `bigwig` | pybigtools | bigWig signal, and backgrounds matched on it |
|
|
83
|
+
| `pyranges` | PyRanges | converting tables to PyRanges objects |
|
|
84
|
+
| `polars-bio` | polars-bio | preparing tables for polars-bio |
|
|
85
|
+
| `pandas` | pandas, pyarrow | pandas DataFrames, and logomaker export |
|
|
86
|
+
|
|
87
|
+
## A quick look
|
|
88
|
+
|
|
89
|
+
Using the example motifs and sequences that come with the package:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
import universalmotif as um
|
|
93
|
+
|
|
94
|
+
# A motif from a few aligned sites, and its log-odds matrix.
|
|
95
|
+
ap1 = um.create_motif(["TGACTCA", "TGAGTCA", "TGACTAA"], name="AP-1", pseudocount=1)
|
|
96
|
+
print(um.convert_type(ap1, "PWM").matrix)
|
|
97
|
+
|
|
98
|
+
# Scan sequences for the example motifs, and test them for enrichment
|
|
99
|
+
# against a set of control sequences.
|
|
100
|
+
motifs = um.example_motifs()
|
|
101
|
+
targets = um.example_sequences("targets")
|
|
102
|
+
controls = um.example_sequences("controls")
|
|
103
|
+
hits = um.scan_sequences(motifs, targets, pvalue=1e-4)
|
|
104
|
+
enriched = um.enrich_motifs(motifs, targets, controls)
|
|
105
|
+
|
|
106
|
+
# How similar are the motifs, and what do they look like?
|
|
107
|
+
similar = um.compare_motifs(motifs, compare_to="AP-1")
|
|
108
|
+
um.view_motifs(motifs[:4]).savefig("logos.png")
|
|
109
|
+
|
|
110
|
+
# Look for new motifs in the targets.
|
|
111
|
+
found = um.motif_finder(targets, controls, seed=1)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## What it can do
|
|
115
|
+
|
|
116
|
+
- **Motifs:** create them from sites, consensus strings or matrices, convert
|
|
117
|
+
between counts, probabilities, log-odds, information content and
|
|
118
|
+
contribution scores, and trim, round, merge, reverse complement and filter
|
|
119
|
+
them.
|
|
120
|
+
- **Files:** MEME, JASPAR, HOMER, TRANSFAC, CIS-BP, UniPROBE and plain
|
|
121
|
+
matrices, and FASTA for sequences, gzipped or not.
|
|
122
|
+
- **Databases:** motifs fetched from JASPAR, HOCOMOCO and CIS-BP and kept in
|
|
123
|
+
a local cache, and conversion to and from Biopython.
|
|
124
|
+
- **Scanning:** exact P-value thresholds, both strands, any alphabet and
|
|
125
|
+
gapped motifs, with whole genomes scanned from a FASTA file in a few
|
|
126
|
+
hundred MB.
|
|
127
|
+
- **Comparison:** similarity with P-values, scored either on the overlap or
|
|
128
|
+
on the whole query, merging of similar motifs, and trees.
|
|
129
|
+
- **Statistics:** enrichment, co-occurrence, positional enrichment,
|
|
130
|
+
proximity to genomic anchors, composition-matched backgrounds and *de
|
|
131
|
+
novo* motif discovery.
|
|
132
|
+
- **Genomes:** FASTA, bgzip and 2bit genomes read a piece at a time, the
|
|
133
|
+
sequences of peaks, bigWig signal over them, and hits moved back to
|
|
134
|
+
genomic coordinates, with ranges exchanged with PyRanges and polars-bio.
|
|
135
|
+
- **Single-cell ATAC and deep learning:** sparse peak by motif matrices for
|
|
136
|
+
AnnData and pychromVAR, motifs as convolution filters and back, one-hot
|
|
137
|
+
sequences, and TF-MoDISco results.
|
|
138
|
+
- **Sequences:** shuffling that keeps k-mer counts, random sequences, k-mer
|
|
139
|
+
backgrounds, complexity, masking and sliding windows.
|
|
140
|
+
- **Plots:** sequence logos, motif trees and plots of the results above,
|
|
141
|
+
with motifs shown as logos in Jupyter and SVG logos for reports.
|
|
142
|
+
|
|
143
|
+
Scanning, comparison, merging, clustering, enrichment and logos work for
|
|
144
|
+
amino acid and custom alphabets as well as DNA and RNA.
|
|
145
|
+
|
|
146
|
+
## Command line
|
|
147
|
+
|
|
148
|
+
The package also installs a command line, as both `universalmotif` and
|
|
149
|
+
`umotif`, which runs the main functions on files for shell scripts and
|
|
150
|
+
workflow managers:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
umotif fetch jaspar --tax-group plants --release 2024 -o jaspar.meme
|
|
154
|
+
umotif extract -g genome.fa.gz -r peaks.narrowPeak -o peaks.fa
|
|
155
|
+
umotif bkg -g genome.fa.gz -r peaks.narrowPeak --seed 1 -o bkg.fa
|
|
156
|
+
umotif enrich jaspar.meme -s peaks.fa -b bkg.fa -p 4 -o enriched.tsv
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`umotif --help` lists all 19 commands.
|
|
160
|
+
|
|
161
|
+
## Differences from the R package
|
|
162
|
+
|
|
163
|
+
Function names follow the R package, with underscores in place of dots, so
|
|
164
|
+
`min.ic` becomes `min_ic`. Where the R package has both a full and a `_lite`
|
|
165
|
+
version of a function, this package provides the lite one under the plain
|
|
166
|
+
name. Readers always return a list of motifs, and MEME site tables come
|
|
167
|
+
back as polars DataFrames. Functions that use random numbers take a `seed`,
|
|
168
|
+
but seeds do not reproduce the R package's results, since the two use
|
|
169
|
+
different random number generators.
|
|
170
|
+
|
|
171
|
+
Bugs found in the R package while porting it are fixed here rather than
|
|
172
|
+
reproduced.
|
|
173
|
+
[DIVERGENCES.md](https://github.com/bjmt/universalmotif-rs/blob/main/DIVERGENCES.md)
|
|
174
|
+
in the Rust crate lists the other differences, including the few features
|
|
175
|
+
left out on purpose.
|
|
176
|
+
|
|
177
|
+
## Documentation
|
|
178
|
+
|
|
179
|
+
The documentation lives at <https://bjmt.github.io/universalmotif-py/>. It is built with MkDocs from `docs/`,
|
|
180
|
+
with the API reference generated from the docstrings and guides written as
|
|
181
|
+
notebooks. To build it and preview it locally:
|
|
182
|
+
|
|
183
|
+
```sh
|
|
184
|
+
uv sync --group docs --no-install-project
|
|
185
|
+
uv run --no-sync maturin develop --release
|
|
186
|
+
uv run --no-sync mkdocs serve
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
Development uses [uv](https://docs.astral.sh/uv/) and
|
|
192
|
+
[maturin](https://www.maturin.rs/), with the Rust crate checked out next to
|
|
193
|
+
this one, since the package builds against it and the tests read the R
|
|
194
|
+
reference values kept there:
|
|
195
|
+
|
|
196
|
+
```sh
|
|
197
|
+
git clone https://github.com/bjmt/universalmotif-rs.git
|
|
198
|
+
git clone https://github.com/bjmt/universalmotif-py.git
|
|
199
|
+
cd universalmotif-py
|
|
200
|
+
uv sync --group dev --no-install-project
|
|
201
|
+
uv run --no-sync maturin develop --release
|
|
202
|
+
uv run --no-sync pytest
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Citation
|
|
206
|
+
|
|
207
|
+
If this package has been useful for your research, please cite the article
|
|
208
|
+
describing universalmotif:
|
|
209
|
+
|
|
210
|
+
Tremblay BJM (2024). universalmotif: An R package for biological motif
|
|
211
|
+
analysis. *Journal of Open Source Software* **9**, 7012.
|
|
212
|
+
DOI: [10.21105/joss.07012](https://doi.org/10.21105/joss.07012)
|
|
213
|
+
|
|
214
|
+
## Licence
|
|
215
|
+
|
|
216
|
+
MIT. The letter shapes used in logos are outlines of the Roboto font,
|
|
217
|
+
released under the Apache License 2.0, and were exported from the R
|
|
218
|
+
package's `fontDFroboto` with `scripts/make_font.R`.
|
|
219
|
+
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# universalmotif (Python)
|
|
2
|
+
|
|
3
|
+
A Python package for working with sequence motifs: creating them, converting
|
|
4
|
+
between their representations, reading and writing them in the common file
|
|
5
|
+
formats, and using them to scan, compare and test sequences. It is a port of
|
|
6
|
+
the [universalmotif](https://bioconductor.org/packages/universalmotif/)
|
|
7
|
+
R/Bioconductor package, built on its Rust version,
|
|
8
|
+
[universalmotif-rs](https://github.com/bjmt/universalmotif-rs), which does
|
|
9
|
+
the heavy lifting, so most of it is quick and can use several threads.
|
|
10
|
+
Motifs are `Motif` objects, matrices come back as numpy arrays, and tables
|
|
11
|
+
come back as [polars](https://pola.rs/) DataFrames.
|
|
12
|
+
|
|
13
|
+
The [documentation](https://bjmt.github.io/universalmotif-py/) has guides
|
|
14
|
+
covering everything from motif basics to a full ChIP-seq analysis, and a
|
|
15
|
+
reference for every function. The package is at an early version, and its
|
|
16
|
+
interface may still change.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
The package needs Python 3.10 or later and can be installed from PyPI:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
pip install universalmotif
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Wheels are built for Linux (x86_64 and aarch64), macOS (Intel and Apple
|
|
27
|
+
Silicon) and Windows (x86_64). Elsewhere pip builds the package from source,
|
|
28
|
+
which needs a [Rust toolchain](https://rustup.rs/).
|
|
29
|
+
|
|
30
|
+
The only required dependencies are numpy and polars. Everything else is an
|
|
31
|
+
optional extra, needed only by the functions that use it, so that for
|
|
32
|
+
example `pip install "universalmotif[plot]"` adds matplotlib for drawing
|
|
33
|
+
logos:
|
|
34
|
+
|
|
35
|
+
| Extra | Brings in | For |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| `plot` | matplotlib | logos, trees and the other plots |
|
|
38
|
+
| `scipy` | SciPy | sparse motif match matrices |
|
|
39
|
+
| `anndata` | AnnData, SciPy | match matrices stored with single-cell ATAC data |
|
|
40
|
+
| `biopython` | Biopython | converting to and from `Bio.motifs` |
|
|
41
|
+
| `h5py` | h5py | reading TF-MoDISco results |
|
|
42
|
+
| `bigwig` | pybigtools | bigWig signal, and backgrounds matched on it |
|
|
43
|
+
| `pyranges` | PyRanges | converting tables to PyRanges objects |
|
|
44
|
+
| `polars-bio` | polars-bio | preparing tables for polars-bio |
|
|
45
|
+
| `pandas` | pandas, pyarrow | pandas DataFrames, and logomaker export |
|
|
46
|
+
|
|
47
|
+
## A quick look
|
|
48
|
+
|
|
49
|
+
Using the example motifs and sequences that come with the package:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import universalmotif as um
|
|
53
|
+
|
|
54
|
+
# A motif from a few aligned sites, and its log-odds matrix.
|
|
55
|
+
ap1 = um.create_motif(["TGACTCA", "TGAGTCA", "TGACTAA"], name="AP-1", pseudocount=1)
|
|
56
|
+
print(um.convert_type(ap1, "PWM").matrix)
|
|
57
|
+
|
|
58
|
+
# Scan sequences for the example motifs, and test them for enrichment
|
|
59
|
+
# against a set of control sequences.
|
|
60
|
+
motifs = um.example_motifs()
|
|
61
|
+
targets = um.example_sequences("targets")
|
|
62
|
+
controls = um.example_sequences("controls")
|
|
63
|
+
hits = um.scan_sequences(motifs, targets, pvalue=1e-4)
|
|
64
|
+
enriched = um.enrich_motifs(motifs, targets, controls)
|
|
65
|
+
|
|
66
|
+
# How similar are the motifs, and what do they look like?
|
|
67
|
+
similar = um.compare_motifs(motifs, compare_to="AP-1")
|
|
68
|
+
um.view_motifs(motifs[:4]).savefig("logos.png")
|
|
69
|
+
|
|
70
|
+
# Look for new motifs in the targets.
|
|
71
|
+
found = um.motif_finder(targets, controls, seed=1)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## What it can do
|
|
75
|
+
|
|
76
|
+
- **Motifs:** create them from sites, consensus strings or matrices, convert
|
|
77
|
+
between counts, probabilities, log-odds, information content and
|
|
78
|
+
contribution scores, and trim, round, merge, reverse complement and filter
|
|
79
|
+
them.
|
|
80
|
+
- **Files:** MEME, JASPAR, HOMER, TRANSFAC, CIS-BP, UniPROBE and plain
|
|
81
|
+
matrices, and FASTA for sequences, gzipped or not.
|
|
82
|
+
- **Databases:** motifs fetched from JASPAR, HOCOMOCO and CIS-BP and kept in
|
|
83
|
+
a local cache, and conversion to and from Biopython.
|
|
84
|
+
- **Scanning:** exact P-value thresholds, both strands, any alphabet and
|
|
85
|
+
gapped motifs, with whole genomes scanned from a FASTA file in a few
|
|
86
|
+
hundred MB.
|
|
87
|
+
- **Comparison:** similarity with P-values, scored either on the overlap or
|
|
88
|
+
on the whole query, merging of similar motifs, and trees.
|
|
89
|
+
- **Statistics:** enrichment, co-occurrence, positional enrichment,
|
|
90
|
+
proximity to genomic anchors, composition-matched backgrounds and *de
|
|
91
|
+
novo* motif discovery.
|
|
92
|
+
- **Genomes:** FASTA, bgzip and 2bit genomes read a piece at a time, the
|
|
93
|
+
sequences of peaks, bigWig signal over them, and hits moved back to
|
|
94
|
+
genomic coordinates, with ranges exchanged with PyRanges and polars-bio.
|
|
95
|
+
- **Single-cell ATAC and deep learning:** sparse peak by motif matrices for
|
|
96
|
+
AnnData and pychromVAR, motifs as convolution filters and back, one-hot
|
|
97
|
+
sequences, and TF-MoDISco results.
|
|
98
|
+
- **Sequences:** shuffling that keeps k-mer counts, random sequences, k-mer
|
|
99
|
+
backgrounds, complexity, masking and sliding windows.
|
|
100
|
+
- **Plots:** sequence logos, motif trees and plots of the results above,
|
|
101
|
+
with motifs shown as logos in Jupyter and SVG logos for reports.
|
|
102
|
+
|
|
103
|
+
Scanning, comparison, merging, clustering, enrichment and logos work for
|
|
104
|
+
amino acid and custom alphabets as well as DNA and RNA.
|
|
105
|
+
|
|
106
|
+
## Command line
|
|
107
|
+
|
|
108
|
+
The package also installs a command line, as both `universalmotif` and
|
|
109
|
+
`umotif`, which runs the main functions on files for shell scripts and
|
|
110
|
+
workflow managers:
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
umotif fetch jaspar --tax-group plants --release 2024 -o jaspar.meme
|
|
114
|
+
umotif extract -g genome.fa.gz -r peaks.narrowPeak -o peaks.fa
|
|
115
|
+
umotif bkg -g genome.fa.gz -r peaks.narrowPeak --seed 1 -o bkg.fa
|
|
116
|
+
umotif enrich jaspar.meme -s peaks.fa -b bkg.fa -p 4 -o enriched.tsv
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`umotif --help` lists all 19 commands.
|
|
120
|
+
|
|
121
|
+
## Differences from the R package
|
|
122
|
+
|
|
123
|
+
Function names follow the R package, with underscores in place of dots, so
|
|
124
|
+
`min.ic` becomes `min_ic`. Where the R package has both a full and a `_lite`
|
|
125
|
+
version of a function, this package provides the lite one under the plain
|
|
126
|
+
name. Readers always return a list of motifs, and MEME site tables come
|
|
127
|
+
back as polars DataFrames. Functions that use random numbers take a `seed`,
|
|
128
|
+
but seeds do not reproduce the R package's results, since the two use
|
|
129
|
+
different random number generators.
|
|
130
|
+
|
|
131
|
+
Bugs found in the R package while porting it are fixed here rather than
|
|
132
|
+
reproduced.
|
|
133
|
+
[DIVERGENCES.md](https://github.com/bjmt/universalmotif-rs/blob/main/DIVERGENCES.md)
|
|
134
|
+
in the Rust crate lists the other differences, including the few features
|
|
135
|
+
left out on purpose.
|
|
136
|
+
|
|
137
|
+
## Documentation
|
|
138
|
+
|
|
139
|
+
The documentation lives at <https://bjmt.github.io/universalmotif-py/>. It is built with MkDocs from `docs/`,
|
|
140
|
+
with the API reference generated from the docstrings and guides written as
|
|
141
|
+
notebooks. To build it and preview it locally:
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
uv sync --group docs --no-install-project
|
|
145
|
+
uv run --no-sync maturin develop --release
|
|
146
|
+
uv run --no-sync mkdocs serve
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Development
|
|
150
|
+
|
|
151
|
+
Development uses [uv](https://docs.astral.sh/uv/) and
|
|
152
|
+
[maturin](https://www.maturin.rs/), with the Rust crate checked out next to
|
|
153
|
+
this one, since the package builds against it and the tests read the R
|
|
154
|
+
reference values kept there:
|
|
155
|
+
|
|
156
|
+
```sh
|
|
157
|
+
git clone https://github.com/bjmt/universalmotif-rs.git
|
|
158
|
+
git clone https://github.com/bjmt/universalmotif-py.git
|
|
159
|
+
cd universalmotif-py
|
|
160
|
+
uv sync --group dev --no-install-project
|
|
161
|
+
uv run --no-sync maturin develop --release
|
|
162
|
+
uv run --no-sync pytest
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Citation
|
|
166
|
+
|
|
167
|
+
If this package has been useful for your research, please cite the article
|
|
168
|
+
describing universalmotif:
|
|
169
|
+
|
|
170
|
+
Tremblay BJM (2024). universalmotif: An R package for biological motif
|
|
171
|
+
analysis. *Journal of Open Source Software* **9**, 7012.
|
|
172
|
+
DOI: [10.21105/joss.07012](https://doi.org/10.21105/joss.07012)
|
|
173
|
+
|
|
174
|
+
## Licence
|
|
175
|
+
|
|
176
|
+
MIT. The letter shapes used in logos are outlines of the Roboto font,
|
|
177
|
+
released under the Apache License 2.0, and were exported from the R
|
|
178
|
+
package's `fontDFroboto` with `scripts/make_font.R`.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["maturin>=1.9,<2"]
|
|
3
|
+
build-backend = "maturin"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "universalmotif"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Sequence motif manipulation and analysis, a Python port of universalmotif"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
authors = [{ name = "Benjamin Jean-Marie Tremblay" }]
|
|
14
|
+
keywords = ["bioinformatics", "motif", "pwm", "genomics"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Rust",
|
|
18
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
19
|
+
]
|
|
20
|
+
dependencies = ["numpy>=1.24", "polars>=1.0"]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Documentation = "https://bjmt.github.io/universalmotif-py/"
|
|
24
|
+
Repository = "https://github.com/bjmt/universalmotif-py"
|
|
25
|
+
Changelog = "https://bjmt.github.io/universalmotif-py/changelog/"
|
|
26
|
+
Issues = "https://github.com/bjmt/universalmotif-py/issues"
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
universalmotif = "universalmotif._cli:main"
|
|
30
|
+
umotif = "universalmotif._cli:main"
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
anndata = ["anndata>=0.10", "scipy>=1.11"]
|
|
34
|
+
bigwig = ["pybigtools>=0.3"]
|
|
35
|
+
biopython = ["biopython>=1.81"]
|
|
36
|
+
h5py = ["h5py>=3.0"]
|
|
37
|
+
pandas = ["pandas>=2.0", "pyarrow>=14"]
|
|
38
|
+
plot = ["matplotlib>=3.8"]
|
|
39
|
+
polars-bio = ["polars-bio>=0.36; python_version >= '3.11' and python_version < '3.15'"]
|
|
40
|
+
pyranges = ["pyranges1>=1.0; python_version >= '3.12'"]
|
|
41
|
+
scipy = ["scipy>=1.11"]
|
|
42
|
+
|
|
43
|
+
[dependency-groups]
|
|
44
|
+
dev = [
|
|
45
|
+
"anndata>=0.10",
|
|
46
|
+
"biopython>=1.81",
|
|
47
|
+
"h5py>=3.0",
|
|
48
|
+
"maturin>=1.9,<2",
|
|
49
|
+
"matplotlib>=3.8",
|
|
50
|
+
"pandas>=2.0",
|
|
51
|
+
"polars-bio>=0.36; python_version >= '3.11' and python_version < '3.15'",
|
|
52
|
+
"pybigtools>=0.3",
|
|
53
|
+
"pyranges1>=1.0; python_version >= '3.12'",
|
|
54
|
+
"pytest>=8",
|
|
55
|
+
"scipy>=1.15.3",
|
|
56
|
+
]
|
|
57
|
+
docs = [
|
|
58
|
+
"maturin>=1.9,<2",
|
|
59
|
+
"matplotlib>=3.8",
|
|
60
|
+
# MkDocs 2 drops the plugin system these rely on.
|
|
61
|
+
"mkdocs>=1.6,<2",
|
|
62
|
+
"mkdocs-material>=9.5",
|
|
63
|
+
"mkdocstrings[python]>=0.27",
|
|
64
|
+
"mkdocs-jupyter>=0.25",
|
|
65
|
+
"ipykernel>=6.29",
|
|
66
|
+
"ruff>=0.6",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[tool.maturin]
|
|
70
|
+
module-name = "universalmotif._core"
|
|
71
|
+
features = ["pyo3/extension-module"]
|
|
72
|
+
# The docs, guides and CI files are not needed to build or use the package.
|
|
73
|
+
exclude = [
|
|
74
|
+
{ path = "docs/**/*", format = "sdist" },
|
|
75
|
+
{ path = "hooks/**/*", format = "sdist" },
|
|
76
|
+
{ path = "scripts/**/*", format = "sdist" },
|
|
77
|
+
{ path = ".github/**/*", format = "sdist" },
|
|
78
|
+
{ path = "mkdocs.yml", format = "sdist" },
|
|
79
|
+
]
|
|
80
|
+
manifest-path = "universalmotif-py/Cargo.toml"
|
|
81
|
+
python-source = "python"
|
|
82
|
+
|
|
83
|
+
[tool.pytest.ini_options]
|
|
84
|
+
testpaths = ["tests", "python/universalmotif"]
|
|
85
|
+
# Docstring examples run as tests too.
|
|
86
|
+
addopts = "--doctest-modules"
|
|
87
|
+
# The package warns about inputs that silently give empty or odd results, so
|
|
88
|
+
# a warning in a test is an error unless the test expects it.
|
|
89
|
+
filterwarnings = ["error::UserWarning"]
|