@dataclass(kw_only=True)
class BpRnaRecord(RnaSecondaryStructureRecord):
r"""Container for bpRNA .st annotations."""
structure_array: str
knot_array: str
structure_types: Dict[str, List[str]]
page_number: int | None
@classmethod
def from_rna_secondary_structure_record(cls, record: RnaSecondaryStructureRecord) -> BpRnaRecord:
from ..utils.rna.secondary_structure.bprna import BpRnaSecondaryStructureTopology
from .rna_secondary_structure import _count_bracket_tiers
pairs = notations.dot_bracket_to_pairs(record.dot_bracket)
segment_data = BpRnaSecondaryStructureTopology(record.sequence, pairs, dot_bracket=record.dot_bracket)
page_number = _count_bracket_tiers(record.dot_bracket)
return cls(
sequence=record.sequence,
dot_bracket=record.dot_bracket,
id=record.id,
page_number=page_number,
structure_array=segment_data.structural_annotation,
knot_array=segment_data.functional_annotation,
structure_types=segment_data.structure_types,
)
@classmethod
def from_sequence_pairs(
cls,
sequence: str,
pairs: np.ndarray | Sequence[tuple[int, int]],
*,
id: str | None = None,
dot_bracket: str | None = None,
) -> BpRnaRecord:
from ..utils.rna.secondary_structure.bprna import BpRnaSecondaryStructureTopology
from ..utils.rna.secondary_structure.pairs import normalize_pairs
from .rna_secondary_structure import _count_bracket_tiers
pairs = np.asarray(normalize_pairs(pairs), dtype=int)
if dot_bracket is None:
dot_bracket = notations.pairs_to_dot_bracket(pairs, length=len(sequence), unsafe=True)
elif len(dot_bracket) != len(sequence):
raise ValueError("dot_bracket length must match sequence length")
page_number = _count_bracket_tiers(dot_bracket)
segment_data = BpRnaSecondaryStructureTopology(sequence, pairs, dot_bracket=dot_bracket)
return cls(
sequence=sequence,
dot_bracket=dot_bracket,
id=id,
page_number=page_number,
structure_array=segment_data.structural_annotation,
knot_array=segment_data.functional_annotation,
structure_types=segment_data.structure_types,
)
@classmethod
def read_st(cls, path: str | Path) -> BpRnaRecord:
from .rna_secondary_structure import read_st
return read_st(path)
def write_st(self, path: str | Path) -> Path:
from .rna_secondary_structure import write_st
return write_st(self, path)