aberrant-expression 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.
- aberrant_expression-0.1.0/LICENSE +48 -0
- aberrant_expression-0.1.0/MANIFEST.in +4 -0
- aberrant_expression-0.1.0/PKG-INFO +451 -0
- aberrant_expression-0.1.0/README.md +395 -0
- aberrant_expression-0.1.0/pyproject.toml +129 -0
- aberrant_expression-0.1.0/setup.cfg +4 -0
- aberrant_expression-0.1.0/src/aberrant_expression.egg-info/PKG-INFO +451 -0
- aberrant_expression-0.1.0/src/aberrant_expression.egg-info/SOURCES.txt +93 -0
- aberrant_expression-0.1.0/src/aberrant_expression.egg-info/dependency_links.txt +1 -0
- aberrant_expression-0.1.0/src/aberrant_expression.egg-info/requires.txt +53 -0
- aberrant_expression-0.1.0/src/aberrant_expression.egg-info/top_level.txt +1 -0
- aberrant_expression-0.1.0/src/abexp/__init__.py +12 -0
- aberrant_expression-0.1.0/src/abexp/absplice/__init__.py +21 -0
- aberrant_expression-0.1.0/src/abexp/absplice/dataloader.py +153 -0
- aberrant_expression-0.1.0/src/abexp/absplice/model.py +75 -0
- aberrant_expression-0.1.0/src/abexp/absplice/precomputed/AbSplice_DNA.onnx +0 -0
- aberrant_expression-0.1.0/src/abexp/absplice/precomputed/GENE_MAP.tsv.gz +0 -0
- aberrant_expression-0.1.0/src/abexp/absplice/result.py +307 -0
- aberrant_expression-0.1.0/src/abexp/absplice/splicemap.py +105 -0
- aberrant_expression-0.1.0/src/abexp/absplice/utils.py +76 -0
- aberrant_expression-0.1.0/src/abexp/absplice2/__init__.py +17 -0
- aberrant_expression-0.1.0/src/abexp/absplice2/dna.py +273 -0
- aberrant_expression-0.1.0/src/abexp/enformer/__init__.py +0 -0
- aberrant_expression-0.1.0/src/abexp/enformer/constants.py +6 -0
- aberrant_expression-0.1.0/src/abexp/enformer/dataloader/__init__.py +1 -0
- aberrant_expression-0.1.0/src/abexp/enformer/dataloader/dataloader.py +214 -0
- aberrant_expression-0.1.0/src/abexp/enformer/dataloader/tss_dataloader.py +266 -0
- aberrant_expression-0.1.0/src/abexp/enformer/enformer.py +551 -0
- aberrant_expression-0.1.0/src/abexp/enformer/logger.py +13 -0
- aberrant_expression-0.1.0/src/abexp/enformer/utils.py +78 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/__init__.py +21 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/batching.py +51 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/dataloader.py +432 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/layers.py +107 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/model.py +104 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/models/Acceptor.h5 +0 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/models/Donor.h5 +0 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/models/Exon.h5 +0 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/models/Intron3.h5 +0 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/models/Intron5.h5 +0 -0
- aberrant_expression-0.1.0/src/abexp/mmsplice/utils.py +140 -0
- aberrant_expression-0.1.0/src/abexp/pangolin/__init__.py +23 -0
- aberrant_expression-0.1.0/src/abexp/pangolin/annotation.py +42 -0
- aberrant_expression-0.1.0/src/abexp/pangolin/model.py +165 -0
- aberrant_expression-0.1.0/src/abexp/pangolin/pangolin.py +262 -0
- aberrant_expression-0.1.0/src/abexp/pangolin/weights.py +95 -0
- aberrant_expression-0.1.0/src/abexp/spliceai_rocksdb/__init__.py +11 -0
- aberrant_expression-0.1.0/src/abexp/spliceai_rocksdb/spliceai.py +194 -0
- aberrant_expression-0.1.0/src/abexp/utils/__init__.py +0 -0
- aberrant_expression-0.1.0/src/abexp/utils/common.py +16 -0
- aberrant_expression-0.1.0/src/abexp/utils/gff3.py +51 -0
- aberrant_expression-0.1.0/src/abexp/utils/models/__init__.py +1 -0
- aberrant_expression-0.1.0/src/abexp/utils/models/wrappers.py +104 -0
- aberrant_expression-0.1.0/src/abexp/utils/polars_functions/__init__.py +13 -0
- aberrant_expression-0.1.0/src/abexp/utils/polars_functions/featureset.py +188 -0
- aberrant_expression-0.1.0/src/abexp/utils/polars_functions/reshape.py +116 -0
- aberrant_expression-0.1.0/src/abexp/utils/polars_functions/write.py +10 -0
- aberrant_expression-0.1.0/src/abexp/utils/spark_functions/__init__.py +14 -0
- aberrant_expression-0.1.0/src/abexp/utils/spark_functions/featureset.py +178 -0
- aberrant_expression-0.1.0/src/abexp/utils/spark_functions/reshape.py +248 -0
- aberrant_expression-0.1.0/tests/absplice2/constellations.py +253 -0
- aberrant_expression-0.1.0/tests/absplice2/make_expected.py +169 -0
- aberrant_expression-0.1.0/tests/absplice2/test_absplice2.py +181 -0
- aberrant_expression-0.1.0/tests/enformer/conftest.py +69 -0
- aberrant_expression-0.1.0/tests/enformer/test_dataloader.py +56 -0
- aberrant_expression-0.1.0/tests/enformer/test_enformer.py +530 -0
- aberrant_expression-0.1.0/tests/enformer/test_tss_dataloader.py +579 -0
- aberrant_expression-0.1.0/tests/pangolin/conftest.py +5 -0
- aberrant_expression-0.1.0/tests/pangolin/data/chr22_excerpt.fa +258 -0
- aberrant_expression-0.1.0/tests/pangolin/data/chr22_excerpt.gff3 +15 -0
- aberrant_expression-0.1.0/tests/pangolin/grch38_excerpt.py +83 -0
- aberrant_expression-0.1.0/tests/pangolin/make_expected.py +111 -0
- aberrant_expression-0.1.0/tests/pangolin/make_expected_published.py +77 -0
- aberrant_expression-0.1.0/tests/pangolin/synthetic.py +149 -0
- aberrant_expression-0.1.0/tests/pangolin/test_pangolin.py +263 -0
- aberrant_expression-0.1.0/tests/pangolin/test_published_weights.py +145 -0
- aberrant_expression-0.1.0/tests/pangolin/test_weights.py +57 -0
- aberrant_expression-0.1.0/tests/splicing/conftest.py +42 -0
- aberrant_expression-0.1.0/tests/splicing/data/Whole_Blood_splicemap_psi3.csv.gz +0 -0
- aberrant_expression-0.1.0/tests/splicing/data/Whole_Blood_splicemap_psi5.csv.gz +0 -0
- aberrant_expression-0.1.0/tests/splicing/data/clinvar_chr22.spliceai.vcf +24 -0
- aberrant_expression-0.1.0/tests/splicing/data/clinvar_chr22.vcf +22 -0
- aberrant_expression-0.1.0/tests/splicing/data/expected/absplice_dna.csv +25 -0
- aberrant_expression-0.1.0/tests/splicing/data/expected/junction_samples.jsonl +59 -0
- aberrant_expression-0.1.0/tests/splicing/data/expected/mmsplice_modular_scores.csv +3 -0
- aberrant_expression-0.1.0/tests/splicing/data/expected/mmsplice_splicemap.csv +66 -0
- aberrant_expression-0.1.0/tests/splicing/data/expected/spliceai_rocksdb.csv +22 -0
- aberrant_expression-0.1.0/tests/splicing/data/expected/spliceai_vcf.csv +24 -0
- aberrant_expression-0.1.0/tests/splicing/make_expected.py +118 -0
- aberrant_expression-0.1.0/tests/splicing/test_absplice.py +263 -0
- aberrant_expression-0.1.0/tests/splicing/test_mmsplice.py +134 -0
- aberrant_expression-0.1.0/tests/splicing/test_spliceai_rocksdb.py +98 -0
- aberrant_expression-0.1.0/tests/utils/test_gff3.py +126 -0
- aberrant_expression-0.1.0/tests/utils/test_polars.py +174 -0
- aberrant_expression-0.1.0/tests/utils/test_spark.py +357 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023-2026 Gagneur lab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
-------------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
This package contains code and model files ported from the following projects.
|
|
26
|
+
They are under the MIT License with the terms above.
|
|
27
|
+
|
|
28
|
+
mmsplice 2.4.0, https://github.com/gagneurlab/MMSplice_MTSplice, commit 31513da:
|
|
29
|
+
src/abexp/mmsplice, including the model files in src/abexp/mmsplice/models
|
|
30
|
+
Copyright (c) 2018, Jun Cheng
|
|
31
|
+
|
|
32
|
+
kipoi-utils 0.7.7, https://github.com/kipoi/kipoi-utils:
|
|
33
|
+
src/abexp/mmsplice/batching.py
|
|
34
|
+
Copyright (c) 2019 Kipoi team
|
|
35
|
+
|
|
36
|
+
absplice, https://github.com/gagneurlab/absplice, commit daad7b6:
|
|
37
|
+
src/abexp/absplice, including the AbSplice-DNA model src/abexp/absplice/precomputed/AbSplice_DNA.onnx
|
|
38
|
+
and the gene table src/abexp/absplice/precomputed/GENE_MAP.tsv.gz
|
|
39
|
+
Copyright (c) 2023 Muhammed Hasan Çelik and Nils Wagner
|
|
40
|
+
|
|
41
|
+
splicemap, https://github.com/gagneurlab/splicemap, commit cf922eb:
|
|
42
|
+
src/abexp/absplice/splicemap.py
|
|
43
|
+
Copyright (c) 2023 Muhammed Hasan Çelik and Nils Wagner
|
|
44
|
+
|
|
45
|
+
spliceai_rocksdb, https://github.com/gagneurlab/spliceai_rocksdb, commit 3c40d6e:
|
|
46
|
+
src/abexp/spliceai_rocksdb
|
|
47
|
+
The repository has no license file; its setup.py declares license="MIT license" and the author
|
|
48
|
+
M. Hasan Çelik.
|
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aberrant-expression
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Utilities, Enformer, MMSplice, AbSplice-DNA, SpliceAI-RocksDB, Pangolin and AbSplice2-DNA for the AbExp pipeline
|
|
5
|
+
Author: Jun Cheng, Muhammed Hasan Çelik, Nils Wagner
|
|
6
|
+
Author-email: Florian Hölzlwimmer <git.ich@frhoelzlwimmer.de>, George Tsitsiridis <gtsitsiridis@gmail.com>
|
|
7
|
+
Maintainer-email: Florian Hölzlwimmer <git.ich@frhoelzlwimmer.de>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/gagneurlab/AbExp
|
|
10
|
+
Project-URL: Source, https://github.com/gagneurlab/AbExp/tree/main/packages/aberrant_expression
|
|
11
|
+
Project-URL: Issues, https://github.com/gagneurlab/AbExp/issues
|
|
12
|
+
Keywords: aberrant expression,variant effect prediction,splicing,mmsplice,absplice,spliceai,pangolin,enformer,deep learning,computational biology,bioinformatics,genomics
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Provides-Extra: models
|
|
17
|
+
Requires-Dist: aberrant-expression[numpy]; extra == "models"
|
|
18
|
+
Requires-Dist: scikit-learn>=1.4.1.post1; extra == "models"
|
|
19
|
+
Provides-Extra: polars
|
|
20
|
+
Requires-Dist: polars>=1.44; extra == "polars"
|
|
21
|
+
Provides-Extra: spark
|
|
22
|
+
Requires-Dist: pyspark>=3.4; extra == "spark"
|
|
23
|
+
Requires-Dist: pandas; extra == "spark"
|
|
24
|
+
Provides-Extra: gff3
|
|
25
|
+
Requires-Dist: aberrant-expression[polars]; extra == "gff3"
|
|
26
|
+
Requires-Dist: polars-bio>=0.36.0; extra == "gff3"
|
|
27
|
+
Provides-Extra: splicing
|
|
28
|
+
Requires-Dist: aberrant-expression[kipoiseq2,numpy,polars,tensorflow,tqdm]; extra == "splicing"
|
|
29
|
+
Requires-Dist: onnxruntime; extra == "splicing"
|
|
30
|
+
Provides-Extra: rocksdb
|
|
31
|
+
Requires-Dist: aberrant-expression[splicing]; extra == "rocksdb"
|
|
32
|
+
Requires-Dist: python-rocksdb>=0.7; extra == "rocksdb"
|
|
33
|
+
Provides-Extra: enformer
|
|
34
|
+
Requires-Dist: aberrant-expression[gff3,kipoiseq2,models,tensorflow,tqdm]; extra == "enformer"
|
|
35
|
+
Requires-Dist: kagglehub; extra == "enformer"
|
|
36
|
+
Requires-Dist: pyarrow; extra == "enformer"
|
|
37
|
+
Requires-Dist: xarray>=2024.5.0; extra == "enformer"
|
|
38
|
+
Requires-Dist: zarr>=2.15.0; extra == "enformer"
|
|
39
|
+
Requires-Dist: pyyaml; extra == "enformer"
|
|
40
|
+
Provides-Extra: pangolin
|
|
41
|
+
Requires-Dist: aberrant-expression[gff3,kipoiseq2,numpy]; extra == "pangolin"
|
|
42
|
+
Requires-Dist: torch>=2.4; extra == "pangolin"
|
|
43
|
+
Provides-Extra: absplice2
|
|
44
|
+
Requires-Dist: aberrant-expression[polars]; extra == "absplice2"
|
|
45
|
+
Provides-Extra: all
|
|
46
|
+
Requires-Dist: aberrant-expression[absplice2,enformer,gff3,models,pangolin,polars,spark,splicing]; extra == "all"
|
|
47
|
+
Provides-Extra: numpy
|
|
48
|
+
Requires-Dist: numpy>=1.26.4; extra == "numpy"
|
|
49
|
+
Provides-Extra: kipoiseq2
|
|
50
|
+
Requires-Dist: kipoiseq2[ranges]<0.2,>=0.1; extra == "kipoiseq2"
|
|
51
|
+
Provides-Extra: tensorflow
|
|
52
|
+
Requires-Dist: tensorflow>=2.14.0; extra == "tensorflow"
|
|
53
|
+
Provides-Extra: tqdm
|
|
54
|
+
Requires-Dist: tqdm; extra == "tqdm"
|
|
55
|
+
Dynamic: license-file
|
|
56
|
+
|
|
57
|
+
# aberrant-expression
|
|
58
|
+
|
|
59
|
+
tl;dr: The Python packages of the [AbExp](https://github.com/gagneurlab/AbExp) pipeline, in one distribution. pip
|
|
60
|
+
installs it as `aberrant-expression`, and Python imports it as `abexp`. The base has no dependencies and covers
|
|
61
|
+
`abexp.utils.common`; each extra adds the dependencies of other subpackages.
|
|
62
|
+
|
|
63
|
+
| import | contents | extra |
|
|
64
|
+
| ------------------------ | ----------------------------------------------------------------------------------------- | ---------- |
|
|
65
|
+
| `abexp.utils` | functions on polars and Spark DataFrames, a GFF3 reader, and the scikit-learn model wrappers of AbExp | `polars`, `spark`, `gff3`, `models` |
|
|
66
|
+
| `abexp.enformer` | variant effect prediction of promoter variants with Enformer | `enformer` |
|
|
67
|
+
| `abexp.mmsplice` | MMSplice and the junction VCF dataloaders | `splicing` |
|
|
68
|
+
| `abexp.absplice` | AbSplice-DNA from MMSplice with SpliceMaps and from SpliceAI | `splicing` |
|
|
69
|
+
| `abexp.spliceai_rocksdb` | SpliceAI scores from SpliceAI-RocksDB | `rocksdb` |
|
|
70
|
+
| `abexp.pangolin` | Pangolin's splice scores per variant and gene, with the published weights of Pangolin | `pangolin` |
|
|
71
|
+
| `abexp.absplice2` | AbSplice2-DNA from Pangolin and from MMSplice with SpliceMaps | `absplice2` |
|
|
72
|
+
|
|
73
|
+
`abexp.utils` and `abexp.enformer` were the distributions abexp-utils (`abexp_utils`) and kipoi-enformer
|
|
74
|
+
(`kipoi_enformer`). `abexp.mmsplice`, `abexp.absplice` and `abexp.spliceai_rocksdb` were the distribution
|
|
75
|
+
abexp-splicing. The modules keep their paths below the new top level, e.g. `kipoi_enformer.enformer` is now
|
|
76
|
+
`abexp.enformer.enformer`.
|
|
77
|
+
|
|
78
|
+
The name `abexp` on PyPI belongs to an unrelated library, which also installs into `site-packages/abexp`. So the two
|
|
79
|
+
cannot share an environment.
|
|
80
|
+
|
|
81
|
+
## Installation
|
|
82
|
+
|
|
83
|
+
Install a release from the AbExp repository with pip. Choose the extras you need:
|
|
84
|
+
|
|
85
|
+
<!-- x-release-please-start-version -->
|
|
86
|
+
```bash
|
|
87
|
+
pip install "aberrant-expression[polars] @ git+https://github.com/gagneurlab/AbExp.git@aberrant-expression-v0.1.0#subdirectory=packages/aberrant_expression"
|
|
88
|
+
```
|
|
89
|
+
<!-- x-release-please-end -->
|
|
90
|
+
|
|
91
|
+
| extra | for |
|
|
92
|
+
| ---------- | ------------------------------------------------------------------------- |
|
|
93
|
+
| `models` | `abexp.utils.models` |
|
|
94
|
+
| `polars` | `abexp.utils.polars_functions` |
|
|
95
|
+
| `spark` | `abexp.utils.spark_functions`. The Spark functions need a Java runtime; pyspark 4 requires Java 17 or newer. |
|
|
96
|
+
| `gff3` | `abexp.utils.gff3` |
|
|
97
|
+
| `splicing` | `abexp.mmsplice` and `abexp.absplice` |
|
|
98
|
+
| `rocksdb` | `abexp.spliceai_rocksdb`, with `splicing` |
|
|
99
|
+
| `pangolin` | `abexp.pangolin`. conda-forge has PyTorch as `pytorch-cpu` and `pytorch-gpu`. |
|
|
100
|
+
| `absplice2` | `abexp.absplice2` |
|
|
101
|
+
| `enformer` | `abexp.enformer`. For GPU support on Linux, also install `tensorflow[and-cuda]`. |
|
|
102
|
+
| `all` | all extras but `rocksdb` |
|
|
103
|
+
| `numpy`, `kipoiseq2`, `tensorflow`, `tqdm` | one requirement each, which several extras share |
|
|
104
|
+
|
|
105
|
+
The extra `rocksdb` installs python-rocksdb, which pip builds only with the RocksDB library installed; conda-forge
|
|
106
|
+
has a build of it. SpliceAI predictions of the variants that are not in SpliceAI-RocksDB also need SpliceAI.
|
|
107
|
+
Install it separately. The AbExp pipeline uses the SpliceAI fork [hoeze/SpliceAI](https://github.com/hoeze/SpliceAI),
|
|
108
|
+
which also predicts multi-nucleotide variants:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pip install "spliceai @ git+https://github.com/hoeze/SpliceAI.git@e3470ae185d1418fe40cf35e8c4e33431cbc5df2"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
For development, use the uv workspace of a checkout of AbExp. In the root of the checkout, this installs the
|
|
115
|
+
package in editable mode, with all extras but `rocksdb` and with the dependency group `test` for the tests:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
uv sync --extra all --group test
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Add `--extra rocksdb` if you work on `abexp.spliceai_rocksdb`.
|
|
122
|
+
[packages/README.md](https://github.com/gagneurlab/AbExp/blob/main/packages/README.md) in the AbExp repository
|
|
123
|
+
describes the workspace and the tests.
|
|
124
|
+
|
|
125
|
+
## abexp.utils
|
|
126
|
+
|
|
127
|
+
`abexp.utils.polars_functions` and `abexp.utils.spark_functions` reshape polars and Spark DataFrames and join the
|
|
128
|
+
feature sets of AbExp. `abexp.utils.models` holds the scikit-learn model wrappers of the AbExp models, and needs the
|
|
129
|
+
extra `models`. `abexp.utils.gff3` reads GFF3 files with polars-bio for `abexp.enformer` and `abexp.pangolin`, and
|
|
130
|
+
needs the extra `gff3`. With `par_y_suffix=True`, it adds the suffix `_PAR_Y` to `gene_id` and `transcript_id` of the
|
|
131
|
+
chrY PAR copies, as `abexp.enformer` does.
|
|
132
|
+
|
|
133
|
+
## abexp.enformer
|
|
134
|
+
|
|
135
|
+
### Enformer model
|
|
136
|
+
|
|
137
|
+
`Enformer()` loads the Enformer model from Kaggle Models with kagglehub, under the handle
|
|
138
|
+
`deepmind/enformer/tensorFlow2/enformer/1`. These are the same files that TF Hub served at
|
|
139
|
+
`https://tfhub.dev/deepmind/enformer/1`. On first use, kagglehub downloads the model, about 1 GB, and caches it in
|
|
140
|
+
`~/.cache/kagglehub`. Set `KAGGLEHUB_CACHE` to use another directory. Once the model is cached, kagglehub loads it
|
|
141
|
+
without contacting Kaggle. kipoi-enformer 0.0.1 downloaded the model with tensorflow-hub instead and cached it in
|
|
142
|
+
`TFHUB_CACHE_DIR`.
|
|
143
|
+
|
|
144
|
+
### Genome annotation
|
|
145
|
+
|
|
146
|
+
The dataloaders and `EnformerVeff` take the genome annotation as `genome_annotation`: the path to a GFF3 file, such
|
|
147
|
+
as a GENCODE annotation, or a polars or pandas DataFrame with pyranges-style columns, see
|
|
148
|
+
`abexp.enformer.utils.genome_annotation_to_polars`. kipoi-enformer 0.0.1 read a GTF file instead, and the parameter
|
|
149
|
+
was `gtf`.
|
|
150
|
+
|
|
151
|
+
### Tissue mapper
|
|
152
|
+
|
|
153
|
+
`EnformerTissueMapper` maps the Enformer CAGE tracks to an expression score per GTEx tissue, with one linear model per
|
|
154
|
+
tissue. `train` fits a scikit-learn pipeline of a `StandardScaler` and a linear model for each tissue. The model must
|
|
155
|
+
be linear, e.g. from `sklearn.linear_model`; other models raise a `TypeError`. `train` writes the parameters of the
|
|
156
|
+
pipelines to a parquet file with one row per tissue: `tissue`, the `mean` and `scale` of the `StandardScaler`, and
|
|
157
|
+
the `coef` and `intercept` of the linear model. The features are the tracks in the order of the tracks yaml file.
|
|
158
|
+
`predict` computes the scores from this file with numpy and gives the same scores as the pipelines with scikit-learn
|
|
159
|
+
1.5 to 1.7.
|
|
160
|
+
|
|
161
|
+
### Usage
|
|
162
|
+
|
|
163
|
+
The example reads the chr22 sequence and genome annotation in `example/` of the AbExp repository and the test
|
|
164
|
+
data of this package. Run it in the root of a checkout of AbExp, after you have fetched the test data, see
|
|
165
|
+
[Tests](#tests).
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from abexp.enformer.dataloader import RefTSSDataloader, VCFTSSDataloader
|
|
169
|
+
from abexp.enformer.enformer import Enformer, EnformerAggregator, EnformerTissueMapper, EnformerVeff
|
|
170
|
+
from pathlib import Path
|
|
171
|
+
from sklearn import linear_model
|
|
172
|
+
|
|
173
|
+
fasta_file = 'example/chr22_hg19.fa'
|
|
174
|
+
genome_annotation = 'example/chr22.gencode.v40lift37.annotation.gff3.gz'
|
|
175
|
+
data_dir = Path('packages/aberrant_expression/tests/enformer/data')
|
|
176
|
+
|
|
177
|
+
# define output dirs
|
|
178
|
+
output_dir = Path('output')
|
|
179
|
+
(output_dir / 'raw/ref.parquet/chrom=chr22').mkdir(exist_ok=True, parents=True)
|
|
180
|
+
(output_dir / 'raw/alt.parquet').mkdir(exist_ok=True, parents=True)
|
|
181
|
+
(output_dir / 'aggregated/ref.parquet/chrom=chr22').mkdir(exist_ok=True, parents=True)
|
|
182
|
+
(output_dir / 'aggregated/alt.parquet').mkdir(exist_ok=True, parents=True)
|
|
183
|
+
(output_dir / 'tissue/ref.parquet/chrom=chr22').mkdir(exist_ok=True, parents=True)
|
|
184
|
+
(output_dir / 'tissue/alt.parquet').mkdir(exist_ok=True, parents=True)
|
|
185
|
+
|
|
186
|
+
# define enformer objects
|
|
187
|
+
enformer = Enformer()
|
|
188
|
+
enformer_aggregator = EnformerAggregator()
|
|
189
|
+
enformer_tissue_mapper = EnformerTissueMapper(
|
|
190
|
+
tracks_path=data_dir / 'human_cage_nonuniversal_enformer_tracks.yaml')
|
|
191
|
+
enformer_veff = EnformerVeff(genome_annotation=genome_annotation)
|
|
192
|
+
|
|
193
|
+
# Reference sequences
|
|
194
|
+
# define reference dataloader
|
|
195
|
+
ref_dl = RefTSSDataloader(fasta_file=fasta_file, genome_annotation=genome_annotation, chromosome='chr22',
|
|
196
|
+
canonical_only=False, protein_coding_only=True)
|
|
197
|
+
# run enformer on reference genome
|
|
198
|
+
enformer.predict(ref_dl, batch_size=2, filepath=output_dir / 'raw/ref.parquet/chrom=chr22/data.parquet',
|
|
199
|
+
num_output_bins=11)
|
|
200
|
+
# aggregate reference enformer scores
|
|
201
|
+
enformer_aggregator.aggregate(output_dir / 'raw/ref.parquet/chrom=chr22/data.parquet',
|
|
202
|
+
output_dir / 'aggregated/ref.parquet/chrom=chr22/data.parquet')
|
|
203
|
+
# train tissue mapper using reference genome
|
|
204
|
+
enformer_tissue_mapper.train([output_dir / 'aggregated/ref.parquet/chrom=chr22/data.parquet'],
|
|
205
|
+
output_path=output_dir / 'tissue_mapper.parquet',
|
|
206
|
+
expression_path=data_dir / 'transcripts_tpms.zarr',
|
|
207
|
+
model=linear_model.ElasticNetCV(cv=2))
|
|
208
|
+
# map reference to tissues
|
|
209
|
+
enformer_tissue_mapper.predict(output_dir / 'aggregated/ref.parquet/chrom=chr22/data.parquet',
|
|
210
|
+
output_dir / 'tissue/ref.parquet/chrom=chr22/data.parquet')
|
|
211
|
+
|
|
212
|
+
# Alternative sequences
|
|
213
|
+
# define alternative dataloader
|
|
214
|
+
alt_dl = VCFTSSDataloader(fasta_file=fasta_file, genome_annotation=genome_annotation,
|
|
215
|
+
vcf_file=data_dir / 'chr22_var.vcf.gz', variant_upstream_tss=50,
|
|
216
|
+
variant_downstream_tss=200, canonical_only=False, protein_coding_only=True)
|
|
217
|
+
# run enformer on alternative genome
|
|
218
|
+
enformer.predict(alt_dl, batch_size=2, filepath=output_dir / 'raw/alt.parquet/chr22_var.vcf.gz.parquet',
|
|
219
|
+
num_output_bins=11)
|
|
220
|
+
# aggregate alternative enformer scores
|
|
221
|
+
enformer_aggregator.aggregate(output_dir / 'raw/alt.parquet/chr22_var.vcf.gz.parquet',
|
|
222
|
+
output_dir / 'aggregated/alt.parquet/chr22_var.vcf.gz.parquet')
|
|
223
|
+
# map alternative to tissues
|
|
224
|
+
enformer_tissue_mapper.predict(output_dir / 'aggregated/alt.parquet/chr22_var.vcf.gz.parquet',
|
|
225
|
+
output_dir / 'tissue/alt.parquet/chr22_var.vcf.gz.parquet')
|
|
226
|
+
|
|
227
|
+
# Variant effect prediction
|
|
228
|
+
enformer_veff.run(ref_paths=[output_dir / 'tissue/ref.parquet/chrom=chr22/data.parquet'],
|
|
229
|
+
alt_path=output_dir / 'tissue/alt.parquet/chr22_var.vcf.gz.parquet',
|
|
230
|
+
output_path=output_dir / 'veff.parquet', aggregation_mode='canonical')
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Known issues
|
|
234
|
+
|
|
235
|
+
`EnformerAggregator` averages the bins around the TSS bin of each shift. As the TSS, it takes the middle of the bins
|
|
236
|
+
that `Enformer.predict` saved. That is right for an even `num_output_bins`, such as all 896. With 21 output bins, the
|
|
237
|
+
workflow default, Enformer saves the bins 438 to 458. Their middle lies 64 bp downstream of the TSS. So shift +43
|
|
238
|
+
averages the bins 447 to 449, although the TSS lies in bin 447. With 896 output bins, it averages 446 to 448. Shifts
|
|
239
|
+
0 and -43 average 447 to 449 in both cases.
|
|
240
|
+
|
|
241
|
+
The training pipeline [gtsitsiridis/kipoi_veff_analysis](https://github.com/gtsitsiridis/kipoi_veff_analysis)
|
|
242
|
+
trained the published tissue mapper (`elasticnet_cage_gtexv8`) on 21 output bins, so the tissue mapper learned this
|
|
243
|
+
behavior. The reference scores that the workflow downloads come from the same pipeline. So the code keeps the
|
|
244
|
+
behavior. A fix would replace `pred_seq_length // 2` with `pred.shape[2] // 2 * bin_size` in
|
|
245
|
+
`EnformerAggregator._aggregate_batch`. It needs a retrained tissue mapper and recomputed reference scores. The offset
|
|
246
|
+
came in with the crop to 21 output bins, in commit e2bbf5ec (2024-05-16) of the training pipeline.
|
|
247
|
+
|
|
248
|
+
## abexp.mmsplice, abexp.absplice and abexp.spliceai_rocksdb
|
|
249
|
+
|
|
250
|
+
The parts of MMSplice, AbSplice and SpliceAI-RocksDB that the AbExp pipeline runs, on kipoiseq2. kipoi, kipoiseq 0.7,
|
|
251
|
+
cyvcf2 and pyranges are no longer needed. The outputs match the upstream packages, except for the row order,
|
|
252
|
+
rounding in the last digits and the choice among tied junctions, see
|
|
253
|
+
[Differences](#differences-from-the-upstream-packages).
|
|
254
|
+
|
|
255
|
+
| import | ported from | what AbExp uses |
|
|
256
|
+
| ------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
257
|
+
| `abexp.mmsplice` | [mmsplice](https://github.com/gagneurlab/MMSplice_MTSplice) 2.4.0 (31513da) | `MMSplice` and the junction VCF dataloaders |
|
|
258
|
+
| `abexp.absplice` | [absplice](https://github.com/gagneurlab/absplice) daad7b6, [splicemap](https://github.com/gagneurlab/splicemap) cf922eb | `SpliceOutlierDataloader`, `SpliceOutlier`, `SplicingOutlierResult`, `read_spliceai_vcf` |
|
|
259
|
+
| `abexp.spliceai_rocksdb` | [spliceai_rocksdb](https://github.com/gagneurlab/spliceai_rocksdb) 3c40d6e | `SpliceAI` |
|
|
260
|
+
|
|
261
|
+
### Usage
|
|
262
|
+
|
|
263
|
+
The example runs AbSplice-DNA on the test data of this package. Run it in the root of a checkout of AbExp.
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
import polars as pl
|
|
267
|
+
from abexp.absplice import SpliceOutlier, SpliceOutlierDataloader, SplicingOutlierResult
|
|
268
|
+
|
|
269
|
+
data_dir = 'packages/aberrant_expression/tests/splicing/data'
|
|
270
|
+
|
|
271
|
+
# MMSplice with SpliceMaps: delta PSI per variant, junction and tissue
|
|
272
|
+
dl = SpliceOutlierDataloader(
|
|
273
|
+
'example/chr22_hg38.fa', f'{data_dir}/clinvar_chr22.vcf',
|
|
274
|
+
splicemap5=[f'{data_dir}/Whole_Blood_splicemap_psi5.csv.gz'],
|
|
275
|
+
splicemap3=[f'{data_dir}/Whole_Blood_splicemap_psi3.csv.gz'],
|
|
276
|
+
)
|
|
277
|
+
SpliceOutlier().predict_save(dl, 'mmsplice_splicemap.csv')
|
|
278
|
+
|
|
279
|
+
# AbSplice-DNA per variant, gene and tissue, from MMSplice and SpliceAI
|
|
280
|
+
result = SplicingOutlierResult(
|
|
281
|
+
df_mmsplice=pl.read_csv('mmsplice_splicemap.csv'),
|
|
282
|
+
df_spliceai=pl.read_csv(f'{data_dir}/expected/spliceai_vcf.csv'),
|
|
283
|
+
)
|
|
284
|
+
df = result.predict_absplice_dna()
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
`abexp.spliceai_rocksdb.SpliceAI(fasta, annotation='grch38', db_path={'22': <path>}).predict_save(vcf, csv)`
|
|
288
|
+
looks up the SpliceAI scores in SpliceAI-RocksDB and runs SpliceAI for the variants that are not in it.
|
|
289
|
+
`abexp.absplice.read_spliceai_vcf` reads a VCF file that the SpliceAI command line tool annotated.
|
|
290
|
+
|
|
291
|
+
### Differences from the upstream packages
|
|
292
|
+
|
|
293
|
+
- kipoiseq2 yields the variant-junction pairs in the order of the VCF file, and kipoiseq 0.7 in the order of
|
|
294
|
+
pyranges. So the rows of the MMSplice table come in another order.
|
|
295
|
+
- MMSplice therefore predicts batches with other samples. TensorFlow rounds them differently, so `delta_logit_psi`
|
|
296
|
+
can differ in the last digits.
|
|
297
|
+
- A variant can have the same delta PSI at several junctions of a gene. absplice daad7b6 picked any one of them,
|
|
298
|
+
and the row order and the numpy version decided which one. abexp.absplice picks the first in the order of
|
|
299
|
+
junction, event_type, splice_site and the other columns. So the reported junction can differ from absplice, and
|
|
300
|
+
with its `median_n` also `splice_site_is_expressed` and `AbSplice_DNA`.
|
|
301
|
+
- `read_spliceai_vcf` names the column `acceptor_loss_position`, not `acceptor_loss_positiin`.
|
|
302
|
+
- `read_spliceai_vcf` gives each ALT allele only the SpliceAI entries of that allele. absplice gave it the entries
|
|
303
|
+
of all ALT alleles of its record. The workflow splits multi-allelic records before SpliceAI, so its tables do
|
|
304
|
+
not change.
|
|
305
|
+
- abexp.mmsplice, abexp.absplice and abexp.spliceai_rocksdb use polars and numpy instead of pandas. The tables in
|
|
306
|
+
and out are polars DataFrames. `predict_absplice_dna` returns variant, gene_id and tissue as columns, sorted by
|
|
307
|
+
them, and not as an index.
|
|
308
|
+
- The CSV files of `predict_save` format floats as polars does, e.g. `6.4e-6` instead of `6.4e-06`. The values do
|
|
309
|
+
not change.
|
|
310
|
+
- A VCF file without variants yields no samples. mmsplice compared the contigs of the VCF header with the FASTA
|
|
311
|
+
file, and abexp.mmsplice compares the chromosomes of the variants.
|
|
312
|
+
- If no variant lies on a chromosome of the junctions, e.g. in a VCF file with only chrM variants, abexp.mmsplice
|
|
313
|
+
logs a warning and yields no samples. mmsplice raised a ValueError if no contig of the VCF header had junctions.
|
|
314
|
+
- Only the parts that AbExp uses are kept. Not included: MTSplice, the VEP plugin, the dataloaders of GTF exons
|
|
315
|
+
and exon tables, the VCF writers, the variant filters of absplice, AbSplice-RNA, the CADD-Splice and
|
|
316
|
+
sample-based features, and the SpliceMap count tables. `predict_absplice_dna` reads only ONNX models.
|
|
317
|
+
|
|
318
|
+
## abexp.pangolin
|
|
319
|
+
|
|
320
|
+
Pangolin's splice scores of variants (Zeng and Li, Genome Biology 2022, [Pangolin](https://github.com/tkzeng/Pangolin)),
|
|
321
|
+
on kipoiseq2 and PyTorch. Per variant and gene, it gives the largest gain and loss of splice site usage within
|
|
322
|
+
`distance` bases, like `pangolin -d 50 -m True`. The network and the data path are our own code; only the weights
|
|
323
|
+
come from Pangolin. The network uses unpadded convolutions, which give the same outputs with about a third less
|
|
324
|
+
computation, and it scores ref and alt sequences of equal length in batches.
|
|
325
|
+
|
|
326
|
+
The weights are not part of this package. They are GPL-3, as the Pangolin repository. `download_models` downloads
|
|
327
|
+
the 12 files of `abexp.pangolin.MODEL_FILES` (35 MB) from `pangolin/models` of the Pangolin repository at the
|
|
328
|
+
pinned commit `PANGOLIN_COMMIT` (5cf94b8), and checks their SHA-256 sums. It keeps the files that exist with the right
|
|
329
|
+
sum. `download_model(file, models_dir)` does the same for one file. `PangolinModels.from_dir` checks the SHA-256
|
|
330
|
+
sums too, and stops with a ValueError on files of another commit.
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
from abexp.pangolin import Pangolin, PangolinModels, download_models, read_gff3_genes
|
|
334
|
+
|
|
335
|
+
download_models('pangolin_models')
|
|
336
|
+
genes = read_gff3_genes('gencode.v42.annotation.gff3.gz', transcript_tags=['Ensembl_canonical'])
|
|
337
|
+
pangolin = Pangolin('genome.fa', genes, PangolinModels.from_dir('pangolin_models'), distance=50, mask=True)
|
|
338
|
+
pangolin.predict_df('variants.vcf').write_parquet('pangolin.parquet')
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Differences from upstream Pangolin
|
|
342
|
+
|
|
343
|
+
The scores match Pangolin (fork neverov-am/Pangolin 232cba0) up to the last float32 digits, except here:
|
|
344
|
+
|
|
345
|
+
- Every ALT allele of a record is scored. Pangolin scores only the first one.
|
|
346
|
+
- A gene counts if the ref allele overlaps it. Pangolin misses a gene that starts at the variant position, and a gene
|
|
347
|
+
that a deletion reaches only after its first base.
|
|
348
|
+
- Beyond the chromosome ends, the sequence is N. Pangolin skips variants within 5050 bases of the chromosome start,
|
|
349
|
+
and stops with an error for most variants within 5050 bases of its end.
|
|
350
|
+
- The ref check ignores the case of the FASTA file, and the sequence is upper case. Pangolin skips a variant whose
|
|
351
|
+
FASTA ref is in lower case.
|
|
352
|
+
- Variants with letters other than A, C, G, T and N in ref or alt are skipped. Pangolin stops with an error on them.
|
|
353
|
+
kipoiseq2 drops ALT alleles with N; Pangolin scores them with N as 0.
|
|
354
|
+
- The output is a polars DataFrame with unrounded float32 scores, not a VCF file with scores rounded to 2 decimals.
|
|
355
|
+
- The genes and splice sites come from a GENCODE GFF3 file, not from a gffutils database. An exon belongs to the
|
|
356
|
+
gene with its `gene_id` on its chromosome.
|
|
357
|
+
- With `mask`, each gene is masked on its own, as in the fork. tkzeng/Pangolin 5cf94b8 masks the loss and gain
|
|
358
|
+
arrays of a strand in place. So there, each gene starts from the arrays that the genes before it on the same
|
|
359
|
+
strand have masked (`pangolin/pangolin.py`, lines 133 to 153). The fork copies the arrays for each gene (lines 144
|
|
360
|
+
and 145 of 232cba0).
|
|
361
|
+
|
|
362
|
+
## abexp.absplice2
|
|
363
|
+
|
|
364
|
+
AbSplice2-DNA per variant, gene and GTEx tissue, from Pangolin, MMSplice with SpliceMaps, and the SpliceMaps. The
|
|
365
|
+
code is our own, in polars, for the steps of the [AbSplice2](https://github.com/gagneurlab/absplice2) example
|
|
366
|
+
workflow after MMSplice and Pangolin, at commit a30120f. `absplice2_dna` matches Pangolin's gain and loss sites
|
|
367
|
+
with the SpliceMap sites within 2 bp, joins them with MMSplice, scores each row with the model, and keeps the row
|
|
368
|
+
with the largest score per variant, gene and tissue.
|
|
369
|
+
|
|
370
|
+
The AbSplice2 model is not part of this package. It is an ExplainableBoostingClassifier of interpret 0.2.7, which
|
|
371
|
+
the caller loads and passes as a function:
|
|
372
|
+
|
|
373
|
+
```python
|
|
374
|
+
import pickle
|
|
375
|
+
|
|
376
|
+
import polars as pl
|
|
377
|
+
from abexp.absplice2 import absplice2_dna, read_mmsplice_splicemap
|
|
378
|
+
|
|
379
|
+
with open('AbSplice_2_DNA.pkl', 'rb') as fd:
|
|
380
|
+
model = pickle.load(fd)
|
|
381
|
+
df = absplice2_dna(
|
|
382
|
+
pangolin=pl.read_parquet('pangolin.parquet'), # the output of abexp.pangolin
|
|
383
|
+
splicemap5=['Whole_Blood_splicemap_psi5.csv.gz'],
|
|
384
|
+
splicemap3=['Whole_Blood_splicemap_psi3.csv.gz'],
|
|
385
|
+
mmsplice_splicemap=read_mmsplice_splicemap('mmsplice_splicemap.csv'),
|
|
386
|
+
predict=lambda features: model.predict_proba(features.to_pandas())[:, 1],
|
|
387
|
+
)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
The output matches the AbSplice2 scripts, except here:
|
|
391
|
+
|
|
392
|
+
- The variant is split into `chrom`, `start` (0-based), `end`, `ref` and `alt`, and `gene_id` is named `gene`.
|
|
393
|
+
- Pangolin's scores are rounded to 2 decimals in float64, Pangolin rounds them in float32. The two differ by 0.01
|
|
394
|
+
only for scores within float32 precision of a rounding boundary.
|
|
395
|
+
- Of the rows with the same largest score, AbSplice2 keeps any one. `absplice2_dna` keeps the first in the order
|
|
396
|
+
of the output columns, so its MMSplice columns can differ from AbSplice2.
|
|
397
|
+
|
|
398
|
+
## Tests
|
|
399
|
+
|
|
400
|
+
The tests are in one directory per area, and each area needs the extras of its subpackages:
|
|
401
|
+
|
|
402
|
+
| directory | extras | reads |
|
|
403
|
+
| ---------------- | ----------------- | --------------------------------------------------------------------------------------- |
|
|
404
|
+
| `tests/utils` | `polars`, `spark`, `gff3` | nothing; the Spark tests need a Java runtime |
|
|
405
|
+
| `tests/enformer` | `enformer` | the files in `tests/enformer/data/` and the hg19 chr22 sequence `example/chr22_hg19.fa` |
|
|
406
|
+
| `tests/splicing` | `splicing` | the files in `tests/splicing/data/` and the hg38 chr22 sequence `example/chr22_hg38.fa` |
|
|
407
|
+
| `tests/pangolin` | `pangolin` | the files in `tests/pangolin/data/` and the published weights of Pangolin (35 MB) |
|
|
408
|
+
| `tests/absplice2` | `absplice2` | nothing |
|
|
409
|
+
|
|
410
|
+
The example sequences are in the AbExp repository, outside of the package. Pytest skips a test if one of its files
|
|
411
|
+
is missing, e.g. in an sdist.
|
|
412
|
+
|
|
413
|
+
git-lfs stores the files in `tests/enformer/data/`. `.lfsconfig` excludes them from the default fetch, so that pip
|
|
414
|
+
installs from a git URL do not download them. With git-lfs installed, fetch them in a checkout of AbExp and run the
|
|
415
|
+
tests:
|
|
416
|
+
|
|
417
|
+
```bash
|
|
418
|
+
git lfs pull --include="packages/aberrant_expression/tests/enformer/data/**" --exclude=""
|
|
419
|
+
cd packages/aberrant_expression
|
|
420
|
+
pytest tests/utils
|
|
421
|
+
pytest tests/enformer
|
|
422
|
+
pytest tests/splicing
|
|
423
|
+
pytest tests/pangolin
|
|
424
|
+
pytest tests/absplice2
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
The tests run across all cores by default, through pytest-xdist. Pass `-n0` to run them in one process, which a
|
|
428
|
+
debugger needs and which restores per-test output order. The tests of one xdist group run on one worker, one after
|
|
429
|
+
the other: the Spark tests, and the tests that run Enformer, which share their outputs. With `-n0`, the enformer
|
|
430
|
+
tests need about 3 GB of memory.
|
|
431
|
+
|
|
432
|
+
The pangolin tests run small networks with fixed random weights on a synthetic genome, and the published weights of
|
|
433
|
+
Pangolin on an excerpt of GRCh38 chr22 in `tests/pangolin/data/`. They download the published weights once into the
|
|
434
|
+
pytest cache, or into the folder in `ABEXP_PANGOLIN_MODELS_DIR` if set. Without network access, the download fails,
|
|
435
|
+
and so do the tests with the published weights. Their expected rows come from upstream Pangolin, see
|
|
436
|
+
`tests/pangolin/make_expected.py` and `tests/pangolin/make_expected_published.py`.
|
|
437
|
+
|
|
438
|
+
The absplice2 tests run `absplice2_dna` with a stand-in for the AbSplice2 model on the made-up inputs of
|
|
439
|
+
`tests/absplice2/constellations.py`, one constellation per test. Their expected rows come from the AbSplice2 scripts
|
|
440
|
+
with the same stand-in, see `tests/absplice2/make_expected.py`.
|
|
441
|
+
|
|
442
|
+
The expected outputs in `tests/splicing/data/expected/` come from the upstream packages, see
|
|
443
|
+
`tests/splicing/make_expected.py`. The SpliceAI-RocksDB tests also need the extra `rocksdb` and the hg38 chr22
|
|
444
|
+
database (2.6 GB). Set `ABEXP_SPLICEAI_ROCKSDB_HG38_CHR22` to the path of `spliceAI_hg38_chr22.db`, otherwise pytest
|
|
445
|
+
skips them. The test of the SpliceAI predictions also needs SpliceAI.
|
|
446
|
+
|
|
447
|
+
## License
|
|
448
|
+
|
|
449
|
+
The code is under the MIT license, see [LICENSE](LICENSE). It lists the copyright notices of the upstream
|
|
450
|
+
projects of `abexp.mmsplice`, `abexp.absplice` and `abexp.spliceai_rocksdb`. `abexp.pangolin` loads the weights of Pangolin, which are
|
|
451
|
+
GPL-3 and not part of the package, see [abexp.pangolin](#abexppangolin).
|