Source code for RNAsketch.Structure

#!/usr/bin/env python
from __future__ import print_function

'''
    Structure.py: Class for RNA secondary structures
    This implements various useful functions to manipulate and analyze secondary structures.
'''

__author__ = "Stefan Hammer"
__copyright__ = "Copyright 2018"
__version__ = "0.1"
__maintainer__ = "Stefan Hammer"
__email__ = "s.hammer@univie.ac.at"

from collections import Counter

[docs]class RNAStructure(object): ''' RNAStructure object to handle RNA secondary structures. Holds a pairtable internally to operate on. :param dotbracket: Dot-bracket notation of the RNA secondary structure as string ''' def __init__(self, dotbracket): self._dotbracket = dotbracket self._pairtable = self._parseRNAStructure(dotbracket) def __str__(self): return self._dotbracket def __unicode__(self): return unicode(self._dotbracket) def _parseRNAStructure(self, structure): ''' Parse RNA structure including pseudoknots :param structure: string, RNA secondary structure in dot-bracket notation :return: list of positions specifying the pair-table ''' opening = "([{<" closing = ")]}>" stack = { op:list() for op in opening } bps = [-1]*len(structure) for i,c in enumerate(structure): for (op,cl) in zip(opening,closing): if c==op: stack[op].append(i) elif c==cl: j = stack[op].pop() bps[i] = j bps[j] = i return bps
[docs] def resolvePKs(self): ''' Removes any pseudoknots from the structure. Pseudoknotted base-pairs are missing in the returned structure! :return: list of pseudoknot-free structure strings in dot-bracket notation ''' opening = "([{<" closing = ")]}>" structures = [] c = Counter(self._dotbracket) for (op,cl) in zip(opening,closing): if c[op] > 0: newstruct = [] for n in self._dotbracket: if n == op: newstruct.append('(') elif n == cl: newstruct.append(')') else: newstruct.append('.') structures.append(''.join(newstruct)) return structures
[docs] def removeLonelyPairs(self): ''' Returns a dotbracket string without lonely pairs. :return: structure string in dot-bracket notation without any lonely pairs ''' newstruct = ['.'] * len(self._dotbracket) for (i,j) in enumerate(self._pairtable): # this pair is stacking if i+1<j-1 and self._pairtable[i+1]==j-1: for n in [i, j, i+1, j-1]: newstruct[n] = self._dotbracket[n] return ''.join(newstruct)
[docs] def hasLonelyPairs(self): ''' Returns a boolean whether the structure has lonely pairs :return: boolean ''' return self.removeLonelyPairs() is self._dotbracket