RNApolis 0.3.17__py3-none-any.whl → 0.4.0__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.3.17
3
+ Version: 0.4.0
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
@@ -21,6 +21,7 @@ Requires-Dist: mmcif
21
21
  Requires-Dist: numpy
22
22
  Requires-Dist: ordered-set
23
23
  Requires-Dist: orjson
24
+ Requires-Dist: pandas
24
25
  Requires-Dist: pulp
25
26
  Requires-Dist: requests
26
27
  Requires-Dist: scipy
@@ -0,0 +1,17 @@
1
+ rnapolis/annotator.py,sha256=7U3f0gchKdIGc6FwJx0UAc_95HJI5SgECj-b7-1yBhc,22086
2
+ rnapolis/clashfinder.py,sha256=i95kp0o6OWNqmJDBr-PbsZd7RY2iJtBDr7QqolJSuAQ,8513
3
+ rnapolis/common.py,sha256=PUYF01P2vevhyImhZjGYE0jJlsxWHX6GQmsxI4W7S-E,30255
4
+ rnapolis/metareader.py,sha256=I1-cXc2YNBPwa3zihAnMTjEsAo79tEKzSmWu5yvN1Pk,2071
5
+ rnapolis/molecule_filter.py,sha256=hB6-nXgjmw7FAsQ3bj0cZ2FvuW2I1PXunEfcdwEUB1o,7389
6
+ rnapolis/motif_extractor.py,sha256=duHvpi9Ulcny9K60E6VBpz5RpJZw-KdTB4_Ph0iP478,774
7
+ rnapolis/parser.py,sha256=wCA9rXqt51iLECgeBqOShFpuT8JwanNkHYD5uXYvLzU,13988
8
+ rnapolis/rfam_folder.py,sha256=SjiiyML_T1__saruFwSMJEoQ7Y55GIU8ktS8ZUn5-fw,11111
9
+ rnapolis/tertiary.py,sha256=iA5_ut1_nhwlbYpu2898h5li4pTEOc-iA_uK7vIvQ2o,20269
10
+ rnapolis/transformer.py,sha256=V9nOQvdq4-p7yUWo0vQg0CDQMpmyxz9t4TMSRVEKHnw,1817
11
+ rnapolis/util.py,sha256=IdquFO3PV1_KDqodjupzm0Rqvgy0CeSzxGHaGEHYXVU,543
12
+ RNApolis-0.4.0.dist-info/LICENSE,sha256=ZGRu12MzCgbYA-Lt8MyBlmjvPZh7xfiD5u5wBx0enq4,1066
13
+ RNApolis-0.4.0.dist-info/METADATA,sha256=kz7fPjyFm8j6HMwnDvtwlLkZGPpzw2Ce29XI1pVyIyU,54322
14
+ RNApolis-0.4.0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
15
+ RNApolis-0.4.0.dist-info/entry_points.txt,sha256=foN2Pn5e-OzEz0fFmNoX6PnFSZFQntOlY8LbognP5F0,308
16
+ RNApolis-0.4.0.dist-info/top_level.txt,sha256=LcO18koxZcWoJ21KDRRRo_tyIbmXL5z61dPitZpy8yc,9
17
+ RNApolis-0.4.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.1.1)
2
+ Generator: setuptools (72.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
rnapolis/annotator.py CHANGED
@@ -10,8 +10,6 @@ from typing import Dict, List, Optional, Set, Tuple
10
10
  import numpy
11
11
  import numpy.typing
12
12
  from ordered_set import OrderedSet
13
- from scipy.spatial import KDTree
14
-
15
13
  from rnapolis.common import (
16
14
  BR,
17
15
  BaseInteractions,
@@ -43,6 +41,7 @@ from rnapolis.tertiary import (
43
41
  torsion_angle,
44
42
  )
45
43
  from rnapolis.util import handle_input_file
44
+ from scipy.spatial import KDTree
46
45
 
47
46
  HYDROGEN_BOND_MAX_DISTANCE = 4.0
48
47
  HYDROGEN_BOND_ANGLE_RANGE = (50.0, 130.0) # 90 degrees is ideal, so allow +- 40 degrees
@@ -149,7 +148,7 @@ def detect_bph_br_classification(
149
148
 
150
149
 
151
150
  def merge_and_clean_bph_br(
152
- pairs: List[Tuple[Residue3D, Residue3D, int]]
151
+ pairs: List[Tuple[Residue3D, Residue3D, int]],
153
152
  ) -> Dict[Tuple[Residue3D, Residue3D], OrderedSet[int]]:
154
153
  bph_br_map: Dict[Tuple[Residue3D, Residue3D], OrderedSet[int]] = defaultdict(
155
154
  OrderedSet
@@ -588,7 +587,7 @@ def main():
588
587
  "-a",
589
588
  "--all-dot-brackets",
590
589
  action="store_true",
591
- help=")optional) print all dot-brackets, not only optimal one (exclusive with -e/--extended)",
590
+ help="(optional) print all dot-brackets, not only optimal one (exclusive with -e/--extended)",
592
591
  )
593
592
  parser.add_argument("-b", "--bpseq", help="(optional) path to output BPSEQ file")
594
593
  parser.add_argument("-c", "--csv", help="(optional) path to output CSV file")
rnapolis/clashfinder.py CHANGED
@@ -8,11 +8,10 @@ from functools import cached_property
8
8
  from typing import List, Optional
9
9
 
10
10
  import numpy as np
11
- from scipy.spatial import KDTree
12
-
13
11
  from rnapolis.metareader import read_metadata
14
12
  from rnapolis.parser import read_3d_structure
15
13
  from rnapolis.tertiary import Atom, Residue3D
14
+ from scipy.spatial import KDTree
16
15
 
17
16
  CARBON_RADIUS = 0.6
18
17
  NITROGEN_RADIUS = 0.54
rnapolis/common.py CHANGED
@@ -8,7 +8,6 @@ from collections.abc import Sequence
8
8
  from dataclasses import dataclass
9
9
  from enum import Enum
10
10
  from functools import cache, cached_property, total_ordering
11
- from itertools import permutations
12
11
  from typing import Dict, List, Optional, Tuple
13
12
 
14
13
  import graphviz
rnapolis/metareader.py CHANGED
@@ -6,7 +6,6 @@ import orjson
6
6
  import pandas as pd
7
7
  from mmcif.io.IoAdapterPy import IoAdapterPy
8
8
  from mmcif.io.PdbxReader import DataContainer
9
-
10
9
  from rnapolis.util import handle_input_file
11
10
 
12
11
 
@@ -5,7 +5,6 @@ from typing import List, Set, Tuple
5
5
 
6
6
  from mmcif.io.IoAdapterPy import IoAdapterPy
7
7
  from mmcif.io.PdbxReader import DataCategory, DataContainer
8
-
9
8
  from rnapolis.util import handle_input_file
10
9
 
11
10
  # Source: https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_entity_poly.type.html
@@ -158,11 +157,17 @@ def main():
158
157
  parser = argparse.ArgumentParser()
159
158
  parser.add_argument(
160
159
  "--type",
161
- help="a type of molecule to select (default: polyribonucleotide)",
160
+ help="a type of molecule to select, you can provide this argument multiple times (default: polyribonucleotide)",
162
161
  action="append",
163
162
  default=["polyribonucleotide"],
164
163
  choices=ENTITY_POLY_TYPES,
165
164
  )
165
+ parser.add_argument(
166
+ "--chain",
167
+ help="a chain ID (label_asym_id) to select, you can provide this argument multiple times (if provided, it overrides the --type argument)",
168
+ action="append",
169
+ default=[],
170
+ )
166
171
  parser.add_argument("path", help="path to a PDBx/mmCIF file")
167
172
  args = parser.parse_args()
168
173
 
@@ -171,8 +176,15 @@ def main():
171
176
  data = adapter.readFile(file.name)
172
177
  output = DataContainer("rnapolis")
173
178
 
174
- entity_ids = select_ids(data, "entity_poly", "type", "entity_id", set(args.type))
175
- asym_ids = select_ids(data, "struct_asym", "entity_id", "id", entity_ids)
179
+ if args.chain:
180
+ entity_ids = select_ids(data, "struct_asym", "id", "entity_id", set(args.chain))
181
+ asym_ids = set(args.chain)
182
+ else:
183
+ entity_ids = select_ids(
184
+ data, "entity_poly", "type", "entity_id", set(args.type)
185
+ )
186
+ asym_ids = select_ids(data, "struct_asym", "entity_id", "id", entity_ids)
187
+
176
188
  auth_asym_ids = select_ids(
177
189
  data, "atom_site", "label_asym_id", "auth_asym_id", asym_ids
178
190
  )
rnapolis/parser.py CHANGED
@@ -2,7 +2,6 @@ import logging
2
2
  from typing import IO, Dict, List, Optional, Tuple, Union
3
3
 
4
4
  from mmcif.io.IoAdapterPy import IoAdapterPy
5
-
6
5
  from rnapolis.common import ResidueAuth, ResidueLabel
7
6
  from rnapolis.tertiary import BASE_ATOMS, Atom, Residue3D, Structure3D
8
7
 
@@ -13,7 +12,7 @@ logger = logging.getLogger(__name__)
13
12
  def read_3d_structure(
14
13
  cif_or_pdb: IO[str], model: Optional[int] = None, nucleic_acid_only: bool = False
15
14
  ) -> Structure3D:
16
- atoms, modified, sequence = (
15
+ atoms, modified, sequence_by_entity, is_nucleic_acid_by_entity = (
17
16
  parse_cif(cif_or_pdb) if is_cif(cif_or_pdb) else parse_pdb(cif_or_pdb)
18
17
  )
19
18
  available_models = {atom.model: None for atom in atoms}
@@ -25,7 +24,13 @@ def read_3d_structure(
25
24
  atoms = atoms_by_model[model]
26
25
  else:
27
26
  atoms = atoms_by_model[list(available_models.keys())[0]]
28
- return group_atoms(atoms, modified, sequence, nucleic_acid_only)
27
+ return group_atoms(
28
+ atoms,
29
+ modified,
30
+ sequence_by_entity,
31
+ is_nucleic_acid_by_entity,
32
+ nucleic_acid_only,
33
+ )
29
34
 
30
35
 
31
36
  def is_cif(cif_or_pdb: IO[str]) -> bool:
@@ -41,7 +46,8 @@ def parse_cif(
41
46
  ) -> Tuple[
42
47
  List[Atom],
43
48
  Dict[Union[ResidueLabel, ResidueAuth], str],
44
- Dict[Tuple[str, int], str],
49
+ Dict[str, str],
50
+ Dict[str, bool],
45
51
  ]:
46
52
  cif.seek(0)
47
53
 
@@ -49,7 +55,8 @@ def parse_cif(
49
55
  data = io_adapter.readFile(cif.name)
50
56
  atoms: List[Atom] = []
51
57
  modified: Dict[Union[ResidueLabel, ResidueAuth], str] = {}
52
- sequence = {}
58
+ sequence_by_entity = {}
59
+ is_nucleic_acid_by_entity = {}
53
60
 
54
61
  if data:
55
62
  atom_site = data[0].getObj("atom_site")
@@ -60,6 +67,7 @@ def parse_cif(
60
67
  for row in atom_site.getRowList():
61
68
  row_dict = dict(zip(atom_site.getAttributeList(), row))
62
69
 
70
+ label_entity_id = row_dict.get("label_entity_id", None)
63
71
  label_chain_name = row_dict.get("label_asym_id", None)
64
72
  label_residue_number = try_parse_int(row_dict.get("label_seq_id", None))
65
73
  label_residue_name = row_dict.get("label_comp_id", None)
@@ -128,7 +136,19 @@ def parse_cif(
128
136
  else None
129
137
  )
130
138
 
131
- atoms.append(Atom(label, auth, model, atom_name, x, y, z, occupancy))
139
+ atoms.append(
140
+ Atom(
141
+ label_entity_id,
142
+ label,
143
+ auth,
144
+ model,
145
+ atom_name,
146
+ x,
147
+ y,
148
+ z,
149
+ occupancy,
150
+ )
151
+ )
132
152
 
133
153
  if mod_residue:
134
154
  for row in mod_residue.getRowList():
@@ -179,17 +199,24 @@ def parse_cif(
179
199
  for row in entity_poly.getRowList():
180
200
  row_dict = dict(zip(entity_poly.getAttributeList(), row))
181
201
 
182
- pdbx_strand_id = row_dict.get("pdbx_strand_id", None)
202
+ entity_id = row_dict.get("entity_id", None)
203
+ type_ = row_dict.get("type", None)
183
204
  pdbx_seq_one_letter_code_can = row_dict.get(
184
205
  "pdbx_seq_one_letter_code_can", None
185
206
  )
186
207
 
187
- if pdbx_strand_id and pdbx_seq_one_letter_code_can:
188
- for strand in pdbx_strand_id.split(","):
189
- for i, letter in enumerate(pdbx_seq_one_letter_code_can):
190
- sequence[(strand, i + 1)] = letter
208
+ if entity_id and type_:
209
+ is_nucleic_acid_by_entity[entity_id] = type_ in (
210
+ "peptide nucleic acid",
211
+ "polydeoxyribonucleotide",
212
+ "polydeoxyribonucleotide/polyribonucleotide hybrid",
213
+ "polyribonucleotide",
214
+ )
215
+
216
+ if entity_id and pdbx_seq_one_letter_code_can:
217
+ sequence_by_entity[entity_id] = pdbx_seq_one_letter_code_can
191
218
 
192
- return atoms, modified, sequence
219
+ return atoms, modified, sequence_by_entity, is_nucleic_acid_by_entity
193
220
 
194
221
 
195
222
  def parse_pdb(
@@ -197,7 +224,8 @@ def parse_pdb(
197
224
  ) -> Tuple[
198
225
  List[Atom],
199
226
  Dict[Union[ResidueLabel, ResidueAuth], str],
200
- Dict[Tuple[str, int], str],
227
+ Dict[str, str],
228
+ Dict[str, bool],
201
229
  ]:
202
230
  pdb.seek(0)
203
231
  atoms: List[Atom] = []
@@ -223,7 +251,7 @@ def parse_pdb(
223
251
  auth = ResidueAuth(
224
252
  chain_identifier, residue_number, insertion_code, residue_name
225
253
  )
226
- atoms.append(Atom(None, auth, model, atom_name, x, y, z, occupancy))
254
+ atoms.append(Atom(None, None, auth, model, atom_name, x, y, z, occupancy))
227
255
  elif line.startswith("MODRES"):
228
256
  original_name = line[12:15]
229
257
  chain_identifier = line[16]
@@ -235,13 +263,14 @@ def parse_pdb(
235
263
  )
236
264
  modified[auth] = standard_residue_name
237
265
 
238
- return atoms, modified, {}
266
+ return atoms, modified, {}, {}
239
267
 
240
268
 
241
269
  def group_atoms(
242
270
  atoms: List[Atom],
243
271
  modified: Dict[Union[ResidueLabel, ResidueAuth], str],
244
- sequence: Dict[Tuple[str, int], str],
272
+ sequence_by_entity: Dict[str, str],
273
+ is_nucleic_acid_by_entity: Dict[str, bool],
245
274
  nucleic_acid_only: bool,
246
275
  ) -> Structure3D:
247
276
  if not atoms:
@@ -259,28 +288,45 @@ def group_atoms(
259
288
  label = key_previous[0]
260
289
  auth = key_previous[1]
261
290
  model = key_previous[2]
291
+ entity_id = residue_atoms[-1].entity_id
262
292
  name = get_residue_name(auth, label, modified)
263
- one_letter_name = get_one_letter_name(label, sequence, name)
264
- if one_letter_name not in "ACGUT":
293
+ one_letter_name = get_one_letter_name(
294
+ entity_id, label, sequence_by_entity, name
295
+ )
296
+
297
+ if one_letter_name not in "ACGUTN":
265
298
  one_letter_name = detect_one_letter_name(residue_atoms)
266
- residue = Residue3D(
267
- label, auth, model, one_letter_name, tuple(residue_atoms)
299
+
300
+ residues.append(
301
+ Residue3D(label, auth, model, one_letter_name, tuple(residue_atoms))
268
302
  )
269
- if not nucleic_acid_only or (nucleic_acid_only and residue.is_nucleotide):
270
- residues.append(residue)
303
+
271
304
  key_previous = key
272
305
  residue_atoms = [atom]
273
306
 
274
307
  label = key_previous[0]
275
308
  auth = key_previous[1]
276
309
  model = key_previous[2]
310
+ entity_id = residue_atoms[-1].entity_id
277
311
  name = get_residue_name(auth, label, modified)
278
- one_letter_name = get_one_letter_name(label, sequence, name)
279
- if one_letter_name not in "ACGUT":
312
+ one_letter_name = get_one_letter_name(entity_id, label, sequence_by_entity, name)
313
+
314
+ if one_letter_name not in "ACGUTN":
280
315
  one_letter_name = detect_one_letter_name(residue_atoms)
281
- residue = Residue3D(label, auth, model, one_letter_name, tuple(residue_atoms))
282
- if not nucleic_acid_only or (nucleic_acid_only and residue.is_nucleotide):
283
- residues.append(residue)
316
+
317
+ residues.append(
318
+ Residue3D(label, auth, model, one_letter_name, tuple(residue_atoms))
319
+ )
320
+
321
+ if nucleic_acid_only:
322
+ if is_nucleic_acid_by_entity:
323
+ residues = [
324
+ residue
325
+ for residue in residues
326
+ if is_nucleic_acid_by_entity[residue.atoms[0].entity_id]
327
+ ]
328
+ else:
329
+ residues = [residue for residue in residues if residue.is_nucleotide]
284
330
 
285
331
  return Structure3D(residues)
286
332
 
@@ -305,13 +351,14 @@ def get_residue_name(
305
351
 
306
352
 
307
353
  def get_one_letter_name(
308
- label: Optional[ResidueLabel], sequence: Dict[Tuple[str, int], str], name: str
354
+ entity_id: Optional[str],
355
+ label: Optional[ResidueLabel],
356
+ sequence_by_entity: Dict[str, str],
357
+ name: str,
309
358
  ) -> str:
310
359
  # try getting the value from _entity_poly first
311
- if label is not None:
312
- key = (label.chain, label.number)
313
- if key in sequence:
314
- return sequence[key]
360
+ if entity_id is not None and label is not None and entity_id in sequence_by_entity:
361
+ return sequence_by_entity[entity_id][label.number - 1]
315
362
  # RNA
316
363
  if len(name) == 1:
317
364
  return name
@@ -335,11 +382,13 @@ def detect_one_letter_name(atoms: List[Atom]) -> str:
335
382
  ) / len(atom_names_expected)
336
383
  score[candidate] = count
337
384
  items = sorted(score.items(), key=lambda kv: kv[1], reverse=True)
385
+ if items[0][1] == 0:
386
+ return "?"
338
387
  return items[0][0]
339
388
 
340
389
 
341
390
  def try_parse_int(s: str) -> Optional[int]:
342
391
  try:
343
392
  return int(s)
344
- except:
393
+ except ValueError:
345
394
  return None
rnapolis/rfam_folder.py CHANGED
@@ -14,7 +14,6 @@ from typing import List
14
14
  import appdirs
15
15
  import requests
16
16
  import RNA
17
-
18
17
  from rnapolis.common import BpSeq, DotBracket
19
18
 
20
19
  COMBINED_CM = "https://ftp.ebi.ac.uk/pub/databases/Rfam/CURRENT/Rfam.cm.gz"
rnapolis/tertiary.py CHANGED
@@ -7,7 +7,6 @@ from typing import Dict, List, Optional, Set, Tuple, Union
7
7
 
8
8
  import numpy
9
9
  import numpy.typing
10
-
11
10
  from rnapolis.common import (
12
11
  BasePair,
13
12
  BpSeq,
@@ -97,6 +96,7 @@ AVERAGE_OXYGEN_PHOSPHORUS_DISTANCE_COVALENT = 1.6
97
96
 
98
97
  @dataclass(frozen=True, order=True)
99
98
  class Atom:
99
+ entity_id: Optional[str]
100
100
  label: Optional[ResidueLabel]
101
101
  auth: Optional[ResidueAuth]
102
102
  model: int
@@ -129,6 +129,29 @@ class Residue3D(Residue):
129
129
  "C": set(["N1", "C2", "O2", "N3", "C4", "N4", "C5", "C6"]),
130
130
  "U": set(["N1", "C2", "O2", "N3", "C4", "O4", "C5", "C6"]),
131
131
  }
132
+ # Heavy atoms in nucleotide
133
+ nucleotide_heavy_atoms = (
134
+ set(
135
+ [
136
+ "P",
137
+ "OP1",
138
+ "OP2",
139
+ "O5'",
140
+ "C5'",
141
+ "C4'",
142
+ "O4'",
143
+ "C3'",
144
+ "O3'",
145
+ "C2'",
146
+ "O2'",
147
+ "C1'",
148
+ ]
149
+ )
150
+ .union(nucleobase_heavy_atoms["A"])
151
+ .union(nucleobase_heavy_atoms["G"])
152
+ .union(nucleobase_heavy_atoms["C"])
153
+ .union(nucleobase_heavy_atoms["U"])
154
+ )
132
155
 
133
156
  def __lt__(self, other):
134
157
  return (self.model, self.chain, self.number, self.icode or " ") < (
@@ -177,8 +200,8 @@ class Residue3D(Residue):
177
200
 
178
201
  @cached_property
179
202
  def is_nucleotide(self) -> bool:
180
- return len(self.atoms) > 1 and any(
181
- [atom for atom in self.atoms if atom.name == "C1'"]
203
+ return self.nucleotide_heavy_atoms.intersection(
204
+ set([atom.name for atom in self.atoms])
182
205
  )
183
206
 
184
207
  @cached_property
@@ -269,7 +292,7 @@ class Residue3D(Residue):
269
292
  logging.error(
270
293
  f"Failed to determine the outermost atom for nucleotide {self}, so an arbitrary atom will be used"
271
294
  )
272
- yield Atom(self.label, self.auth, self.model, "UNK", 0.0, 0.0, 0.0, None)
295
+ yield Atom(None, self.label, self.auth, self.model, "UNK", 0.0, 0.0, 0.0, None)
273
296
 
274
297
  def __inner_generator(self):
275
298
  # try to find expected atom name
@@ -297,7 +320,7 @@ class Residue3D(Residue):
297
320
  logging.error(
298
321
  f"Failed to determine the innermost atom for nucleotide {self}, so an arbitrary atom will be used"
299
322
  )
300
- yield Atom(self.label, self.auth, self.model, "UNK", 0.0, 0.0, 0.0, None)
323
+ yield Atom(None, self.label, self.auth, self.model, "UNK", 0.0, 0.0, 0.0, None)
301
324
 
302
325
 
303
326
  @dataclass(frozen=True, order=True)
@@ -1,17 +0,0 @@
1
- rnapolis/annotator.py,sha256=XnjFBeu3P_2UMdkD4Ao7m7K6JfeqYa-13xRzghrLvt8,22086
2
- rnapolis/clashfinder.py,sha256=jD3s_UovygWi01NUbQNeAeRRFkARTSRraLXUV43UbAA,8514
3
- rnapolis/common.py,sha256=tbmKV64nLClmzNN0HyKnvWA0-5aSyf4x8CGpBjpIJ4M,30290
4
- rnapolis/metareader.py,sha256=9HZIrpPsmmWkEUeSeKAeG1sstfqbBDKUw5QPsn5cshw,2072
5
- rnapolis/molecule_filter.py,sha256=NhjuqdCRnXgPefWZPeTq77tifmnAzamQtA0ODqPPG9k,6918
6
- rnapolis/motif_extractor.py,sha256=duHvpi9Ulcny9K60E6VBpz5RpJZw-KdTB4_Ph0iP478,774
7
- rnapolis/parser.py,sha256=nHRXcoKbzfMJuDMJO-8MSPkzfmD-788ZzgcfjLQpgFs,12666
8
- rnapolis/rfam_folder.py,sha256=3rgXEJR16uPFy_BOo8qkdClOAOQDVOkidnLE-yoRbeI,11112
9
- rnapolis/tertiary.py,sha256=VuATTN2SD7lBL9iUgT-doDwuEYsLodgV2u-SwQsyQcU,19658
10
- rnapolis/transformer.py,sha256=V9nOQvdq4-p7yUWo0vQg0CDQMpmyxz9t4TMSRVEKHnw,1817
11
- rnapolis/util.py,sha256=IdquFO3PV1_KDqodjupzm0Rqvgy0CeSzxGHaGEHYXVU,543
12
- RNApolis-0.3.17.dist-info/LICENSE,sha256=ZGRu12MzCgbYA-Lt8MyBlmjvPZh7xfiD5u5wBx0enq4,1066
13
- RNApolis-0.3.17.dist-info/METADATA,sha256=2h_8NfBq0uKpgXC-CYsvB1O1hglxTGyZHfGfJmsKrmI,54301
14
- RNApolis-0.3.17.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
15
- RNApolis-0.3.17.dist-info/entry_points.txt,sha256=foN2Pn5e-OzEz0fFmNoX6PnFSZFQntOlY8LbognP5F0,308
16
- RNApolis-0.3.17.dist-info/top_level.txt,sha256=LcO18koxZcWoJ21KDRRRo_tyIbmXL5z61dPitZpy8yc,9
17
- RNApolis-0.3.17.dist-info/RECORD,,