Source code for bg.kbreak

# -*- coding: utf-8 -*-
from collections import Counter


__author__ = "Sergey Aganezov"
__email__ = "aganezov(at)cs.jhu.edu"
__status__ = "production"


[docs]class KBreak(object): """ A generic object that can represent any k-break ( k>= 2) A notion of k-break arises from the bioinformatics combinatorial object BreakpointGraph and is first mentioned in http://home.gwu.edu/~maxal/ap_tcs08.pdf A generic k-break operates on k specified edges of spisific multicolor and replaces them with another set of k edges with the same multicolor on the same set of vertices in way, that the degree of vertices is kept intact. Initialization of the instance of :class:`KBreak` is performed with a validity check of supplied data, which must comply with the definition of k-break. Class carries following attributes carrying information about k-break structure: * :attr:`KBreak.start_edges`: a list of edges (in terms of paired vertices) that are to be removed by current :class:`KBreak` * :attr:`KBreak.result_edges`: a list of edges (in terms of paired vertices) that are to be created by current :class:`KBreak` * :attr:`KBreak.multicolor`: a :class:`bg.multicolor.Multicolor` instance, that specifies the multicolor of edges that are to be removed / created by current :class:`KBreak` Main operations: * :meth:`KBreak.valid_kbreak_matchings`: a method that checks if provided sets of started / resulted edges comply with the notions ob k-break definition """
[docs] def __init__(self, start_edges, result_edges, multicolor, data=None): """ Initialization of :class:`KBreak` object. The initialization process consists of multiple checks, before any assignment and initialization itself is performed. First checks the fact, that information about start / result edges is supplied in form of paired vertices. Then check is performed to make sure, that degrees of vertices, that current :class:`KBreak` operates on, is preserved. :param start_edges: a list of pairs of vertices, that specifies where edges shall be removed by current :class:`KBreak` :type start_edges: ``list(tuple(vertex, vertex), ...)`` :param result_edges: a list of pairs of vertices, that specifies where edges shall be created by current :class:`KBreak` :type result_edges: ``list(tuple(vertex, vertex), ...)`` :param multicolor: a multicolor, that specifies which edges between specified pairs of vertices are to be removed / created :type multicolor: :class:`bg.multicolor.Multicolor` :return: a new instance of :class:`Kbreak` :rtype: :class:`KBreak` :raises: ``ValueError`` """ self.start_edges = start_edges self.result_edges = result_edges self.multicolor = multicolor if data is None: data = self.create_default_data_dict() self.data = data for vertex_pair in self.start_edges: if len(vertex_pair) != 2: raise ValueError("Expected edges in a form of pairs of vertices.\n " "Not a pair of vertices ({issue}) in start edges." "".format(issue=str(vertex_pair))) for vertex_pair in self.result_edges: if len(vertex_pair) != 2: raise ValueError("Expected edges in a form of pairs of vertices.\n " "Not a pair of vertices ({issue}) in result edges." "".format(issue=str(vertex_pair))) if not KBreak.valid_kbreak_matchings(start_edges=self.start_edges, result_edges=self.result_edges): raise ValueError("Supplied sets of start and result edges do not correspond to " "correct k-break operation (either the set of vertices is not consistent, or " "the degrees of vertices change)")
@property def is_a_two_break(self): return len(self.start_edges) == 2 @property def is_a_fusion(self): return self.is_a_two_break and any(map(lambda vertex_set: all(map(lambda vertex: vertex.is_irregular_vertex, vertex_set)), self.result_edges)) @classmethod def create_default_data_dict(cls): return { "origin": None }
[docs] @staticmethod def valid_kbreak_matchings(start_edges, result_edges): """ A staticmethod check implementation that makes sure that degrees of vertices, that are affected by current :class:`KBreak` By the notion of k-break, it shall keep the degree of vertices in :class:`bg.breakpoint_graph.BreakpointGraph` the same, after its application. By utilizing the Counter class, such check is performed, as the number the vertex is mentioned corresponds to its degree. :param start_edges: a list of pairs of vertices, that specifies where edges shall be removed by :class:`KBreak` :type start_edges: ``list(tuple(vertex, vertex), ...)`` :param result_edges: a list of pairs of vertices, that specifies where edges shall be created by :class:`KBreak` :type result_edges: ``list(tuple(vertex, vertex), ...)`` :return: a flag indicating if the degree of vertices are equal in start / result edges, targeted by :class:`KBreak` :rtype: ``Boolean`` """ start_stats = Counter(vertex for vertex_pair in start_edges for vertex in vertex_pair) result_stats = Counter(vertex for vertex_pair in result_edges for vertex in vertex_pair) return start_stats == result_stats