RNApolis 0.0.16__py3-none-any.whl → 0.1.1__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.0.16.dist-info → RNApolis-0.1.1.dist-info}/METADATA +1 -1
- RNApolis-0.1.1.dist-info/RECORD +15 -0
- rnapolis/annotator.py +26 -12
- rnapolis/common.py +54 -32
- rnapolis/motif_extractor.py +5 -1
- rnapolis/tertiary.py +4 -3
- RNApolis-0.0.16.dist-info/RECORD +0 -15
- {RNApolis-0.0.16.dist-info → RNApolis-0.1.1.dist-info}/LICENSE +0 -0
- {RNApolis-0.0.16.dist-info → RNApolis-0.1.1.dist-info}/WHEEL +0 -0
- {RNApolis-0.0.16.dist-info → RNApolis-0.1.1.dist-info}/entry_points.txt +0 -0
- {RNApolis-0.0.16.dist-info → RNApolis-0.1.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
rnapolis/annotator.py,sha256=CLdwuq0Y42unPd3W-NKIqy4JMCSanzUj6GmP9VnfRb4,20766
|
2
|
+
rnapolis/clashfinder.py,sha256=jD3s_UovygWi01NUbQNeAeRRFkARTSRraLXUV43UbAA,8514
|
3
|
+
rnapolis/common.py,sha256=o6I51SkBuHxiP9G91Uy42h8_JpCVc2Sd8lGLviCTKAc,24518
|
4
|
+
rnapolis/metareader.py,sha256=4qtMKRvww2sUStLeV8WVrLEt-ScydHUv4Gxx96tnf-M,1683
|
5
|
+
rnapolis/motif_extractor.py,sha256=5gUSNGeT_jBVzpj3gCaZJaRA4XPUpxJ9NteWns6UMAY,961
|
6
|
+
rnapolis/parser.py,sha256=Z3Zd_IuRyOP45x5BStgu7UgoyHthhw55fT3udHUhAE4,11905
|
7
|
+
rnapolis/tertiary.py,sha256=fA7ml3zlcWz0xsq4z73m-HGQh3KAkwzv7vVM5ivfgkg,18293
|
8
|
+
rnapolis/transformer.py,sha256=V9nOQvdq4-p7yUWo0vQg0CDQMpmyxz9t4TMSRVEKHnw,1817
|
9
|
+
rnapolis/util.py,sha256=IdquFO3PV1_KDqodjupzm0Rqvgy0CeSzxGHaGEHYXVU,543
|
10
|
+
RNApolis-0.1.1.dist-info/LICENSE,sha256=ZGRu12MzCgbYA-Lt8MyBlmjvPZh7xfiD5u5wBx0enq4,1066
|
11
|
+
RNApolis-0.1.1.dist-info/METADATA,sha256=0MspfjX3C2UlAe1c1eHVncrtXagp_DlMqA09ABKiS1E,1124
|
12
|
+
RNApolis-0.1.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
13
|
+
RNApolis-0.1.1.dist-info/entry_points.txt,sha256=113HwzaWSIoCvcPxkg_j2TIbnezP4_7akpTNr5n3Zjg,220
|
14
|
+
RNApolis-0.1.1.dist-info/top_level.txt,sha256=LcO18koxZcWoJ21KDRRRo_tyIbmXL5z61dPitZpy8yc,9
|
15
|
+
RNApolis-0.1.1.dist-info/RECORD,,
|
rnapolis/annotator.py
CHANGED
@@ -19,6 +19,7 @@ from rnapolis.common import (
|
|
19
19
|
BasePhosphate,
|
20
20
|
BaseRibose,
|
21
21
|
BPh,
|
22
|
+
BpSeq,
|
22
23
|
LeontisWesthof,
|
23
24
|
Residue,
|
24
25
|
Saenger,
|
@@ -471,11 +472,26 @@ def find_stackings(structure: Structure3D, model: int = 1) -> List[Stacking]:
|
|
471
472
|
|
472
473
|
|
473
474
|
def extract_secondary_structure(
|
474
|
-
tertiary_structure: Structure3D, model: int = 1
|
475
|
+
tertiary_structure: Structure3D, model: int = 1, find_gaps: bool = False
|
475
476
|
) -> Structure2D:
|
476
477
|
base_pairs, base_phosphate, base_ribose = find_pairs(tertiary_structure, model)
|
477
478
|
stackings = find_stackings(tertiary_structure, model)
|
478
|
-
|
479
|
+
mapping = Mapping2D3D(tertiary_structure, base_pairs, stackings, find_gaps)
|
480
|
+
stems, single_strands, hairpins, loops = mapping.bpseq.elements
|
481
|
+
return Structure2D(
|
482
|
+
base_pairs,
|
483
|
+
stackings,
|
484
|
+
base_ribose,
|
485
|
+
base_phosphate,
|
486
|
+
[],
|
487
|
+
str(mapping.bpseq),
|
488
|
+
mapping.dot_bracket,
|
489
|
+
mapping.extended_dot_bracket,
|
490
|
+
stems,
|
491
|
+
single_strands,
|
492
|
+
hairpins,
|
493
|
+
loops,
|
494
|
+
)
|
479
495
|
|
480
496
|
|
481
497
|
def write_json(path: str, structure2d: Structure2D):
|
@@ -541,9 +557,9 @@ def write_csv(path: str, structure2d: Structure2D):
|
|
541
557
|
)
|
542
558
|
|
543
559
|
|
544
|
-
def write_bpseq(path: str,
|
560
|
+
def write_bpseq(path: str, bpseq: BpSeq):
|
545
561
|
with open(path, "w") as f:
|
546
|
-
f.write(str(
|
562
|
+
f.write(str(bpseq))
|
547
563
|
|
548
564
|
|
549
565
|
def main():
|
@@ -563,14 +579,14 @@ def main():
|
|
563
579
|
parser.add_argument(
|
564
580
|
"--find-gaps",
|
565
581
|
action="store_true",
|
566
|
-
help=
|
567
|
-
"the gap is defined as O3'-P distance greater then {1.5 * AVERAGE_OXYGEN_PHOSPHORUS_DISTANCE_COVALENT}",
|
582
|
+
help="(optional) if set, the program will detect gaps and break the PDB chain into two or more strands; "
|
583
|
+
f"the gap is defined as O3'-P distance greater then {1.5 * AVERAGE_OXYGEN_PHOSPHORUS_DISTANCE_COVALENT}",
|
568
584
|
)
|
569
585
|
args = parser.parse_args()
|
570
586
|
|
571
587
|
file = handle_input_file(args.input)
|
572
588
|
structure3d = read_3d_structure(file, 1)
|
573
|
-
structure2d = extract_secondary_structure(structure3d)
|
589
|
+
structure2d = extract_secondary_structure(structure3d, 1, args.find_gaps)
|
574
590
|
|
575
591
|
if args.csv:
|
576
592
|
write_csv(args.csv, structure2d)
|
@@ -578,15 +594,13 @@ def main():
|
|
578
594
|
if args.json:
|
579
595
|
write_json(args.json, structure2d)
|
580
596
|
|
581
|
-
mapping = Mapping2D3D(structure3d, structure2d, args.find_gaps)
|
582
|
-
|
583
597
|
if args.bpseq:
|
584
|
-
write_bpseq(args.bpseq,
|
598
|
+
write_bpseq(args.bpseq, structure2d.bpseq)
|
585
599
|
|
586
600
|
if args.extended:
|
587
|
-
print(
|
601
|
+
print(structure2d.extendedDotBracket)
|
588
602
|
else:
|
589
|
-
print(
|
603
|
+
print(structure2d.dotBracket)
|
590
604
|
|
591
605
|
|
592
606
|
if __name__ == "__main__":
|
rnapolis/common.py
CHANGED
@@ -321,15 +321,6 @@ class OtherInteraction(Interaction):
|
|
321
321
|
pass
|
322
322
|
|
323
323
|
|
324
|
-
@dataclass(frozen=True, order=True)
|
325
|
-
class Structure2D:
|
326
|
-
basePairs: List[BasePair]
|
327
|
-
stackings: List[Stacking]
|
328
|
-
baseRiboseInteractions: List[BaseRibose]
|
329
|
-
basePhosphateInteractions: List[BasePhosphate]
|
330
|
-
otherInteractions: List[OtherInteraction]
|
331
|
-
|
332
|
-
|
333
324
|
@dataclass
|
334
325
|
class Entry(Sequence):
|
335
326
|
index_: int
|
@@ -380,12 +371,15 @@ class Strand:
|
|
380
371
|
return f"{self.first}-{self.sequence}-{self.last}"
|
381
372
|
|
382
373
|
|
383
|
-
@dataclass
|
374
|
+
@dataclass
|
384
375
|
class SingleStrand:
|
385
376
|
strand: Strand
|
386
377
|
is5p: bool
|
387
378
|
is3p: bool
|
388
379
|
|
380
|
+
def __post_init__(self):
|
381
|
+
self.description = str(self)
|
382
|
+
|
389
383
|
def __str__(self):
|
390
384
|
if self.is5p:
|
391
385
|
return f"SingleStrand5p {self.strand.first} {self.strand.last} {self.strand.sequence} {self.strand.structure}"
|
@@ -394,7 +388,7 @@ class SingleStrand:
|
|
394
388
|
return f"SingleStrand {self.strand.first} {self.strand.last} {self.strand.sequence} {self.strand.structure}"
|
395
389
|
|
396
390
|
|
397
|
-
@dataclass
|
391
|
+
@dataclass
|
398
392
|
class Stem:
|
399
393
|
strand5p: Strand
|
400
394
|
strand3p: Strand
|
@@ -410,22 +404,31 @@ class Stem:
|
|
410
404
|
Strand.from_bpseq_entries(strand3p_entries, dotbracket),
|
411
405
|
)
|
412
406
|
|
407
|
+
def __post_init__(self):
|
408
|
+
self.description = str(self)
|
409
|
+
|
413
410
|
def __str__(self):
|
414
411
|
return f"Stem {self.strand5p.first} {self.strand5p.last} {self.strand5p.sequence} {self.strand5p.structure} {self.strand3p.first} {self.strand3p.last} {self.strand3p.sequence} {self.strand3p.structure}"
|
415
412
|
|
416
413
|
|
417
|
-
@dataclass
|
414
|
+
@dataclass
|
418
415
|
class Hairpin:
|
419
416
|
strand: Strand
|
420
417
|
|
418
|
+
def __post_init__(self):
|
419
|
+
self.description = str(self)
|
420
|
+
|
421
421
|
def __str__(self):
|
422
422
|
return f"Hairpin {self.strand.first} {self.strand.last} {self.strand.sequence} {self.strand.structure}"
|
423
423
|
|
424
424
|
|
425
|
-
@dataclass
|
425
|
+
@dataclass
|
426
426
|
class Loop:
|
427
427
|
strands: List[Strand]
|
428
428
|
|
429
|
+
def __post_init__(self):
|
430
|
+
self.description = str(self)
|
431
|
+
|
429
432
|
def __str__(self):
|
430
433
|
desc = " ".join(
|
431
434
|
[
|
@@ -516,30 +519,32 @@ class BpSeq:
|
|
516
519
|
return stems
|
517
520
|
|
518
521
|
@cached_property
|
519
|
-
def elements(
|
522
|
+
def elements(
|
523
|
+
self,
|
524
|
+
) -> Tuple[List[Stem], List[SingleStrand], List[Hairpin], List[Loop]]:
|
520
525
|
if not self.__stems_entries:
|
521
|
-
return []
|
526
|
+
return [], [], [], []
|
522
527
|
|
523
|
-
|
524
|
-
|
528
|
+
stems, single_strands, hairpins, loops = [], [], [], []
|
529
|
+
stopset = set()
|
525
530
|
|
526
531
|
# stems
|
527
532
|
for stem_entries in self.__stems_entries:
|
528
533
|
stem = Stem.from_bpseq_entries(
|
529
534
|
stem_entries, self.entries, self.to_dot_bracket.structure
|
530
535
|
)
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
+
stems.append(stem)
|
537
|
+
stopset.add(stem.strand5p.first - 1)
|
538
|
+
stopset.add(stem.strand5p.last - 1)
|
539
|
+
stopset.add(stem.strand3p.first - 1)
|
540
|
+
stopset.add(stem.strand3p.last - 1)
|
536
541
|
|
537
|
-
stops = sorted(
|
542
|
+
stops = sorted(stopset)
|
538
543
|
loop_candidates = []
|
539
544
|
|
540
545
|
# 5' single strand
|
541
546
|
if stops[0] > 0:
|
542
|
-
|
547
|
+
single_strands.append(
|
543
548
|
SingleStrand(
|
544
549
|
Strand.from_bpseq_entries(
|
545
550
|
self.entries[: stops[0] + 1],
|
@@ -555,7 +560,7 @@ class BpSeq:
|
|
555
560
|
candidate = self.entries[stops[i - 1] : stops[i] + 1]
|
556
561
|
if all([entry.pair == 0 for entry in candidate[1:-1]]):
|
557
562
|
if candidate[0].pair == candidate[-1].index_:
|
558
|
-
|
563
|
+
hairpins.append(
|
559
564
|
Hairpin(
|
560
565
|
Strand.from_bpseq_entries(
|
561
566
|
candidate, self.to_dot_bracket.structure
|
@@ -571,7 +576,7 @@ class BpSeq:
|
|
571
576
|
|
572
577
|
# 3' single strand
|
573
578
|
if stops[-1] < len(self.entries) - 1:
|
574
|
-
|
579
|
+
single_strands.append(
|
575
580
|
SingleStrand(
|
576
581
|
Strand.from_bpseq_entries(
|
577
582
|
self.entries[stops[-1] :], self.to_dot_bracket.structure
|
@@ -613,13 +618,13 @@ class BpSeq:
|
|
613
618
|
|
614
619
|
if self.entries[loop[0].first - 1].pair == loop[-1].last:
|
615
620
|
if not all([strand.last - strand.first <= 1 for strand in loop]):
|
616
|
-
|
621
|
+
loops.append(Loop(loop))
|
617
622
|
|
618
623
|
for i in range(len(loop_candidates)):
|
619
624
|
if i not in used:
|
620
|
-
|
625
|
+
single_strands.append(SingleStrand(loop_candidates[i], False, False))
|
621
626
|
|
622
|
-
return
|
627
|
+
return stems, single_strands, hairpins, loops
|
623
628
|
|
624
629
|
@cached_property
|
625
630
|
def __regions(self) -> List[Tuple[int, int, int]]:
|
@@ -675,14 +680,14 @@ class BpSeq:
|
|
675
680
|
vars_by_region[i].append(variable)
|
676
681
|
vars_by_order[j].append(variable)
|
677
682
|
var_by_region_order[(i, j)] = variable
|
678
|
-
region_by_var[variable] = i
|
683
|
+
region_by_var[variable] = regions[i]
|
679
684
|
|
680
685
|
# define objective function terms
|
681
686
|
terms = []
|
682
687
|
|
683
688
|
for order, vars in vars_by_order.items():
|
684
689
|
for var in vars:
|
685
|
-
length =
|
690
|
+
length = region_by_var[var][2]
|
686
691
|
if order == 0:
|
687
692
|
terms.append(var * length)
|
688
693
|
else:
|
@@ -707,6 +712,7 @@ class BpSeq:
|
|
707
712
|
|
708
713
|
# solve the problem
|
709
714
|
try:
|
715
|
+
logging.debug(f"POA: problem formulation\n{problem}")
|
710
716
|
problem.solve(solver)
|
711
717
|
except pulp.PulpSolverError:
|
712
718
|
logging.warning(
|
@@ -720,7 +726,7 @@ class BpSeq:
|
|
720
726
|
return self.fcfs()
|
721
727
|
|
722
728
|
# log solver time statistics
|
723
|
-
logging.
|
729
|
+
logging.debug(
|
724
730
|
f"POA: solver {solver.name} took {round(problem.solutionTime, 2)} seconds"
|
725
731
|
)
|
726
732
|
|
@@ -833,3 +839,19 @@ class DotBracket:
|
|
833
839
|
|
834
840
|
def __str__(self):
|
835
841
|
return f"{self.sequence}\n{self.structure}"
|
842
|
+
|
843
|
+
|
844
|
+
@dataclass(frozen=True, order=True)
|
845
|
+
class Structure2D:
|
846
|
+
basePairs: List[BasePair]
|
847
|
+
stackings: List[Stacking]
|
848
|
+
baseRiboseInteractions: List[BaseRibose]
|
849
|
+
basePhosphateInteractions: List[BasePhosphate]
|
850
|
+
otherInteractions: List[OtherInteraction]
|
851
|
+
bpseq: str
|
852
|
+
dotBracket: str
|
853
|
+
extendedDotBracket: str
|
854
|
+
stems: List[Stem]
|
855
|
+
singleStrands: List[SingleStrand]
|
856
|
+
hairpins: List[Hairpin]
|
857
|
+
loops: List[Loop]
|
rnapolis/motif_extractor.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#! /usr/bin/env python
|
2
2
|
import argparse
|
3
|
+
import itertools
|
3
4
|
from typing import IO, Dict, List
|
4
5
|
|
5
6
|
import orjson
|
@@ -24,7 +25,10 @@ def main():
|
|
24
25
|
parser.print_help()
|
25
26
|
return
|
26
27
|
|
27
|
-
|
28
|
+
print(f"Full dot-bracket:\n{bpseq.to_dot_bracket}")
|
29
|
+
stems, single_strands, hairpins, loops = bpseq.elements
|
30
|
+
|
31
|
+
for element in itertools.chain(stems, single_strands, hairpins, loops):
|
28
32
|
print(element)
|
29
33
|
|
30
34
|
|
rnapolis/tertiary.py
CHANGED
@@ -388,14 +388,15 @@ class Structure3D:
|
|
388
388
|
@dataclass
|
389
389
|
class Mapping2D3D:
|
390
390
|
structure3d: Structure3D
|
391
|
-
|
391
|
+
base_pairs2d: List[BasePair]
|
392
|
+
stackings2d: List[Stacking]
|
392
393
|
find_gaps: bool
|
393
394
|
|
394
395
|
@cached_property
|
395
396
|
def base_pairs(self) -> List[BasePair3D]:
|
396
397
|
result = []
|
397
398
|
used = set()
|
398
|
-
for base_pair in self.
|
399
|
+
for base_pair in self.base_pairs2d:
|
399
400
|
nt1 = self.structure3d.find_residue(base_pair.nt1.label, base_pair.nt1.auth)
|
400
401
|
nt2 = self.structure3d.find_residue(base_pair.nt2.label, base_pair.nt2.auth)
|
401
402
|
if nt1 is not None and nt2 is not None:
|
@@ -439,7 +440,7 @@ class Mapping2D3D:
|
|
439
440
|
def stackings(self) -> List[Stacking3D]:
|
440
441
|
result = []
|
441
442
|
used = set()
|
442
|
-
for stacking in self.
|
443
|
+
for stacking in self.stackings2d:
|
443
444
|
nt1 = self.structure3d.find_residue(stacking.nt1.label, stacking.nt1.auth)
|
444
445
|
nt2 = self.structure3d.find_residue(stacking.nt2.label, stacking.nt2.auth)
|
445
446
|
if nt1 is not None and nt2 is not None:
|
RNApolis-0.0.16.dist-info/RECORD
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
rnapolis/annotator.py,sha256=aaPb1gMbzVv8Jx1iSJ12nW9R-aWE-lq95gZks9RZDfk,20419
|
2
|
-
rnapolis/clashfinder.py,sha256=jD3s_UovygWi01NUbQNeAeRRFkARTSRraLXUV43UbAA,8514
|
3
|
-
rnapolis/common.py,sha256=_ylHz3KdB75cugX_7wTzqbPQChAUKlnuThsvMLuxsfM,23859
|
4
|
-
rnapolis/metareader.py,sha256=4qtMKRvww2sUStLeV8WVrLEt-ScydHUv4Gxx96tnf-M,1683
|
5
|
-
rnapolis/motif_extractor.py,sha256=nz3aenyhPBZNuWzdHOCpFG95SLqf5yLhQQi1Bx-i2H8,786
|
6
|
-
rnapolis/parser.py,sha256=Z3Zd_IuRyOP45x5BStgu7UgoyHthhw55fT3udHUhAE4,11905
|
7
|
-
rnapolis/tertiary.py,sha256=DcY4OPRg9d05L9Fr9G_1KTbMwkNVTyEPnLkJOPODlAM,18276
|
8
|
-
rnapolis/transformer.py,sha256=V9nOQvdq4-p7yUWo0vQg0CDQMpmyxz9t4TMSRVEKHnw,1817
|
9
|
-
rnapolis/util.py,sha256=IdquFO3PV1_KDqodjupzm0Rqvgy0CeSzxGHaGEHYXVU,543
|
10
|
-
RNApolis-0.0.16.dist-info/LICENSE,sha256=ZGRu12MzCgbYA-Lt8MyBlmjvPZh7xfiD5u5wBx0enq4,1066
|
11
|
-
RNApolis-0.0.16.dist-info/METADATA,sha256=ODBaX0GLTPv7WaCiFdJErR9dCdeOV50N7sjkf1U1sFs,1125
|
12
|
-
RNApolis-0.0.16.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
13
|
-
RNApolis-0.0.16.dist-info/entry_points.txt,sha256=113HwzaWSIoCvcPxkg_j2TIbnezP4_7akpTNr5n3Zjg,220
|
14
|
-
RNApolis-0.0.16.dist-info/top_level.txt,sha256=LcO18koxZcWoJ21KDRRRo_tyIbmXL5z61dPitZpy8yc,9
|
15
|
-
RNApolis-0.0.16.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|