RNApolis 0.4.6__py3-none-any.whl → 0.4.8__py3-none-any.whl
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.
- {RNApolis-0.4.6.dist-info → RNApolis-0.4.8.dist-info}/METADATA +1 -1
- {RNApolis-0.4.6.dist-info → RNApolis-0.4.8.dist-info}/RECORD +8 -8
- {RNApolis-0.4.6.dist-info → RNApolis-0.4.8.dist-info}/WHEEL +1 -1
- rnapolis/common.py +12 -4
- rnapolis/tertiary.py +59 -29
- {RNApolis-0.4.6.dist-info → RNApolis-0.4.8.dist-info}/LICENSE +0 -0
- {RNApolis-0.4.6.dist-info → RNApolis-0.4.8.dist-info}/entry_points.txt +0 -0
- {RNApolis-0.4.6.dist-info → RNApolis-0.4.8.dist-info}/top_level.txt +0 -0
@@ -1,17 +1,17 @@
|
|
1
1
|
rnapolis/annotator.py,sha256=7U3f0gchKdIGc6FwJx0UAc_95HJI5SgECj-b7-1yBhc,22086
|
2
2
|
rnapolis/clashfinder.py,sha256=i95kp0o6OWNqmJDBr-PbsZd7RY2iJtBDr7QqolJSuAQ,8513
|
3
|
-
rnapolis/common.py,sha256=
|
3
|
+
rnapolis/common.py,sha256=7KSWZzqR7ntpaS6VRDYgpP2pC1dnBttOzYB06hQzWEI,30499
|
4
4
|
rnapolis/metareader.py,sha256=I1-cXc2YNBPwa3zihAnMTjEsAo79tEKzSmWu5yvN1Pk,2071
|
5
5
|
rnapolis/molecule_filter.py,sha256=hB6-nXgjmw7FAsQ3bj0cZ2FvuW2I1PXunEfcdwEUB1o,7389
|
6
6
|
rnapolis/motif_extractor.py,sha256=duHvpi9Ulcny9K60E6VBpz5RpJZw-KdTB4_Ph0iP478,774
|
7
7
|
rnapolis/parser.py,sha256=2pQYy0sh8TCpeluMmmSJ7C5dudK_bsfstTWCdpwwpNU,15193
|
8
8
|
rnapolis/rfam_folder.py,sha256=SjiiyML_T1__saruFwSMJEoQ7Y55GIU8ktS8ZUn5-fw,11111
|
9
|
-
rnapolis/tertiary.py,sha256=
|
9
|
+
rnapolis/tertiary.py,sha256=6t9ZB4w33-5n_M3sns1RoFXCOTgVAgGH4WDNG5OG9Kg,23426
|
10
10
|
rnapolis/transformer.py,sha256=V9nOQvdq4-p7yUWo0vQg0CDQMpmyxz9t4TMSRVEKHnw,1817
|
11
11
|
rnapolis/util.py,sha256=IdquFO3PV1_KDqodjupzm0Rqvgy0CeSzxGHaGEHYXVU,543
|
12
|
-
RNApolis-0.4.
|
13
|
-
RNApolis-0.4.
|
14
|
-
RNApolis-0.4.
|
15
|
-
RNApolis-0.4.
|
16
|
-
RNApolis-0.4.
|
17
|
-
RNApolis-0.4.
|
12
|
+
RNApolis-0.4.8.dist-info/LICENSE,sha256=ZGRu12MzCgbYA-Lt8MyBlmjvPZh7xfiD5u5wBx0enq4,1066
|
13
|
+
RNApolis-0.4.8.dist-info/METADATA,sha256=FZsizaaGYKRz7ndlAySWt8mPfpjjHUoP-OzXaO3LBv8,54322
|
14
|
+
RNApolis-0.4.8.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
15
|
+
RNApolis-0.4.8.dist-info/entry_points.txt,sha256=foN2Pn5e-OzEz0fFmNoX6PnFSZFQntOlY8LbognP5F0,308
|
16
|
+
RNApolis-0.4.8.dist-info/top_level.txt,sha256=LcO18koxZcWoJ21KDRRRo_tyIbmXL5z61dPitZpy8yc,9
|
17
|
+
RNApolis-0.4.8.dist-info/RECORD,,
|
rnapolis/common.py
CHANGED
@@ -338,6 +338,9 @@ class Entry(Sequence):
|
|
338
338
|
return self.pair
|
339
339
|
raise IndexError()
|
340
340
|
|
341
|
+
def __lt__(self, other):
|
342
|
+
return self.index_ < other.index_
|
343
|
+
|
341
344
|
def __len__(self) -> int:
|
342
345
|
return 3
|
343
346
|
|
@@ -701,12 +704,17 @@ class BpSeq:
|
|
701
704
|
|
702
705
|
@cached_property
|
703
706
|
def dot_bracket(self):
|
704
|
-
pulp.
|
705
|
-
|
707
|
+
if pulp.HiGHS_CMD().available():
|
708
|
+
solver = pulp.HiGHS_CMD() # much faster than default
|
709
|
+
else:
|
710
|
+
solver = pulp.LpSolverDefault
|
711
|
+
if solver is not None:
|
712
|
+
solver.msg = False
|
713
|
+
return self.convert_to_dot_bracket(solver)
|
706
714
|
|
707
715
|
def convert_to_dot_bracket(self, solver: pulp.LpSolver):
|
708
716
|
# if PuLP solvers are not installed, use FCFS
|
709
|
-
if
|
717
|
+
if solver is None:
|
710
718
|
return self.fcfs()
|
711
719
|
|
712
720
|
# build conflict graph
|
@@ -838,7 +846,7 @@ class BpSeq:
|
|
838
846
|
|
839
847
|
for i in range(1, len(regions)):
|
840
848
|
k, l, _ = regions[i]
|
841
|
-
available = [True for
|
849
|
+
available = [True for _ in range(len("([{<" + string.ascii_uppercase))]
|
842
850
|
|
843
851
|
for j in range(i):
|
844
852
|
m, n, _ = regions[j]
|
rnapolis/tertiary.py
CHANGED
@@ -124,36 +124,17 @@ class Residue3D(Residue):
|
|
124
124
|
outermost_atoms = {"A": "N9", "G": "N9", "C": "N1", "U": "N1", "T": "N1"}
|
125
125
|
# Dist representing expected name of atom closest to the tetrad center
|
126
126
|
innermost_atoms = {"A": "N6", "G": "O6", "C": "N4", "U": "O4", "T": "O4"}
|
127
|
+
# Heavy atoms in phosphate and ribose
|
128
|
+
phosphate_atoms = {"P", "OP1", "OP2", "O3'", "O5'"}
|
129
|
+
sugar_atoms = {"C1'", "C2'", "C3'", "C4'", "C5'", "O4'"}
|
127
130
|
# Heavy atoms for each main nucleobase
|
128
131
|
nucleobase_heavy_atoms = {
|
129
132
|
"A": set(["N1", "C2", "N3", "C4", "C5", "C6", "N6", "N7", "C8", "N9"]),
|
130
133
|
"G": set(["N1", "C2", "N2", "N3", "C4", "C5", "C6", "O6", "N7", "C8", "N9"]),
|
131
134
|
"C": set(["N1", "C2", "O2", "N3", "C4", "N4", "C5", "C6"]),
|
132
135
|
"U": set(["N1", "C2", "O2", "N3", "C4", "O4", "C5", "C6"]),
|
136
|
+
"T": set(["N1", "C2", "O2", "N3", "C4", "O4", "C5", "C5M", "C6"]),
|
133
137
|
}
|
134
|
-
# Heavy atoms in nucleotide
|
135
|
-
nucleotide_heavy_atoms = (
|
136
|
-
set(
|
137
|
-
[
|
138
|
-
"P",
|
139
|
-
"OP1",
|
140
|
-
"OP2",
|
141
|
-
"O5'",
|
142
|
-
"C5'",
|
143
|
-
"C4'",
|
144
|
-
"O4'",
|
145
|
-
"C3'",
|
146
|
-
"O3'",
|
147
|
-
"C2'",
|
148
|
-
"O2'",
|
149
|
-
"C1'",
|
150
|
-
]
|
151
|
-
)
|
152
|
-
.union(nucleobase_heavy_atoms["A"])
|
153
|
-
.union(nucleobase_heavy_atoms["G"])
|
154
|
-
.union(nucleobase_heavy_atoms["C"])
|
155
|
-
.union(nucleobase_heavy_atoms["U"])
|
156
|
-
)
|
157
138
|
|
158
139
|
def __lt__(self, other):
|
159
140
|
return (self.model, self.chain, self.number, self.icode or " ") < (
|
@@ -202,9 +183,59 @@ class Residue3D(Residue):
|
|
202
183
|
|
203
184
|
@cached_property
|
204
185
|
def is_nucleotide(self) -> bool:
|
205
|
-
|
206
|
-
|
186
|
+
scores = {"phosphate": 0.0, "sugar": 0.0, "base": 0.0, "connections": 0.0}
|
187
|
+
weights = {"phosphate": 0.25, "sugar": 0.25, "base": 0.25, "connections": 0.25}
|
188
|
+
|
189
|
+
residue_atoms = {atom.name for atom in self.atoms}
|
190
|
+
|
191
|
+
phosphate_match = len(residue_atoms.intersection(self.phosphate_atoms))
|
192
|
+
scores["phosphate"] = phosphate_match / len(self.phosphate_atoms)
|
193
|
+
|
194
|
+
sugar_match = len(residue_atoms.intersection(self.sugar_atoms))
|
195
|
+
scores["sugar"] = sugar_match / len(self.sugar_atoms)
|
196
|
+
|
197
|
+
nucleobase_atoms = {
|
198
|
+
key: self.nucleobase_heavy_atoms[key] for key in self.nucleobase_heavy_atoms
|
199
|
+
}
|
200
|
+
matches = {
|
201
|
+
key: len(residue_atoms.intersection(nucleobase_atoms[key]))
|
202
|
+
/ len(nucleobase_atoms[key])
|
203
|
+
for key in nucleobase_atoms
|
204
|
+
}
|
205
|
+
best_match = max(matches.items(), key=lambda x: x[1])
|
206
|
+
scores["base"] = best_match[1]
|
207
|
+
|
208
|
+
connection_score = 0.0
|
209
|
+
distance_threshold = 2.0
|
210
|
+
|
211
|
+
if "P" in residue_atoms and "O5'" in residue_atoms:
|
212
|
+
p_atom = next(atom for atom in self.atoms if atom.name == "P")
|
213
|
+
o5_atom = next(atom for atom in self.atoms if atom.name == "O5'")
|
214
|
+
if (
|
215
|
+
numpy.linalg.norm(p_atom.coordinates - o5_atom.coordinates)
|
216
|
+
<= distance_threshold
|
217
|
+
):
|
218
|
+
connection_score += 0.5
|
219
|
+
if "C1'" in residue_atoms:
|
220
|
+
c1_atom = next(atom for atom in self.atoms if atom.name == "C1'")
|
221
|
+
for base_connection in ["N9", "N1"]:
|
222
|
+
if base_connection in residue_atoms:
|
223
|
+
base_atom = next(
|
224
|
+
atom for atom in self.atoms if atom.name == base_connection
|
225
|
+
)
|
226
|
+
if (
|
227
|
+
numpy.linalg.norm(c1_atom.coordinates - base_atom.coordinates)
|
228
|
+
<= distance_threshold
|
229
|
+
):
|
230
|
+
connection_score += 0.5
|
231
|
+
break
|
232
|
+
|
233
|
+
scores["connections"] = connection_score
|
234
|
+
|
235
|
+
probability = sum(
|
236
|
+
scores[component] * weights[component] for component in scores.keys()
|
207
237
|
)
|
238
|
+
return probability > 0.5
|
208
239
|
|
209
240
|
@cached_property
|
210
241
|
def base_normal_vector(self) -> Optional[numpy.typing.NDArray[numpy.floating]]:
|
@@ -566,15 +597,14 @@ class Mapping2D3D:
|
|
566
597
|
return self.__generate_bpseq(canonical)
|
567
598
|
|
568
599
|
def __generate_bpseq(self, base_pairs):
|
600
|
+
nucleotides = list(filter(lambda r: r.is_nucleotide, self.structure3d.residues))
|
569
601
|
result: Dict[int, List] = {}
|
570
602
|
residue_map: Dict[Residue3D, int] = {}
|
571
603
|
i = 1
|
572
604
|
|
573
|
-
for j, residue in enumerate(
|
574
|
-
filter(lambda r: r.is_nucleotide, self.structure3d.residues)
|
575
|
-
):
|
605
|
+
for j, residue in enumerate(nucleotides):
|
576
606
|
if self.find_gaps and j > 0:
|
577
|
-
previous =
|
607
|
+
previous = nucleotides[j - 1]
|
578
608
|
|
579
609
|
if (
|
580
610
|
not previous.is_connected(residue)
|
File without changes
|
File without changes
|
File without changes
|