Example #1
0
def _fix_transfer(node: tree.Node,
                  left_node,
                  right_node: tree.Node,
                  host_node: tree.Node,
                  host_lookup: dict,
                  parasite_lookup: dict,
                  recon_obj: recon.Reconciliation,
                  node_col: float = None,
                  offset_number: int = 1):
    """
    Checks to see in tranfer node is inconsistent and the tries to fix node if it can be slid down the host edge
    The tries to push a given node forward if possible to correct the assumed inconsistency
    :param node: Node object representing the parasite event being rendered
    :param node: Right node of the node object
    :param left_node: Left node of the node object
    :param right_node: Right node of the node object
    :param host_node: Node object represeting a host that the parasite node is mapped to
    :param host_lookup: Dictionary with host node names as the key and host node objects as the values
    :param parasite_lookup: Dictionary with parasite node names as the key and parasite node objects as the values
    :param recon_obj: Reconciliation object that represents an edge-to-edge mapping from  a parasite tree to a host tree
    :param node_col: Column of the node, used when function is called recursively to check the next available transfer spot
    :param offset_number: Used to push node to an available transfer spot
    """
    min_col = host_lookup[recon_obj.mapping_of(
        right_node.name).host].parent_node.layout.col
    max_col = host_node.layout.col
    node_col = node.layout.col
    max_col = min(host_node.layout.col, left_node.layout.col)
    if not (node_col):
        node_col = node.layout.col

    # Checks to see if transfer is inconsistent and if the inconsistency can be fixed by sliding the transfer node down the host edge
    if min_col >= node_col and min_col < max_col and not (_is_sharing_track(
            node, host_node.name, recon_obj)):
        node.set_layout(col=min_col + 0.5, x=min_col + 0.5)
    if min_col < max_col:
        new_value = min_col + render_settings.PUSHED_NODE_OFFSET * offset_number
        if _is_col_taken(new_value, host_lookup, parasite_lookup):
            _fix_transfer(node,
                          left_node,
                          right_node,
                          host_node,
                          host_lookup,
                          parasite_lookup,
                          recon_obj,
                          node_col=new_value,
                          offset_number=offset_number + 1)
        else:
            node.set_layout(col=new_value, x=new_value)
Example #2
0
def _render_parasite_helper(fig: plot_tools.FigureWrapper, node: tree.Node,
                            recon_obj: recon.Reconciliation, host_lookup: dict,
                            parasite_lookup: dict, show_internal_labels: bool,
                            show_freq: bool, font_size: float,
                            longest_host_name: int):
    """
    Helper function for rendering the parasite tree.
    :param fig: Figure object that visualizes trees using MatplotLib
    :param node: Node object representing the parasite event being rendered
    :param recon_obj: Reconciliation object that represents an edge-to-edge mapping from  a parasite tree to a host tree
    :param host_lookup: Dictionary with host node names as the key and host node objects as the values
    :param parasite_lookup: Dictionary with parasite node names as the key and parasite node objects as the values
    :param show_internal_labels: Boolean that determines whether or not the internal labels are shown
    :param show_freq: Boolean that determines wheter or not the frequencies are shown
    :param font_size: Font size for the text of the tips and internal nodes of the tree
    :param longest_host_name: The number of symbols in the longest host tree tip name
    """
    # mapping_node is of type MappingNode which associates
    # a parasite to a host in a reconciliation
    mapping_node = recon_obj.mapping_of(node.name)

    # A reconciliation has an event_of method which is an object of
    # type Event.
    event = recon_obj.event_of(mapping_node)

    host_name = mapping_node.host

    # host_lookup is a dictionary computed in the Tree class
    # that associates a host name (a string) with the correspond node
    # object for that host.  The node object contains layout information
    # which we need here.
    host_node = host_lookup[host_name]

    # Set parasite node layout
    host_row = host_node.layout.row
    # host_col = host_node.layout.col
    # host_x = host_node.layout.x
    host_y = host_node.layout.y
    node.set_layout(row=host_row, x=node.layout.col, y=host_y)

    # Render parasite node and recurse if not a leaf
    if node.is_leaf():
        node.layout.y += host_node.get_and_update_track(
            tree.Track.HORIZONTAL) * host_node.layout.offset
        _render_parasite_node(fig, node, event, font_size, longest_host_name)
        return

    # If the Node is in their own track, change their position
    if not (_is_sharing_track(node, host_name, recon_obj)):
        node.layout.y += host_node.layout.h_track * host_node.layout.offset

    left_node, right_node = _get_children(node, recon_obj, parasite_lookup)

    _render_parasite_helper(fig, left_node, recon_obj, host_lookup,
                            parasite_lookup, show_internal_labels, show_freq,
                            font_size, longest_host_name)
    _render_parasite_helper(fig, right_node, recon_obj, host_lookup,
                            parasite_lookup, show_internal_labels, show_freq,
                            font_size, longest_host_name)

    # Checking to see if left node is mapped to the same host node as parent
    if node.layout.row == left_node.layout.row:
        node.set_layout(y=left_node.layout.y)
    elif node.layout.row == right_node.layout.row:
        node.set_layout(y=right_node.layout.y)
    elif event.event_type is recon.EventType.TRANSFER:
        node.layout.y = host_node.layout.y + host_node.layout.h_track * host_node.layout.offset

    #Checks to see if transfer node is inconsistent and if it can be fixed
    if event.event_type is recon.EventType.TRANSFER:
        min_col = host_lookup[recon_obj.mapping_of(
            right_node.name).host].parent_node.layout.col
        if min_col >= node.layout.col:
            _fix_transfer(node, left_node, right_node, host_node, host_lookup,
                          parasite_lookup, recon_obj)

    _render_parasite_branches(fig, node, recon_obj, host_lookup,
                              parasite_lookup)
    _render_parasite_node(fig, node, event, font_size, longest_host_name,
                          show_internal_labels, show_freq)