trackplot 0.5.7__tar.gz → 0.5.9__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.
- {trackplot-0.5.7/trackplot.egg-info → trackplot-0.5.9}/PKG-INFO +2 -2
- {trackplot-0.5.7 → trackplot-0.5.9}/pyproject.toml +2 -2
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/anno/AxLabel.py +2 -5
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/anno/theme.py +8 -7
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/CoordinateMap.py +39 -45
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/GenomicLoci.py +22 -23
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/Junction.py +18 -18
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/Protein.py +66 -69
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/ReadDepth.py +69 -34
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/Readder.py +68 -32
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/Stroke.py +9 -3
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/Transcript.py +24 -26
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/pyUniprot.py +63 -42
- trackplot-0.5.9/trackplot/cli.py +1375 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/conf/DomainSetting.py +108 -23
- trackplot-0.5.9/trackplot/conf/config.py +122 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/conf/drawing.py +28 -17
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/conf/ui.py +173 -130
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/ATAC.py +38 -26
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/Annotation.py +176 -109
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/Bam.py +115 -58
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/BedGraph.py +4 -4
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/Bigwig.py +7 -4
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/Depth.py +20 -16
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/Fasta.py +5 -7
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/File.py +29 -11
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/HiCMatrixTrack.py +67 -48
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/Junction.py +3 -2
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/Motif.py +8 -9
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/ReadSegments.py +178 -122
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/plot.py +508 -351
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/plot_func.py +891 -411
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/server.py +60 -28
- {trackplot-0.5.7 → trackplot-0.5.9/trackplot.egg-info}/PKG-INFO +2 -2
- trackplot-0.5.9/trackplot.egg-info/SOURCES.txt +44 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot.egg-info/top_level.txt +0 -1
- trackplot-0.5.7/trackplot/cli.py +0 -787
- trackplot-0.5.7/trackplot/conf/config.py +0 -36
- trackplot-0.5.7/trackplot/plot_tests.py +0 -210
- trackplot-0.5.7/trackplot.egg-info/SOURCES.txt +0 -98
- trackplot-0.5.7/ui/assets/Home-7GzAh8lS.js +0 -1
- trackplot-0.5.7/ui/assets/Home-BV58jH3t.js +0 -1
- trackplot-0.5.7/ui/assets/Home-CDW3Zwoa.js +0 -1
- trackplot-0.5.7/ui/assets/Home-DOO13BH7.js +0 -1
- trackplot-0.5.7/ui/assets/Home-DZ_TnNqV.js +0 -1
- trackplot-0.5.7/ui/assets/Home-QmeAKOl4.js +0 -1
- trackplot-0.5.7/ui/assets/Home-RdVPWns6.js +0 -1
- trackplot-0.5.7/ui/assets/Home-jSR0MsHI.css +0 -1
- trackplot-0.5.7/ui/assets/Home-zRV7yePL.css +0 -1
- trackplot-0.5.7/ui/assets/Plot-BALbchCV.css +0 -1
- trackplot-0.5.7/ui/assets/Plot-BmqHZ4QE.css +0 -1
- trackplot-0.5.7/ui/assets/Plot-BrjU8Kwg.js +0 -17
- trackplot-0.5.7/ui/assets/Plot-Bvyo6ju9.css +0 -1
- trackplot-0.5.7/ui/assets/Plot-C4RNyMVn.css +0 -1
- trackplot-0.5.7/ui/assets/Plot-COvGnprQ.css +0 -1
- trackplot-0.5.7/ui/assets/Plot-CTM-EDrj.js +0 -25
- trackplot-0.5.7/ui/assets/Plot-Ch3Psf3q.js +0 -17
- trackplot-0.5.7/ui/assets/Plot-Cnt8iJB8.js +0 -21
- trackplot-0.5.7/ui/assets/Plot-Cyj_LlDt.js +0 -17
- trackplot-0.5.7/ui/assets/Plot-DiuFnwNK.js +0 -25
- trackplot-0.5.7/ui/assets/Plot-DpL7z7tp.css +0 -1
- trackplot-0.5.7/ui/assets/Plot-hvkDteAn.js +0 -25
- trackplot-0.5.7/ui/assets/Plot-rbQz1TOM.css +0 -1
- trackplot-0.5.7/ui/assets/el-divider-BHm65SRq.css +0 -1
- trackplot-0.5.7/ui/assets/el-divider-BVZhQIwQ.js +0 -1
- trackplot-0.5.7/ui/assets/el-divider-Brt4-Qvr.js +0 -1
- trackplot-0.5.7/ui/assets/el-divider-BuEUMHwE.css +0 -1
- trackplot-0.5.7/ui/assets/el-divider-C8ttpjuy.css +0 -1
- trackplot-0.5.7/ui/assets/el-divider-Cwxg0Ado.css +0 -1
- trackplot-0.5.7/ui/assets/el-divider-DcvrsrBa.css +0 -1
- trackplot-0.5.7/ui/assets/el-divider-DnCOJT55.js +0 -1
- trackplot-0.5.7/ui/assets/el-divider-IbBQ8ZK2.js +0 -4
- trackplot-0.5.7/ui/assets/el-divider-SYT5K-ds.css +0 -1
- trackplot-0.5.7/ui/assets/el-divider-VYjL3C7L.js +0 -1
- trackplot-0.5.7/ui/assets/el-divider-eEJXnQD5.js +0 -1
- trackplot-0.5.7/ui/assets/el-divider-i9JMIXVR.css +0 -1
- trackplot-0.5.7/ui/assets/el-divider-u9f0bZWY.js +0 -1
- trackplot-0.5.7/ui/assets/index-4hxJ_zbq.js +0 -26
- trackplot-0.5.7/ui/assets/index-C4Mi9Kmf.js +0 -30
- trackplot-0.5.7/ui/assets/index-CETGMNio.css +0 -1
- trackplot-0.5.7/ui/assets/index-CWfdj0DH.js +0 -26
- trackplot-0.5.7/ui/assets/index-Cexhr_fn.css +0 -1
- trackplot-0.5.7/ui/assets/index-CrzyEb9s.js +0 -31
- trackplot-0.5.7/ui/assets/index-DRYYJBwu.js +0 -30
- trackplot-0.5.7/ui/assets/index-D_Cw0sbX.js +0 -26
- trackplot-0.5.7/ui/assets/index-Dd6Bavnk.js +0 -26
- trackplot-0.5.7/ui/assets/index-DgEIiwRJ.css +0 -1
- trackplot-0.5.7/ui/assets/index-O8P0XkxB.css +0 -1
- trackplot-0.5.7/ui/assets/index-Sq2gI4sE.css +0 -1
- trackplot-0.5.7/ui/assets/index-ns9n7-F7.css +0 -1
- trackplot-0.5.7/ui/assets/index-p5klR3EI.css +0 -1
- trackplot-0.5.7/ui/index.html +0 -14
- trackplot-0.5.7/ui/vite.svg +0 -1
- {trackplot-0.5.7 → trackplot-0.5.9}/LICENSE +0 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/README.md +0 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/setup.cfg +0 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/__init__.py +0 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/anno/__init__.py +0 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/base/__init__.py +0 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/conf/__init__.py +0 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot/file/__init__.py +0 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot.egg-info/dependency_links.txt +0 -0
- {trackplot-0.5.7 → trackplot-0.5.9}/trackplot.egg-info/requires.txt +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trackplot
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.9
|
|
4
4
|
Summary: The trackplot is a tool for visualizing various next-generation sequencing (NGS) data, including DNA-seq, RNA-seq, single-cell RNA-seq and full-length sequencing datasets. https://sashimi.readthedocs.io/
|
|
5
5
|
Author-email: ygidtu <ygidtu@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
7
|
-
Requires-Python:
|
|
7
|
+
Requires-Python: <3.14,>=3.11
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Dist: adjusttext>=1.3.0
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "trackplot"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.9"
|
|
4
4
|
description = "The trackplot is a tool for visualizing various next-generation sequencing (NGS) data, including DNA-seq, RNA-seq, single-cell RNA-seq and full-length sequencing datasets. https://sashimi.readthedocs.io/"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "ygidtu", email = "ygidtu@gmail.com" }
|
|
7
7
|
]
|
|
8
8
|
license = "BSD-3-Clause"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.11"
|
|
10
|
+
requires-python = ">=3.11, <3.14"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"adjusttext>=1.3.0",
|
|
13
13
|
"cairocffi>=1.7.1",
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding:utf-8 -*-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"""
|
|
3
|
+
""" """
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
class AxLabel(object):
|
|
9
|
-
|
|
10
7
|
__slots__ = ["Ax", "Label"]
|
|
11
8
|
|
|
12
9
|
def __init__(self, ax, label):
|
|
@@ -20,5 +17,5 @@ class AxLabel(object):
|
|
|
20
17
|
return self.__hash__() == other.__hash__()
|
|
21
18
|
|
|
22
19
|
|
|
23
|
-
if __name__ ==
|
|
20
|
+
if __name__ == "__main__":
|
|
24
21
|
pass
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding:utf-8 -*-
|
|
3
|
-
|
|
3
|
+
"""
|
|
4
4
|
This file contains the configuration of different themes
|
|
5
5
|
"""
|
|
6
|
+
|
|
6
7
|
from matplotlib import axes
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class Theme(object):
|
|
10
11
|
@classmethod
|
|
11
12
|
def blank(cls, ax: axes.Axes):
|
|
12
|
-
|
|
13
|
+
"""
|
|
13
14
|
|
|
14
15
|
:param ax:
|
|
15
16
|
:return:
|
|
@@ -23,15 +24,15 @@ class Theme(object):
|
|
|
23
24
|
|
|
24
25
|
@classmethod
|
|
25
26
|
def ticks(cls, ax: axes.Axes):
|
|
26
|
-
ax.spines[
|
|
27
|
-
ax.spines[
|
|
27
|
+
ax.spines["top"].set_visible(False)
|
|
28
|
+
ax.spines["right"].set_visible(False)
|
|
28
29
|
ax.tick_params(bottom=True, top=False, left=True, right=False)
|
|
29
30
|
|
|
30
31
|
@classmethod
|
|
31
32
|
def ticks_blank(cls, ax: axes.Axes):
|
|
32
|
-
ax.spines[
|
|
33
|
-
ax.spines[
|
|
34
|
-
ax.spines[
|
|
33
|
+
ax.spines["top"].set_visible(False)
|
|
34
|
+
ax.spines["right"].set_visible(False)
|
|
35
|
+
ax.spines["bottom"].set_visible(False)
|
|
35
36
|
ax.set_xticklabels([])
|
|
36
37
|
ax.tick_params(bottom=False, top=False, left=True, right=False)
|
|
37
38
|
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
# @Time : 2019/1/11 2:55 PM
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
"""
|
|
6
6
|
Convert aa position into genomic coordinate, Ran zhou.
|
|
7
7
|
|
|
8
8
|
"""
|
|
9
|
+
|
|
9
10
|
from itertools import islice
|
|
10
11
|
from typing import Optional
|
|
11
12
|
|
|
@@ -13,38 +14,41 @@ import numpy as np
|
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class Coordinate(object):
|
|
16
|
-
|
|
17
|
+
"""
|
|
17
18
|
A Coordinate object for genomic regions.
|
|
18
19
|
"""
|
|
19
20
|
|
|
20
21
|
__slots__ = ["strand", "se"]
|
|
21
22
|
|
|
22
23
|
def __init__(self, coordinate_list: list, strand: str = "*"):
|
|
23
|
-
|
|
24
|
+
"""
|
|
24
25
|
Set genomic coordinates
|
|
25
26
|
:param coordinate_list: a nested tuple of list
|
|
26
27
|
:param strand: a strands of given coordinate object
|
|
27
28
|
"""
|
|
28
29
|
self.strand = strand
|
|
29
30
|
self.se = self.__fmt_exons__(coordinate_list)
|
|
30
|
-
assert len(self.location_list) == len(set(self.location_list)),
|
|
31
|
+
assert len(self.location_list) == len(set(self.location_list)), (
|
|
31
32
|
f"Overlapped regions were found in {self.se}"
|
|
33
|
+
)
|
|
32
34
|
|
|
33
35
|
@staticmethod
|
|
34
36
|
def __fmt_exons__(coordinate_list: list) -> list:
|
|
35
|
-
|
|
37
|
+
"""
|
|
36
38
|
Format and sort exon list
|
|
37
39
|
:param coordinate_list: a nested tuple of list. like [('5','6'),('1','4')]
|
|
38
40
|
:return: a nested tuple of list. like [(1,4), (5,6)]
|
|
39
41
|
"""
|
|
40
42
|
# sorting coordinate based on first of location.
|
|
41
|
-
formatted_coordinate_list = list(
|
|
43
|
+
formatted_coordinate_list = list(
|
|
44
|
+
map(lambda x: tuple(map(int, x)), coordinate_list)
|
|
45
|
+
)
|
|
42
46
|
formatted_coordinate_list.sort(key=lambda x: x[0])
|
|
43
47
|
return formatted_coordinate_list
|
|
44
48
|
|
|
45
49
|
@staticmethod
|
|
46
50
|
def __get_s_or_e__(coordinate_list: list, index: int) -> list:
|
|
47
|
-
|
|
51
|
+
"""
|
|
48
52
|
Get start or end site for each given coordinates
|
|
49
53
|
:param coordinate_list: a nested tuple of list, like [(1,3),(5,6)]
|
|
50
54
|
:param index: the index of tuple, 0 for the left site and 1 for the right end site.
|
|
@@ -62,7 +66,7 @@ class Coordinate(object):
|
|
|
62
66
|
|
|
63
67
|
@property
|
|
64
68
|
def introns(self):
|
|
65
|
-
|
|
69
|
+
"""
|
|
66
70
|
Set intronic regions for each coordinate object
|
|
67
71
|
:return: a nested tuple of list which contained intronic coordinates.
|
|
68
72
|
"""
|
|
@@ -71,19 +75,16 @@ class Coordinate(object):
|
|
|
71
75
|
else:
|
|
72
76
|
introns_list = []
|
|
73
77
|
for left_exon, right_exon in self.__slide_window__(self.se, num_of_chunk=2):
|
|
74
|
-
introns_list.append(tuple(
|
|
75
|
-
[left_exon[1] + 1,
|
|
76
|
-
right_exon[0] - 1]
|
|
77
|
-
))
|
|
78
|
+
introns_list.append(tuple([left_exon[1] + 1, right_exon[0] - 1]))
|
|
78
79
|
return introns_list
|
|
79
80
|
|
|
80
81
|
@staticmethod
|
|
81
82
|
def __slide_window__(nested_list: list, num_of_chunk: int):
|
|
82
|
-
|
|
83
|
+
"""
|
|
83
84
|
A sliding window to slice the given list
|
|
84
85
|
:param nested_list: a nested tuple of list, like [(1,3),(5,6)]
|
|
85
86
|
:param num_of_chunk: num of element for each chunk.
|
|
86
|
-
:return:
|
|
87
|
+
:return:
|
|
87
88
|
"""
|
|
88
89
|
nested_list = iter(nested_list)
|
|
89
90
|
chunked_list = list(islice(nested_list, num_of_chunk))
|
|
@@ -95,7 +96,7 @@ class Coordinate(object):
|
|
|
95
96
|
|
|
96
97
|
@classmethod
|
|
97
98
|
def __flatten__(cls, nested_list: list):
|
|
98
|
-
|
|
99
|
+
"""
|
|
99
100
|
Flatten the nested list
|
|
100
101
|
:param nested_list: a nested tuple of list, like [(1,3),(5,6)]
|
|
101
102
|
:return:
|
|
@@ -109,33 +110,33 @@ class Coordinate(object):
|
|
|
109
110
|
|
|
110
111
|
@property
|
|
111
112
|
def location_list(self) -> np.ndarray:
|
|
112
|
-
|
|
113
|
+
"""
|
|
113
114
|
Get a list which contained all position.
|
|
114
115
|
For example, an exon list `[(10, 15), (20,25)]` as input,
|
|
115
116
|
[10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25] will return
|
|
116
117
|
:return: a list which contained all position
|
|
117
118
|
"""
|
|
118
119
|
# Add 1 offset because of 0-based coordinate
|
|
119
|
-
position_list = list(
|
|
120
|
-
lambda x: range(x[0], x[1] + 1), self.se
|
|
121
|
-
)
|
|
120
|
+
position_list = list(
|
|
121
|
+
self.__flatten__(list(map(lambda x: range(x[0], x[1] + 1), self.se)))
|
|
122
|
+
)
|
|
122
123
|
|
|
123
|
-
if self.strand ==
|
|
124
|
+
if self.strand == "-":
|
|
124
125
|
return np.array(position_list[::-1])
|
|
125
126
|
|
|
126
127
|
return np.array(position_list)
|
|
127
128
|
|
|
128
129
|
@property
|
|
129
130
|
def pep_index(self) -> np.ndarray:
|
|
130
|
-
|
|
131
|
+
"""
|
|
131
132
|
Relative position of pep coordinates
|
|
132
|
-
:return:
|
|
133
|
+
:return:
|
|
133
134
|
"""
|
|
134
135
|
return np.array(list(map(lambda x: int(x / 3), range(len(self.location_list)))))
|
|
135
136
|
|
|
136
137
|
@property
|
|
137
138
|
def cds_index(self) -> np.ndarray:
|
|
138
|
-
|
|
139
|
+
"""
|
|
139
140
|
Relative position of cds coordinates
|
|
140
141
|
:return:
|
|
141
142
|
"""
|
|
@@ -143,7 +144,7 @@ class Coordinate(object):
|
|
|
143
144
|
|
|
144
145
|
@staticmethod
|
|
145
146
|
def __group_consecutive_value__(location_list: np.ndarray, strand: str) -> list:
|
|
146
|
-
|
|
147
|
+
"""
|
|
147
148
|
group the consecutive value into a list
|
|
148
149
|
|
|
149
150
|
:param location_list: a list of location site
|
|
@@ -153,46 +154,39 @@ class Coordinate(object):
|
|
|
153
154
|
offset = -1 if strand == "-" else 1
|
|
154
155
|
group_ids = np.concatenate(([0], (np.diff(location_list) != offset).cumsum()))
|
|
155
156
|
|
|
156
|
-
grouped_truncated_location_array =
|
|
157
|
-
np.
|
|
158
|
-
|
|
159
|
-
np.unique(group_ids, return_counts=True)[1].cumsum().tolist()
|
|
160
|
-
)
|
|
157
|
+
grouped_truncated_location_array = np.split(
|
|
158
|
+
location_list, np.unique(group_ids, return_counts=True)[1].cumsum().tolist()
|
|
159
|
+
)
|
|
161
160
|
|
|
162
161
|
return grouped_truncated_location_array
|
|
163
162
|
|
|
164
163
|
@classmethod
|
|
165
164
|
def init_from_location_list(cls, truncated_location_array: np.ndarray, strand: str):
|
|
166
|
-
|
|
165
|
+
"""
|
|
167
166
|
init class based on the list of location
|
|
168
167
|
:param truncated_location_array: truncated location array
|
|
169
168
|
:param strand: the strand of the current list
|
|
170
169
|
:return:
|
|
171
170
|
"""
|
|
172
171
|
__coordinate_list = []
|
|
173
|
-
for sub_array in cls.__group_consecutive_value__(
|
|
172
|
+
for sub_array in cls.__group_consecutive_value__(
|
|
173
|
+
truncated_location_array, strand
|
|
174
|
+
):
|
|
174
175
|
if len(sub_array) == 0:
|
|
175
176
|
continue
|
|
176
177
|
|
|
177
|
-
__coordinate_list.append(
|
|
178
|
-
tuple(
|
|
179
|
-
[
|
|
180
|
-
min(sub_array),
|
|
181
|
-
max(sub_array)
|
|
182
|
-
]
|
|
183
|
-
)
|
|
184
|
-
)
|
|
178
|
+
__coordinate_list.append(tuple([min(sub_array), max(sub_array)]))
|
|
185
179
|
return cls(__coordinate_list, strand)
|
|
186
180
|
|
|
187
181
|
|
|
188
182
|
class CoordinateMapper(Coordinate):
|
|
189
|
-
|
|
183
|
+
"""
|
|
190
184
|
Convert positions between CDS and protein coordinates.
|
|
191
185
|
TODO: Add cds to pep coordinate?
|
|
192
186
|
"""
|
|
193
187
|
|
|
194
188
|
def __init__(self, coordinates_list, strand: str):
|
|
195
|
-
|
|
189
|
+
"""
|
|
196
190
|
Set genomic coordinates to be used for mapping
|
|
197
191
|
:param coordinates_list: a nested tuple of list
|
|
198
192
|
:param strand: a strands of given coordinate object
|
|
@@ -200,7 +194,7 @@ class CoordinateMapper(Coordinate):
|
|
|
200
194
|
super().__init__(coordinate_list=coordinates_list, strand=strand)
|
|
201
195
|
|
|
202
196
|
def pep_to_cds(self, pep_start: int, pep_end: Optional[int] = None):
|
|
203
|
-
|
|
197
|
+
"""
|
|
204
198
|
Convert pep position into genomic position
|
|
205
199
|
:param pep_start: the start position of pep
|
|
206
200
|
:param pep_end: the end position of pep, if None, the start site is equal to end site
|
|
@@ -216,9 +210,9 @@ class CoordinateMapper(Coordinate):
|
|
|
216
210
|
cds_left_index, cds_right_index = start_ind[0], end_ind[-1] + 1
|
|
217
211
|
|
|
218
212
|
return self.init_from_location_list(
|
|
219
|
-
self.location_list[cds_left_index:cds_right_index],
|
|
220
|
-
|
|
213
|
+
self.location_list[cds_left_index:cds_right_index], self.strand
|
|
214
|
+
)
|
|
221
215
|
|
|
222
216
|
|
|
223
|
-
if __name__ ==
|
|
217
|
+
if __name__ == "__main__":
|
|
224
218
|
pass
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding:utf-8 -*-
|
|
3
|
-
|
|
3
|
+
"""
|
|
4
4
|
Created by ygidtu@gmail.com at 2019.01.04
|
|
5
5
|
|
|
6
6
|
This script contains all the basic data types used by this suite of scripts
|
|
@@ -13,23 +13,16 @@ Changelog:
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class GenomicLoci(object):
|
|
16
|
-
|
|
16
|
+
"""
|
|
17
17
|
Created by ygidtu at 2018.12.19
|
|
18
18
|
|
|
19
19
|
A base class to handle the position relationships
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
-
__slots__ = [
|
|
23
|
-
"chromosome",
|
|
24
|
-
"start",
|
|
25
|
-
"end",
|
|
26
|
-
"strand",
|
|
27
|
-
"gtf_line",
|
|
28
|
-
"name"
|
|
29
|
-
]
|
|
22
|
+
__slots__ = ["chromosome", "start", "end", "strand", "gtf_line", "name"]
|
|
30
23
|
|
|
31
24
|
def __init__(self, chromosome, start, end, strand, name="", gtf_line=None):
|
|
32
|
-
|
|
25
|
+
"""
|
|
33
26
|
init this class
|
|
34
27
|
:param chromosome: str
|
|
35
28
|
:param start: int
|
|
@@ -47,7 +40,9 @@ class GenomicLoci(object):
|
|
|
47
40
|
self.name = name
|
|
48
41
|
|
|
49
42
|
if self.end < self.start:
|
|
50
|
-
raise ValueError(
|
|
43
|
+
raise ValueError(
|
|
44
|
+
f"End site should bigger than start site, not {self.start} -> {self.end}"
|
|
45
|
+
)
|
|
51
46
|
if strand == ".":
|
|
52
47
|
strand = "*"
|
|
53
48
|
if strand not in ("+", "-", "*"):
|
|
@@ -56,7 +51,7 @@ class GenomicLoci(object):
|
|
|
56
51
|
self.strand = strand
|
|
57
52
|
|
|
58
53
|
def __str__(self):
|
|
59
|
-
|
|
54
|
+
"""
|
|
60
55
|
convert this to string
|
|
61
56
|
:return:
|
|
62
57
|
"""
|
|
@@ -65,11 +60,11 @@ class GenomicLoci(object):
|
|
|
65
60
|
return f"{self.chromosome}:{self.start}-{self.end}:{self.strand}"
|
|
66
61
|
|
|
67
62
|
def __iter__(self):
|
|
68
|
-
for i in range(self.start, self.end+1):
|
|
63
|
+
for i in range(self.start, self.end + 1):
|
|
69
64
|
yield i
|
|
70
65
|
|
|
71
66
|
def __gt__(self, other):
|
|
72
|
-
|
|
67
|
+
"""
|
|
73
68
|
if other downstream of other
|
|
74
69
|
|
|
75
70
|
Note:
|
|
@@ -88,7 +83,7 @@ class GenomicLoci(object):
|
|
|
88
83
|
return self.end < other.end
|
|
89
84
|
|
|
90
85
|
def __lt__(self, other):
|
|
91
|
-
|
|
86
|
+
"""
|
|
92
87
|
if other is upstream of other
|
|
93
88
|
|
|
94
89
|
Note:
|
|
@@ -107,7 +102,7 @@ class GenomicLoci(object):
|
|
|
107
102
|
return self.end > other.end
|
|
108
103
|
|
|
109
104
|
def __eq__(self, other):
|
|
110
|
-
|
|
105
|
+
"""
|
|
111
106
|
if two objects are the same
|
|
112
107
|
:param other:
|
|
113
108
|
:return:
|
|
@@ -115,7 +110,7 @@ class GenomicLoci(object):
|
|
|
115
110
|
return hash(self) == hash(other)
|
|
116
111
|
|
|
117
112
|
def __add__(self, other):
|
|
118
|
-
|
|
113
|
+
"""
|
|
119
114
|
merge two sites into one
|
|
120
115
|
:param other:
|
|
121
116
|
:return:
|
|
@@ -124,11 +119,11 @@ class GenomicLoci(object):
|
|
|
124
119
|
chromosome=self.chromosome,
|
|
125
120
|
start=min(self.start, other.start),
|
|
126
121
|
end=max(self.end, other.end),
|
|
127
|
-
strand=self.strand
|
|
122
|
+
strand=self.strand,
|
|
128
123
|
)
|
|
129
124
|
|
|
130
125
|
def __hash__(self):
|
|
131
|
-
|
|
126
|
+
"""
|
|
132
127
|
generate hash
|
|
133
128
|
:return:
|
|
134
129
|
"""
|
|
@@ -138,16 +133,20 @@ class GenomicLoci(object):
|
|
|
138
133
|
return self.end - self.start + 1
|
|
139
134
|
|
|
140
135
|
def is_overlap(self, other):
|
|
141
|
-
|
|
136
|
+
"""
|
|
142
137
|
whether two loci have any overlaps
|
|
143
138
|
:param other: another GenomicLoci and it's children class
|
|
144
139
|
:return: Boolean
|
|
145
140
|
"""
|
|
146
|
-
return
|
|
141
|
+
return (
|
|
142
|
+
self.chromosome == other.chromosome
|
|
143
|
+
and self.start <= other.end
|
|
144
|
+
and self.end >= other.start
|
|
145
|
+
)
|
|
147
146
|
|
|
148
147
|
@classmethod
|
|
149
148
|
def create_loci(cls, string):
|
|
150
|
-
|
|
149
|
+
"""
|
|
151
150
|
Create loci from String
|
|
152
151
|
:param string: chr1:1-100:+
|
|
153
152
|
:return:
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding:utf-8 -*-
|
|
3
|
-
|
|
3
|
+
"""
|
|
4
4
|
Created by ygidtu@gmail.com at 2019.12.06
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class Junction(object):
|
|
9
|
-
|
|
9
|
+
"""
|
|
10
10
|
Created by ygidtu at 2018.12.19
|
|
11
11
|
|
|
12
12
|
This is used to collect information of single junction
|
|
@@ -16,7 +16,7 @@ class Junction(object):
|
|
|
16
16
|
__slots__ = ["chromosome", "start", "end", "strand"]
|
|
17
17
|
|
|
18
18
|
def __init__(self, chromosome, start, end, strand: str = "+"):
|
|
19
|
-
|
|
19
|
+
"""
|
|
20
20
|
init this class
|
|
21
21
|
:param chromosome: the chromosome name of the given junction
|
|
22
22
|
:param start: the start site of the given junction
|
|
@@ -33,14 +33,14 @@ class Junction(object):
|
|
|
33
33
|
|
|
34
34
|
@property
|
|
35
35
|
def length(self):
|
|
36
|
-
|
|
36
|
+
"""
|
|
37
37
|
:return: int, the length of this junction
|
|
38
38
|
"""
|
|
39
39
|
return self.end - self.start
|
|
40
40
|
|
|
41
41
|
@classmethod
|
|
42
42
|
def create_junction(cls, string):
|
|
43
|
-
|
|
43
|
+
"""
|
|
44
44
|
create Junction from chr1:1-100:+
|
|
45
45
|
:param string: str, chr1:1-100:+ format or chr1:1-100 also work
|
|
46
46
|
:return:
|
|
@@ -57,21 +57,21 @@ class Junction(object):
|
|
|
57
57
|
return cls(chromosome=chromosome, start=start, end=end, strand=strand)
|
|
58
58
|
|
|
59
59
|
def __hash__(self):
|
|
60
|
-
|
|
60
|
+
"""
|
|
61
61
|
generate hash
|
|
62
62
|
:return:
|
|
63
63
|
"""
|
|
64
64
|
return hash((self.chromosome, self.start, self.end, self.strand))
|
|
65
65
|
|
|
66
66
|
def __str__(self):
|
|
67
|
-
|
|
67
|
+
"""
|
|
68
68
|
convert junctions to string
|
|
69
69
|
:return:
|
|
70
70
|
"""
|
|
71
71
|
return f"{self.chromosome}:{self.start}-{self.end}:{self.strand}"
|
|
72
72
|
|
|
73
73
|
def __gt__(self, other):
|
|
74
|
-
|
|
74
|
+
"""
|
|
75
75
|
greater than
|
|
76
76
|
compare two junction by length
|
|
77
77
|
:param other:
|
|
@@ -80,7 +80,7 @@ class Junction(object):
|
|
|
80
80
|
return self.length > other.length
|
|
81
81
|
|
|
82
82
|
def __lt__(self, other):
|
|
83
|
-
|
|
83
|
+
"""
|
|
84
84
|
less than
|
|
85
85
|
compare two junction by length
|
|
86
86
|
:param other:a
|
|
@@ -89,7 +89,7 @@ class Junction(object):
|
|
|
89
89
|
return self.length < other.length
|
|
90
90
|
|
|
91
91
|
def __eq__(self, other):
|
|
92
|
-
|
|
92
|
+
"""
|
|
93
93
|
same length
|
|
94
94
|
:param other:
|
|
95
95
|
:return:
|
|
@@ -97,7 +97,7 @@ class Junction(object):
|
|
|
97
97
|
return self.length == other.length
|
|
98
98
|
|
|
99
99
|
def is_overlap(self, other):
|
|
100
|
-
|
|
100
|
+
"""
|
|
101
101
|
whether any overlap with another Junction or GenomicLoci
|
|
102
102
|
:param other:
|
|
103
103
|
:return:
|
|
@@ -109,7 +109,7 @@ class Junction(object):
|
|
|
109
109
|
return self.start < other.end and self.end > other.start
|
|
110
110
|
|
|
111
111
|
def is_upstream(self, other):
|
|
112
|
-
|
|
112
|
+
"""
|
|
113
113
|
whether this junction is upstream of other
|
|
114
114
|
:param other:
|
|
115
115
|
:return:
|
|
@@ -122,7 +122,7 @@ class Junction(object):
|
|
|
122
122
|
return self.end < self.start
|
|
123
123
|
|
|
124
124
|
def is_downstream(self, other):
|
|
125
|
-
|
|
125
|
+
"""
|
|
126
126
|
whether this junction is downstream of other
|
|
127
127
|
:param other:
|
|
128
128
|
:return:
|
|
@@ -135,8 +135,8 @@ class Junction(object):
|
|
|
135
135
|
return self.start > other.end
|
|
136
136
|
|
|
137
137
|
def str(self, with_strand: bool = True) -> str:
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
"""convert junctions to string, with or without strand
|
|
139
|
+
|
|
140
140
|
Keyword arguments:
|
|
141
141
|
:param with_strand: as name says
|
|
142
142
|
Return: chr:strat-end:strand or chr:start-end
|
|
@@ -144,11 +144,11 @@ class Junction(object):
|
|
|
144
144
|
if with_strand:
|
|
145
145
|
return str(self)
|
|
146
146
|
return f"{self.chromosome}:{self.start}-{self.end}"
|
|
147
|
-
|
|
147
|
+
|
|
148
148
|
def eq(self, other, with_strand: bool = False):
|
|
149
|
-
|
|
149
|
+
"""判断两个位点是否一致"""
|
|
150
150
|
return self.str(with_strand) == other.str(with_strand)
|
|
151
151
|
|
|
152
152
|
|
|
153
|
-
if __name__ ==
|
|
153
|
+
if __name__ == "__main__":
|
|
154
154
|
pass
|