dna-parser 0.3.0__tar.gz → 0.4.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.
- {dna_parser-0.3.0 → dna_parser-0.4.0}/Cargo.lock +2 -2
- {dna_parser-0.3.0 → dna_parser-0.4.0}/Cargo.toml +1 -1
- {dna_parser-0.3.0 → dna_parser-0.4.0}/PKG-INFO +5 -4
- {dna_parser-0.3.0 → dna_parser-0.4.0}/docs/documentation.md +18 -3
- {dna_parser-0.3.0 → dna_parser-0.4.0}/pyproject.toml +2 -2
- {dna_parser-0.3.0 → dna_parser-0.4.0}/python/dna_parser/call_functions.py +12 -8
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/lib.rs +0 -5
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/zcurve.rs +101 -101
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_fasta.py +6 -6
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_zcurve.py +32 -1
- dna_parser-0.3.0/src/fasta_files.rs +0 -126
- {dna_parser-0.3.0 → dna_parser-0.4.0}/.github/workflows/CI.yml +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/.github/workflows/release.yml +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/.gitignore +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/LICENSE +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/README.md +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/docs/about.md +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/docs/index.md +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/docs/license.md +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/mkdocs.yml +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/python/dna_parser/__init__.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/python/dna_parser/tfidf_class.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/atomic_number.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/chaos_game.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/cross.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/dna_walk.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/eiip.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/fickett.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/kmers.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/onehot.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/random_sequence.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/real.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/tfidf.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/src/utils/mod.rs +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/seq_test.fasta +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_atomic.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_chaos.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_cross.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_dna_walk.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_eiip.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_fickett.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_onehot.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_real.py +0 -0
- {dna_parser-0.3.0 → dna_parser-0.4.0}/tests/test_tfidf.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This file is automatically @generated by Cargo.
|
|
2
2
|
# It is not intended for manual editing.
|
|
3
|
-
version =
|
|
3
|
+
version = 4
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "ahash"
|
|
@@ -54,7 +54,7 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|
|
54
54
|
|
|
55
55
|
[[package]]
|
|
56
56
|
name = "dna_parser"
|
|
57
|
-
version = "0.
|
|
57
|
+
version = "0.4.0"
|
|
58
58
|
dependencies = [
|
|
59
59
|
"ahash",
|
|
60
60
|
"indexmap",
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dna_parser
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
7
|
-
Requires-Dist: numpy
|
|
8
|
-
Requires-Dist: scipy
|
|
9
|
-
Requires-Dist: scikit-learn
|
|
7
|
+
Requires-Dist: numpy>=1.16.0
|
|
8
|
+
Requires-Dist: scipy>=1.3.0
|
|
9
|
+
Requires-Dist: scikit-learn>=1.5.0
|
|
10
|
+
Requires-Dist: needletail>=0.7.0
|
|
10
11
|
Requires-Dist: pytest ; extra == 'dev'
|
|
11
12
|
Requires-Dist: mkdocs ; extra == 'dev'
|
|
12
13
|
Provides-Extra: dev
|
|
@@ -486,7 +486,7 @@ print(encodings2)
|
|
|
486
486
|
|
|
487
487
|
|
|
488
488
|
```python
|
|
489
|
-
dna_parser.zcurve_encoding(sequences, pad_type= "after", pad_length= -2, n_jobs= 1)
|
|
489
|
+
dna_parser.zcurve_encoding(sequences, pad_type= "after", pad_length= -2, window= 1, n_jobs= 1)
|
|
490
490
|
```
|
|
491
491
|
|
|
492
492
|
#### Function Arguments
|
|
@@ -494,11 +494,12 @@ dna_parser.zcurve_encoding(sequences, pad_type= "after", pad_length= -2, n_jobs=
|
|
|
494
494
|
* **sequences** (list of str): list of genomic sequences.
|
|
495
495
|
* **pad_type** (str): pad (or trim) "before" or "after" the sequences.
|
|
496
496
|
* **pad_length** (int): -2 to pad according to the longest sequence, -1 to trim to the shortest sequence, any positive number for a fixed length.
|
|
497
|
+
* **window** (int): non-overlapping window size to consider along the sequence for the encoding.
|
|
497
498
|
* **n_jobs** (int): number of threads used to encode the sequences in parallel. 0 to use all CPUs available.
|
|
498
499
|
|
|
499
500
|
#### Output
|
|
500
501
|
|
|
501
|
-
**Numpy array with shape (number of sequences, length of sequences, 3).** <br /> The sequences are encoded within a cube. At each
|
|
502
|
+
**Numpy array with shape (number of sequences, (length of sequences/window), 3).** <br /> The sequences are encoded within a cube. At each window position the Z-curve encoding gives the disparity between purines (r) and pyrimidines (y), the disparity between nucleotides with an amino (m) and a keto (k) group, and the disparity between nucleotide with weak (w) and strong (s) bonds.
|
|
502
503
|
|
|
503
504
|
|
|
504
505
|
```python
|
|
@@ -521,7 +522,21 @@ print(encoding.shape)
|
|
|
521
522
|
# [-1 3 -1]
|
|
522
523
|
# [-1 3 -1]]]
|
|
523
524
|
#
|
|
524
|
-
#(2,
|
|
525
|
+
#(2, 4, 3)
|
|
526
|
+
|
|
527
|
+
sequences= ["agtc","acc"]
|
|
528
|
+
encoding= dps.zcurve_encoding(sequences, window=2)
|
|
529
|
+
print(encoding)
|
|
530
|
+
print(encoding.shape)
|
|
531
|
+
|
|
532
|
+
#Output:
|
|
533
|
+
#[[[ 2 0 0]
|
|
534
|
+
# [ 0 0 0]]
|
|
535
|
+
#
|
|
536
|
+
# [[ 0 2 0]
|
|
537
|
+
# [-1 3 -1]]]
|
|
538
|
+
#(2, 2, 3)
|
|
539
|
+
|
|
525
540
|
```
|
|
526
541
|
<br/>
|
|
527
542
|
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dna_parser"
|
|
7
|
-
project.version = "0.
|
|
7
|
+
project.version = "0.4.0"
|
|
8
8
|
requires-python = ">=3.9"
|
|
9
9
|
classifiers = [
|
|
10
10
|
"Programming Language :: Rust",
|
|
@@ -12,7 +12,7 @@ classifiers = [
|
|
|
12
12
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
13
13
|
]
|
|
14
14
|
|
|
15
|
-
dependencies = ['numpy >= 1.16.0', 'scipy >= 1.3.0', "scikit-learn >= 1.5.0",]
|
|
15
|
+
dependencies = ['numpy >= 1.16.0', 'scipy >= 1.3.0', "scikit-learn >= 1.5.0", 'needletail >= 0.7.0' ]
|
|
16
16
|
|
|
17
17
|
[project.optional-dependencies]
|
|
18
18
|
dev = ["pytest","mkdocs"]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .dna_parser import *
|
|
2
|
+
from needletail import parse_fastx_file
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
def onehot_encoding(sequences, pad_type= "after", pad_length= -2, n_jobs= 1):
|
|
@@ -17,9 +18,9 @@ def random_seq(length, nb_of_seq, seq_type= "dna", n_jobs= 1):
|
|
|
17
18
|
|
|
18
19
|
return random_seq_rust(length, nb_of_seq, seq_type, n_jobs)
|
|
19
20
|
|
|
20
|
-
def zcurve_encoding(sequences, pad_type= "after", pad_length= -2, n_jobs= 1):
|
|
21
|
+
def zcurve_encoding(sequences, pad_type= "after", pad_length= -2, window=1, n_jobs= 1):
|
|
21
22
|
|
|
22
|
-
return zcurve_encoding_rust(sequences, pad_type, pad_length, n_jobs)
|
|
23
|
+
return zcurve_encoding_rust(sequences, pad_type, pad_length, window, n_jobs)
|
|
23
24
|
|
|
24
25
|
def chaos_encoding(sequences, pad_type= "after", pad_length= -2, n_jobs= 1):
|
|
25
26
|
|
|
@@ -44,30 +45,33 @@ def atomic_encoding(sequences, pad_type= "after", pad_length= -2, n_jobs= 1):
|
|
|
44
45
|
def load_fasta(path):
|
|
45
46
|
|
|
46
47
|
if type(path) is str:
|
|
47
|
-
return
|
|
48
|
+
return [(seq.id, seq.seq) for seq in parse_fastx_file(path)]
|
|
48
49
|
|
|
49
50
|
elif type(path) is list:
|
|
50
51
|
|
|
51
|
-
sequences= [ seq for
|
|
52
|
+
sequences= [ (seq.id, seq.seq) for file in path for seq in parse_fastx_file(file) ]
|
|
52
53
|
return sequences
|
|
54
|
+
|
|
53
55
|
|
|
54
56
|
def load_metadata(path):
|
|
55
57
|
|
|
58
|
+
|
|
56
59
|
if type(path) is str:
|
|
57
|
-
return
|
|
60
|
+
return [seq.id for seq in parse_fastx_file(path)]
|
|
58
61
|
|
|
59
62
|
elif type(path) is list:
|
|
60
63
|
|
|
61
|
-
sequences= [ seq for
|
|
64
|
+
sequences= [ seq.id for file in path for seq in parse_fastx_file(file)]
|
|
62
65
|
return sequences
|
|
66
|
+
|
|
63
67
|
|
|
64
68
|
|
|
65
69
|
def load_sequences(path):
|
|
66
70
|
|
|
67
71
|
if type(path) is str:
|
|
68
|
-
return
|
|
72
|
+
return [seq.seq for seq in parse_fastx_file(path)]
|
|
69
73
|
|
|
70
74
|
elif type(path) is list:
|
|
71
75
|
|
|
72
|
-
sequences= [ seq for
|
|
76
|
+
sequences= [ seq.seq for file in path for seq in parse_fastx_file(file)]
|
|
73
77
|
return sequences
|
|
@@ -4,7 +4,6 @@ pub mod kmers;
|
|
|
4
4
|
pub mod random_sequence;
|
|
5
5
|
pub mod tfidf;
|
|
6
6
|
pub mod real;
|
|
7
|
-
pub mod fasta_files;
|
|
8
7
|
pub mod utils;
|
|
9
8
|
pub mod cross;
|
|
10
9
|
pub mod zcurve;
|
|
@@ -27,7 +26,6 @@ use kmers::*;
|
|
|
27
26
|
use random_sequence::*;
|
|
28
27
|
use tfidf::*;
|
|
29
28
|
use real::*;
|
|
30
|
-
use fasta_files::*;
|
|
31
29
|
use cross::*;
|
|
32
30
|
use zcurve::*;
|
|
33
31
|
use chaos_game::*;
|
|
@@ -47,9 +45,6 @@ fn dna_parser(_py: Python<'_>, m: &Bound<PyModule>)-> PyResult<()> {
|
|
|
47
45
|
m.add_function(wrap_pyfunction!(make_kmers,m)?)?;
|
|
48
46
|
m.add_function(wrap_pyfunction!(random_seq_rust,m)?)?;
|
|
49
47
|
m.add_function(wrap_pyfunction!(real_encoding_rust,m)?)?;
|
|
50
|
-
m.add_function(wrap_pyfunction!(load_fasta_rust,m)?)?;
|
|
51
|
-
m.add_function(wrap_pyfunction!(seq_from_fasta_rust,m)?)?;
|
|
52
|
-
m.add_function(wrap_pyfunction!(metadata_from_fasta_rust,m)?)?;
|
|
53
48
|
m.add_function(wrap_pyfunction!(cross_encoding_rust,m)?)?;
|
|
54
49
|
m.add_function(wrap_pyfunction!(zcurve_encoding_rust,m)?)?;
|
|
55
50
|
m.add_function(wrap_pyfunction!(chaos_encoding_rust,m)?)?;
|
|
@@ -11,7 +11,7 @@ use std::thread;
|
|
|
11
11
|
use crate::utils;
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
fn zcurve_after(sequence: &str, mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[usize; 2]
|
|
14
|
+
fn zcurve_after(sequence: &str, mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[usize; 2]>>, window: usize) {
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
let mut r= 0;
|
|
@@ -20,71 +20,70 @@ fn zcurve_after(sequence: &str, mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[us
|
|
|
20
20
|
let mut k= 0;
|
|
21
21
|
let mut w= 0;
|
|
22
22
|
let mut s= 0;
|
|
23
|
-
|
|
24
23
|
|
|
25
|
-
for item in array.axis_iter_mut(Axis(0)).zip_longest(sequence.chars()) {
|
|
24
|
+
for item in array.axis_iter_mut(Axis(0)).zip_longest(sequence.chars().chunks(window).into_iter()) {
|
|
26
25
|
|
|
27
|
-
let nucleotide: char;
|
|
28
26
|
let mut col: ArrayBase<ViewRepr<&mut i64>, Dim<[usize; 1]>>;
|
|
29
27
|
|
|
30
|
-
if item.
|
|
31
|
-
let (option_col,char) = item.left_and_right();
|
|
32
|
-
col= option_col.unwrap();
|
|
33
|
-
nucleotide= char.unwrap().to_ascii_lowercase();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
else if !item.is_left() {
|
|
28
|
+
if item.is_left() {
|
|
37
29
|
break
|
|
38
30
|
}
|
|
39
31
|
|
|
40
|
-
else {
|
|
32
|
+
else if item.is_right() {
|
|
41
33
|
col= item.left().unwrap();
|
|
42
|
-
nucleotide= ' ';
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if nucleotide == 'a' || nucleotide == 'g' {
|
|
46
|
-
r += 1;
|
|
47
34
|
col[0]= r-y;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
else if nucleotide == 'c' || nucleotide == 't' || nucleotide == 'u'{
|
|
51
|
-
y += 1;
|
|
52
|
-
col[0]= r-y;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
else {
|
|
56
|
-
col[0]= r-y;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if nucleotide == 'a' || nucleotide == 'c' {
|
|
60
|
-
m += 1;
|
|
61
35
|
col[1]= m-k;
|
|
62
|
-
|
|
36
|
+
col[2]= w-s;
|
|
63
37
|
}
|
|
64
38
|
|
|
65
|
-
else
|
|
66
|
-
|
|
67
|
-
col
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
col[1]= m-k;
|
|
72
|
-
}
|
|
39
|
+
else {
|
|
40
|
+
let (option_col,nt_chunk) = item.left_and_right();
|
|
41
|
+
col= option_col.unwrap();
|
|
42
|
+
|
|
43
|
+
for mut nucleotide in nt_chunk.unwrap() {
|
|
44
|
+
nucleotide= nucleotide.to_ascii_lowercase();
|
|
73
45
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
46
|
+
if nucleotide == 'a' || nucleotide == 'g' {
|
|
47
|
+
r += 1;
|
|
48
|
+
col[0]= r-y;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
else if nucleotide == 'c' || nucleotide == 't' || nucleotide == 'u'{
|
|
52
|
+
y += 1;
|
|
53
|
+
col[0]= r-y;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if nucleotide == 'a' || nucleotide == 'c' {
|
|
57
|
+
m += 1;
|
|
58
|
+
col[1]= m-k;
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
else if nucleotide == 't' || nucleotide == 'u'|| nucleotide == 'g' {
|
|
63
|
+
k += 1;
|
|
64
|
+
col[1]= m-k;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if nucleotide == 'a' || nucleotide == 't' || nucleotide == 'u' {
|
|
68
|
+
w += 1;
|
|
69
|
+
col[2]= w-s
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
else if nucleotide == 'g' || nucleotide == 'c' {
|
|
73
|
+
s += 1;
|
|
74
|
+
col[2]= w-s
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
col[0]= r-y;
|
|
79
|
+
col[1]= m-k;
|
|
80
|
+
col[2]= w-s;
|
|
81
|
+
|
|
82
|
+
}
|
|
77
83
|
}
|
|
78
84
|
|
|
79
|
-
else if nucleotide == 'g' || nucleotide == 'c' {
|
|
80
|
-
s += 1;
|
|
81
|
-
col[2]= w-s
|
|
82
|
-
|
|
83
|
-
}
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
col[2]= w-s
|
|
87
|
-
}
|
|
86
|
+
|
|
88
87
|
|
|
89
88
|
|
|
90
89
|
}
|
|
@@ -93,7 +92,7 @@ fn zcurve_after(sequence: &str, mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[us
|
|
|
93
92
|
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
fn zcurve_before(sequence: &str, mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[usize; 2]
|
|
95
|
+
fn zcurve_before(sequence: &str, mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[usize; 2]>>, window: usize) {
|
|
97
96
|
|
|
98
97
|
|
|
99
98
|
let mut r= 0;
|
|
@@ -107,61 +106,61 @@ fn zcurve_before(sequence: &str, mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[u
|
|
|
107
106
|
let array_rev = array.axis_iter_mut(Axis(0)).rev();
|
|
108
107
|
let sequence_rev: Vec<char>= sequence.chars().rev().collect();
|
|
109
108
|
|
|
110
|
-
let zip_tup= array_rev.zip(sequence_rev).rev();
|
|
111
|
-
|
|
112
|
-
for (mut col, charac) in zip_tup {
|
|
113
|
-
|
|
114
|
-
let nucleotide= charac.to_ascii_lowercase();
|
|
115
|
-
|
|
116
|
-
if nucleotide == 'a' || nucleotide == 'g' {
|
|
117
|
-
r += 1;
|
|
118
|
-
col[0]= r-y;
|
|
119
|
-
}
|
|
109
|
+
let zip_tup= array_rev.zip(sequence_rev.chunks(window)).rev();
|
|
120
110
|
|
|
121
|
-
|
|
122
|
-
y += 1;
|
|
123
|
-
col[0]= r-y;
|
|
124
|
-
}
|
|
111
|
+
for (mut col, nt_chunk) in zip_tup {
|
|
125
112
|
|
|
126
|
-
|
|
127
|
-
col[0]= r-y;
|
|
128
|
-
}
|
|
113
|
+
for nt in nt_chunk {
|
|
129
114
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
115
|
+
let nucleotide= nt.to_ascii_lowercase();
|
|
116
|
+
|
|
117
|
+
if nucleotide == 'a' || nucleotide == 'g' {
|
|
118
|
+
r += 1;
|
|
119
|
+
col[0]= r-y;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
else if nucleotide == 'c' || nucleotide == 't' || nucleotide == 'u'{
|
|
123
|
+
y += 1;
|
|
124
|
+
col[0]= r-y;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
else {
|
|
128
|
+
col[0]= r-y;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if nucleotide == 'a' || nucleotide == 'c' {
|
|
132
|
+
m += 1;
|
|
133
|
+
col[1]= m-k;
|
|
134
|
+
|
|
135
|
+
}
|
|
135
136
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
else if nucleotide == 't' || nucleotide == 'u'|| nucleotide == 'g' {
|
|
138
|
+
k += 1;
|
|
139
|
+
col[1]= m-k;
|
|
140
|
+
}
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
else {
|
|
143
|
+
col[1]= m-k;
|
|
144
|
+
}
|
|
144
145
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
if nucleotide == 'a' || nucleotide == 't' || nucleotide == 'u' {
|
|
147
|
+
w += 1;
|
|
148
|
+
col[2]= w-s
|
|
149
|
+
}
|
|
149
150
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
else if nucleotide == 'g' || nucleotide == 'c' {
|
|
152
|
+
s += 1;
|
|
153
|
+
col[2]= w-s
|
|
153
154
|
|
|
154
|
-
|
|
155
|
+
}
|
|
155
156
|
|
|
156
|
-
|
|
157
|
-
|
|
157
|
+
else {
|
|
158
|
+
col[2]= w-s
|
|
159
|
+
}
|
|
158
160
|
}
|
|
159
161
|
|
|
160
|
-
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
|
|
164
|
-
|
|
165
164
|
}
|
|
166
165
|
|
|
167
166
|
|
|
@@ -171,14 +170,14 @@ fn zcurve_before(sequence: &str, mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[u
|
|
|
171
170
|
/// Returns the onehot encodings in a Vec for the sequences passed to this fucntion.
|
|
172
171
|
///
|
|
173
172
|
/// this function parse the type and length of padding for the encoding
|
|
174
|
-
fn encode_chunks(chunk: &[String], mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[usize; 3]>> , pad_type: &str ) {
|
|
173
|
+
fn encode_chunks(chunk: &[String], mut array: ArrayBase<ViewRepr<&mut i64>, Dim<[usize; 3]>> , pad_type: &str , window: usize) {
|
|
175
174
|
|
|
176
175
|
|
|
177
176
|
if pad_type== "after" {
|
|
178
177
|
|
|
179
178
|
for (seq, sub_array) in chunk.iter().zip(array.axis_iter_mut(Axis(0))) {
|
|
180
179
|
|
|
181
|
-
zcurve_after(seq, sub_array);
|
|
180
|
+
zcurve_after(seq, sub_array, window);
|
|
182
181
|
|
|
183
182
|
}
|
|
184
183
|
}
|
|
@@ -187,7 +186,7 @@ fn encode_chunks(chunk: &[String], mut array: ArrayBase<ViewRepr<&mut i64>, Dim<
|
|
|
187
186
|
|
|
188
187
|
for (seq, sub_array) in chunk.iter().zip(array.axis_iter_mut(Axis(0))) {
|
|
189
188
|
|
|
190
|
-
zcurve_before(seq, sub_array);
|
|
189
|
+
zcurve_before(seq, sub_array, window);
|
|
191
190
|
|
|
192
191
|
}
|
|
193
192
|
}
|
|
@@ -206,7 +205,7 @@ fn encode_chunks(chunk: &[String], mut array: ArrayBase<ViewRepr<&mut i64>, Dim<
|
|
|
206
205
|
///
|
|
207
206
|
/// This function splits the sequences to encode and distributes them to different threads.
|
|
208
207
|
/// the usize is used to keep the order of sequences and the Vec<Array2<i8>> represent the onehot encodings of the genomic sequences
|
|
209
|
-
fn multithreads(sequences: Vec<String>, pad_type: &str, mut array: Array3<i64>, nb_cpus: usize) -> Array3<i64> {
|
|
208
|
+
fn multithreads(sequences: Vec<String>, pad_type: &str, mut array: Array3<i64>, window: usize, nb_cpus: usize) -> Array3<i64> {
|
|
210
209
|
|
|
211
210
|
//determine size of chunks based on number of threads and add 1 to be sure
|
|
212
211
|
//to have a number of chunks equal to nb of cpus and not superior
|
|
@@ -222,7 +221,7 @@ fn multithreads(sequences: Vec<String>, pad_type: &str, mut array: Array3<i64>,
|
|
|
222
221
|
|
|
223
222
|
s.spawn( move || {
|
|
224
223
|
|
|
225
|
-
encode_chunks(chunk_seq, array_slice, pad_type );
|
|
224
|
+
encode_chunks(chunk_seq, array_slice, pad_type, window );
|
|
226
225
|
|
|
227
226
|
});
|
|
228
227
|
|
|
@@ -248,17 +247,18 @@ fn multithreads(sequences: Vec<String>, pad_type: &str, mut array: Array3<i64>,
|
|
|
248
247
|
/// * `n_jobs` - number of threads to use. 0 to use every cpu
|
|
249
248
|
#[allow(unused_must_use)]
|
|
250
249
|
#[pyfunction]
|
|
251
|
-
pub fn zcurve_encoding_rust<'pyt>(py: Python <'pyt>, sequences_py: &Bound<'pyt, PyList>, pad_type: &str, pad_length: i128, n_jobs: i16 ) -> Bound<'pyt, PyArray3<i64>> {
|
|
250
|
+
pub fn zcurve_encoding_rust<'pyt>(py: Python <'pyt>, sequences_py: &Bound<'pyt, PyList>, pad_type: &str, pad_length: i128, window: usize, n_jobs: i16 ) -> Bound<'pyt, PyArray3<i64>> {
|
|
252
251
|
|
|
253
252
|
let sequences: Vec<String> = sequences_py.extract().expect("Error unpacking Python object to Rust");
|
|
254
253
|
|
|
255
|
-
let vec_length= utils::get_length(&sequences, pad_length);
|
|
254
|
+
let mut vec_length= utils::get_length(&sequences, pad_length);
|
|
255
|
+
vec_length= vec_length.div_ceil(window);
|
|
256
256
|
let cpu_to_use= utils::check_nb_cpus(n_jobs);
|
|
257
257
|
|
|
258
258
|
let mut final_array= Array3::<i64>::zeros((sequences.len(), vec_length, 3));
|
|
259
259
|
|
|
260
260
|
|
|
261
|
-
final_array= py.allow_threads(move || multithreads(sequences, pad_type, final_array, cpu_to_use));
|
|
261
|
+
final_array= py.allow_threads(move || multithreads(sequences, pad_type, final_array, window, cpu_to_use));
|
|
262
262
|
|
|
263
263
|
final_array.to_pyarray(py)
|
|
264
264
|
|
|
@@ -4,9 +4,9 @@ import numpy
|
|
|
4
4
|
|
|
5
5
|
def test_load_fasta():
|
|
6
6
|
|
|
7
|
-
expected= [ ("
|
|
8
|
-
("
|
|
9
|
-
("
|
|
7
|
+
expected= [ ("sequence1", "acgtatgcgtcgtc"),
|
|
8
|
+
("sequence2","cccgtga---gtcgat"),
|
|
9
|
+
("sequence3","xgtcgycaaatcg-?")]
|
|
10
10
|
|
|
11
11
|
results= load_fasta("tests/seq_test.fasta")
|
|
12
12
|
|
|
@@ -29,7 +29,7 @@ def test_seq_from_fasta():
|
|
|
29
29
|
|
|
30
30
|
def test_seq_metadata_fasta():
|
|
31
31
|
|
|
32
|
-
expected= ["
|
|
32
|
+
expected= ["sequence1", "sequence2", "sequence3"]
|
|
33
33
|
|
|
34
34
|
results= load_metadata("tests/seq_test.fasta")
|
|
35
35
|
|
|
@@ -38,8 +38,8 @@ def test_seq_metadata_fasta():
|
|
|
38
38
|
def test_list_of_paths():
|
|
39
39
|
paths= ["tests/seq_test.fasta","tests/seq_test.fasta","tests/seq_test.fasta"]
|
|
40
40
|
|
|
41
|
-
fasta_expected= [ ("
|
|
42
|
-
metadata_expected= ["
|
|
41
|
+
fasta_expected= [ ("sequence1", "acgtatgcgtcgtc"), ("sequence2","cccgtga---gtcgat"), ("sequence3","xgtcgycaaatcg-?")]*3
|
|
42
|
+
metadata_expected= ["sequence1", "sequence2", "sequence3"]*3
|
|
43
43
|
sequences_expected= ["acgtatgcgtcgtc", "cccgtga---gtcgat", "xgtcgycaaatcg-?"]*3
|
|
44
44
|
|
|
45
45
|
fasta= load_fasta(paths)
|
|
@@ -64,4 +64,35 @@ def test_unexpected_char():
|
|
|
64
64
|
|
|
65
65
|
for index, x in numpy.ndenumerate(test_matrix):
|
|
66
66
|
|
|
67
|
-
assert x
|
|
67
|
+
assert x
|
|
68
|
+
|
|
69
|
+
def test_window():
|
|
70
|
+
expected= numpy.array([ [0,0,2], [0,0,2], [1,-1,1]])
|
|
71
|
+
results= zcurve_encoding([DNA_SEQUENCES[1]], window= 2)[0]
|
|
72
|
+
|
|
73
|
+
test_matrix= results == expected
|
|
74
|
+
|
|
75
|
+
for index, x in numpy.ndenumerate(test_matrix):
|
|
76
|
+
|
|
77
|
+
assert x
|
|
78
|
+
|
|
79
|
+
def test_window():
|
|
80
|
+
expected= numpy.array([ [0,0,2], [0,0,2], [1,-1,1]])
|
|
81
|
+
results= zcurve_encoding([DNA_SEQUENCES[1]], window= 2)[0]
|
|
82
|
+
|
|
83
|
+
test_matrix= results == expected
|
|
84
|
+
|
|
85
|
+
for index, x in numpy.ndenumerate(test_matrix):
|
|
86
|
+
|
|
87
|
+
assert x
|
|
88
|
+
|
|
89
|
+
def before_test_window():
|
|
90
|
+
expected= numpy.array([ [0,0,0],[0,0,0],[0,0,2], [0,0,2], [1,-1,1]])
|
|
91
|
+
results= zcurve_encoding([DNA_SEQUENCES[1]],pad_length=10, pad_type="before",window= 2)[0]
|
|
92
|
+
|
|
93
|
+
test_matrix= results == expected
|
|
94
|
+
|
|
95
|
+
for index, x in numpy.ndenumerate(test_matrix):
|
|
96
|
+
|
|
97
|
+
assert x
|
|
98
|
+
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
use std::fs::File;
|
|
2
|
-
use pyo3::prelude::*;
|
|
3
|
-
use std::io::{prelude::*, BufReader};
|
|
4
|
-
|
|
5
|
-
//implement a struct for fasta file?
|
|
6
|
-
|
|
7
|
-
/// Returns a Vec of string where each string is one of the genomic sequences in the fasta file
|
|
8
|
-
/// The order in which the sequences appear in the fasta file is conserved
|
|
9
|
-
///
|
|
10
|
-
/// # Arguments
|
|
11
|
-
/// * `file_path` - path to the fasta file
|
|
12
|
-
#[pyfunction]
|
|
13
|
-
pub fn seq_from_fasta_rust(file_path: &str) -> Vec<String> {
|
|
14
|
-
|
|
15
|
-
let f = File::open(file_path).expect("Unable to open file");
|
|
16
|
-
let f = BufReader::new(f);
|
|
17
|
-
|
|
18
|
-
let mut sequences = Vec::new();
|
|
19
|
-
let mut seq= String::from("");
|
|
20
|
-
|
|
21
|
-
for line in f.lines(){
|
|
22
|
-
|
|
23
|
-
let line = line.expect("Unable to read line");
|
|
24
|
-
|
|
25
|
-
if line.starts_with('>') {
|
|
26
|
-
|
|
27
|
-
if !seq.is_empty() {
|
|
28
|
-
|
|
29
|
-
sequences.push(seq);
|
|
30
|
-
seq= String::from("");
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
else {
|
|
35
|
-
|
|
36
|
-
seq.push_str(line.trim());
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if !seq.is_empty() {
|
|
43
|
-
sequences.push(seq);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
sequences
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/// Returns a Vec of string where each string is the metadata for one genomic sequence
|
|
51
|
-
/// The order in which the sequences metadata appear in the fasta file is conserved
|
|
52
|
-
///
|
|
53
|
-
/// # Arguments
|
|
54
|
-
/// * `file_path` - path to the fasta file
|
|
55
|
-
#[pyfunction]
|
|
56
|
-
pub fn metadata_from_fasta_rust(file_path: &str) -> Vec<String> {
|
|
57
|
-
|
|
58
|
-
let f = File::open(file_path).expect("Unable to open file");
|
|
59
|
-
let f = BufReader::new(f);
|
|
60
|
-
|
|
61
|
-
let mut metadata = Vec::new();
|
|
62
|
-
|
|
63
|
-
for line in f.lines() {
|
|
64
|
-
|
|
65
|
-
let line = line.expect("Unable to read line");
|
|
66
|
-
|
|
67
|
-
if line.starts_with('>') {
|
|
68
|
-
|
|
69
|
-
metadata.push(line)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
metadata
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
/// Returns a Vec of tuples each containing 2 strings. The first string is the metadata and the second one is the associated genomic sequence
|
|
78
|
-
/// The order in which the metadatas and sequences appear in the fasta file is conserved
|
|
79
|
-
///
|
|
80
|
-
/// # Arguments
|
|
81
|
-
/// * `file_path` - path to the fasta files
|
|
82
|
-
#[pyfunction]
|
|
83
|
-
pub fn load_fasta_rust(file_path: &str) -> Vec<(String,String)> {
|
|
84
|
-
|
|
85
|
-
let f = File::open(file_path).expect("Unable to open file");
|
|
86
|
-
let reader = BufReader::new(f);
|
|
87
|
-
|
|
88
|
-
let mut metadata_and_seq = Vec::new();
|
|
89
|
-
let mut metadata= String::from("");
|
|
90
|
-
let mut seq= String::from("");
|
|
91
|
-
|
|
92
|
-
for line in reader.lines() {
|
|
93
|
-
|
|
94
|
-
let line = line.expect("Unable to read line");
|
|
95
|
-
|
|
96
|
-
if line.starts_with('>') {
|
|
97
|
-
|
|
98
|
-
if !seq.is_empty() {
|
|
99
|
-
|
|
100
|
-
metadata_and_seq.push((metadata, seq));
|
|
101
|
-
seq= String::from("");
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
metadata= line;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
else {
|
|
108
|
-
|
|
109
|
-
seq.push_str(line.trim())
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if !seq.is_empty() {
|
|
116
|
-
|
|
117
|
-
metadata_and_seq.push((metadata, seq));
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
metadata_and_seq
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// ################ test implementation generator load seq #############
|
|
126
|
-
|
|
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
|
|
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
|