RNApolis 0.4.2__py3-none-any.whl → 0.4.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: RNApolis
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: A Python library containing RNA-related bioinformatics functions and classes
5
5
  Home-page: https://github.com/tzok/rnapolis-py
6
6
  Author: Tomasz Zok
@@ -6,12 +6,12 @@ rnapolis/molecule_filter.py,sha256=hB6-nXgjmw7FAsQ3bj0cZ2FvuW2I1PXunEfcdwEUB1o,7
6
6
  rnapolis/motif_extractor.py,sha256=duHvpi9Ulcny9K60E6VBpz5RpJZw-KdTB4_Ph0iP478,774
7
7
  rnapolis/parser.py,sha256=wCA9rXqt51iLECgeBqOShFpuT8JwanNkHYD5uXYvLzU,13988
8
8
  rnapolis/rfam_folder.py,sha256=SjiiyML_T1__saruFwSMJEoQ7Y55GIU8ktS8ZUn5-fw,11111
9
- rnapolis/tertiary.py,sha256=ya7A2HyhPZSbA4rC8E43-mRIhR73-AeBuLE2GRpOTxk,20347
9
+ rnapolis/tertiary.py,sha256=SQyiYWA0RJhAK70f88CKZvS4EzGKHQ2RoL1s4MueEDQ,21657
10
10
  rnapolis/transformer.py,sha256=V9nOQvdq4-p7yUWo0vQg0CDQMpmyxz9t4TMSRVEKHnw,1817
11
11
  rnapolis/util.py,sha256=IdquFO3PV1_KDqodjupzm0Rqvgy0CeSzxGHaGEHYXVU,543
12
- RNApolis-0.4.2.dist-info/LICENSE,sha256=ZGRu12MzCgbYA-Lt8MyBlmjvPZh7xfiD5u5wBx0enq4,1066
13
- RNApolis-0.4.2.dist-info/METADATA,sha256=1rZv7syiOsppxC9PAy0kYmgBXABKCX4gWZaqdtpbvis,54322
14
- RNApolis-0.4.2.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
15
- RNApolis-0.4.2.dist-info/entry_points.txt,sha256=foN2Pn5e-OzEz0fFmNoX6PnFSZFQntOlY8LbognP5F0,308
16
- RNApolis-0.4.2.dist-info/top_level.txt,sha256=LcO18koxZcWoJ21KDRRRo_tyIbmXL5z61dPitZpy8yc,9
17
- RNApolis-0.4.2.dist-info/RECORD,,
12
+ RNApolis-0.4.4.dist-info/LICENSE,sha256=ZGRu12MzCgbYA-Lt8MyBlmjvPZh7xfiD5u5wBx0enq4,1066
13
+ RNApolis-0.4.4.dist-info/METADATA,sha256=irtWJbeg1LWun2r3WtnsnDDSHlLvru0hO9wz1e67cIE,54322
14
+ RNApolis-0.4.4.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
15
+ RNApolis-0.4.4.dist-info/entry_points.txt,sha256=foN2Pn5e-OzEz0fFmNoX6PnFSZFQntOlY8LbognP5F0,308
16
+ RNApolis-0.4.4.dist-info/top_level.txt,sha256=LcO18koxZcWoJ21KDRRRo_tyIbmXL5z61dPitZpy8yc,9
17
+ RNApolis-0.4.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.2.0)
2
+ Generator: setuptools (74.1.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
rnapolis/tertiary.py CHANGED
@@ -7,6 +7,7 @@ from typing import Dict, List, Optional, Set, Tuple, Union
7
7
 
8
8
  import numpy
9
9
  import numpy.typing
10
+
10
11
  from rnapolis.common import (
11
12
  BasePair,
12
13
  BpSeq,
@@ -16,6 +17,7 @@ from rnapolis.common import (
16
17
  Residue,
17
18
  ResidueAuth,
18
19
  ResidueLabel,
20
+ Saenger,
19
21
  Stacking,
20
22
  )
21
23
 
@@ -497,34 +499,71 @@ class Mapping2D3D:
497
499
 
498
500
  @cached_property
499
501
  def strands_sequences(self) -> List[Tuple[str, str]]:
500
- result = defaultdict(list)
502
+ nucleotides = list(filter(lambda r: r.is_nucleotide, self.structure3d.residues))
501
503
 
502
- for i, residue in enumerate(
503
- filter(lambda r: r.is_nucleotide, self.structure3d.residues)
504
- ):
505
- if i > 0 and self.find_gaps:
506
- previous = self.structure3d.residues[i - 1]
504
+ if not nucleotides:
505
+ return []
507
506
 
508
- if (
509
- not previous.is_connected(residue)
510
- and previous.chain == residue.chain
511
- ):
512
- for k in range(residue.number - previous.number - 1):
513
- result[residue.chain].append("?")
507
+ result = [(nucleotides[0].chain, [nucleotides[0].one_letter_name])]
514
508
 
515
- result[residue.chain].append(residue.one_letter_name)
509
+ for i in range(1, len(nucleotides)):
510
+ previous = nucleotides[i - 1]
511
+ residue = nucleotides[i]
516
512
 
517
- return [(chain, "".join(sequence)) for chain, sequence in result.items()]
513
+ if residue.chain != previous.chain:
514
+ result.append((residue.chain, [residue.one_letter_name]))
515
+ else:
516
+ if self.find_gaps:
517
+ if not previous.is_connected(residue):
518
+ for k in range(residue.number - previous.number - 1):
519
+ result[-1][1].append("?")
520
+ result[-1][1].append(residue.one_letter_name)
521
+
522
+ return [(chain, "".join(sequence)) for chain, sequence in result]
518
523
 
519
524
  @cached_property
520
525
  def bpseq(self) -> BpSeq:
521
- return self.__generate_bpseq(
522
- [
523
- base_pair
524
- for base_pair in self.base_pairs
525
- if base_pair.is_canonical and base_pair.nt1 < base_pair.nt2
526
- ]
527
- )
526
+ def pair_scoring_function(pair: BasePair3D) -> int:
527
+ if pair.saenger is not None:
528
+ if pair.saenger in (Saenger.XIX, Saenger.XX):
529
+ return 0, pair.nt1, pair.nt2
530
+ else:
531
+ return 1, pair.nt1, pair.nt2
532
+
533
+ sequence = "".join(
534
+ sorted(
535
+ [
536
+ pair.nt1_3d.one_letter_name.upper(),
537
+ pair.nt2_3d.one_letter_name.upper(),
538
+ ]
539
+ )
540
+ )
541
+ if sequence in ("AU", "AT", "CG"):
542
+ return 0, pair.nt1, pair.nt2
543
+ return 1, pair.nt1, pair.nt2
544
+
545
+ canonical = [
546
+ base_pair
547
+ for base_pair in self.base_pairs
548
+ if base_pair.is_canonical and base_pair.nt1 < base_pair.nt2
549
+ ]
550
+
551
+ while True:
552
+ matches = defaultdict(set)
553
+
554
+ for base_pair in canonical:
555
+ matches[base_pair.nt1_3d].add(base_pair)
556
+ matches[base_pair.nt2_3d].add(base_pair)
557
+
558
+ for pairs in matches.values():
559
+ if len(pairs) > 1:
560
+ pairs = sorted(pairs, key=pair_scoring_function)
561
+ canonical.remove(pairs[-1])
562
+ break
563
+ else:
564
+ break
565
+
566
+ return self.__generate_bpseq(canonical)
528
567
 
529
568
  def __generate_bpseq(self, base_pairs):
530
569
  result: Dict[int, List] = {}