Exemplo n.º 1
0
def test_bad_continuity(known_net):
    """
    Test check_continuity().

    This test flips links so that continuity is disturbed.
    """
    links = known_net.links
    links = lnu.flip_link(links, 199)
    links = lnu.flip_link(links, 198)
    problem_nodes = di.check_continuity(links, known_net.nodes)
    # make assertion that a problem node has been created
    assert problem_nodes == [177]
Exemplo n.º 2
0
def test_fix_source_sink_river(known_river):
    """Test fix_sources_and_sinks() with river example."""
    links = known_river.links
    # flip links to create sources/sinks and check that it happened
    links = lnu.flip_link(links, 2635)
    links = lnu.flip_link(links, 2634)
    bad_nodes = di.check_continuity(links, known_river.nodes)
    assert bad_nodes == [1897, 1899]
    # now try to fix them
    newlinks, nodes = di.fix_sources_and_sinks(links, known_river.nodes)
    # re-check for sources and sinks and verify that there are less bad nodes
    fixed_nodes = di.check_continuity(newlinks, known_river.nodes)
    assert len(fixed_nodes) < len(bad_nodes)
Exemplo n.º 3
0
def test_find_cycle(known_net):
    """Test find_a_cycle() by creating one."""
    links = known_net.links
    links = lnu.flip_link(links, 964)
    c_nodes, c_links = di.find_a_cycle(links, known_net.nodes)
    # make assertions
    assert c_nodes == [761, 784]
    assert c_links == [964, 964]
Exemplo n.º 4
0
def test_fix_cycles_river(known_river):
    """Test fix_cycles() with river example."""
    links = known_river.links
    nodes = known_river.nodes
    # flip link to create a cycle
    links = lnu.flip_link(links, 2494)
    # check that cycle exists
    c_nodes, c_links = di.find_a_cycle(links, nodes)
    assert c_nodes == [1794, 1805]
    assert c_links == [2494, 2494]
    # check that there are no continuity issues
    problem_nodes = di.check_continuity(links, nodes)
    assert problem_nodes == []
    # now try to fix the cycles
    links, nodes, n_cycles = di.fix_cycles(links, nodes)
Exemplo n.º 5
0
def test_set_link_directions(known_net):
    """Test set_link_directions()."""
    links = known_net.links
    nodes = known_net.nodes
    imshape = known_net.Imask.shape
    # verify that old problem node exists or create it
    old_problem_nodes = di.check_continuity(links, nodes)
    if 177 in old_problem_nodes:
        assert old_problem_nodes == [177]
    else:
        links = lnu.flip_link(links, 198)
        old_problem_nodes = di.check_continuity(links, nodes)
        assert old_problem_nodes == [177]
    # set up capture string
    capturedOutput = io.StringIO()
    sys.stdout = capturedOutput
    # apply the function
    newlinks, newnodes = dd.set_link_directions(links, nodes, imshape)
    # grab output
    sys.stdout = sys.__stdout__
    # assert output
    assert capturedOutput.getvalue()[:-1] == 'Nodes 177 violate continuity. Check connected links and fix manually.'
Exemplo n.º 6
0
def fix_river_cycle(links, nodes, cyclelinks, cyclenodes, imshape):
    """
    Attempt to fix a single cycle.

    Attempts to resolve a single cycle within a river network. The general
    logic is that all link directions of the cycle are un-set except for those
    set by highly-reliable algorithms, and a modified direction-setting
    recipe is implemented to re-set these algorithms. This was developed
    according to the most commonly-encountered cases for real braided rivers,
    but could certainly be improved.


    Parameters
    ----------
    links : dict
        Network links and associated properties.
    nodes : dict
        Network nodes and associated properties.
    cyclelinks : list
        List of link ids that comprise a cycle.
    cyclenodes : list
        List of node ids taht comprise a cycle.
    imshape : tuple
        Shape of binary mask as (nrows, ncols).

    Returns
    -------
    links : dict
        Network links and associated properties with the cycle fixed if
        possible.
    nodes : dict
        Network nodes and associated properties with the cycle fixed if
        possible.
    fixed : int
        1 if the cycle was resolved, else 0.

    """

    # dont_reset_algs = [20, 21, 22, 23, 0, 5]
    dont_reset_algs = [
        dy.algmap(key) for key in [
            'manual_set', 'cl_dist_guess', 'cl_ang_guess', 'cl_dist_set',
            'cl_ang_set', 'inletoutlet', 'bridges'
        ]
    ]

    fixed = 1  # One if fix was successful, else zero
    reset = 0  # One if original orientation need to be reset

    # If an artifical node triad is present, flip its direction and see if the
    # cycle is resolved.
    # See if any links are part of an artificial triad
    clset = set(cyclelinks)
    all_pars = []
    for i, pl in enumerate(links['parallels']):
        if len(clset.intersection(set(pl))) > 0:
            all_pars.append(pl)

    # Get continuity violators before flipping
    pre_sourcesink = dy.check_continuity(links, nodes)

    if len(
            all_pars
    ) == 1:  # There is one parallel link set, flip its direction and re-set other cycle links and see if cycle is resolved
        certzero = list(set(all_pars[0] + cyclelinks))
        orig_links = dy.cycle_get_original_orientation(
            links, certzero
        )  # Save the original orientations in case the cycle can't be fixed
        for cz in certzero:
            links['certain'][links['id'].index(cz)] = 0

        # Flip the links of the triad
        for l in all_pars[0]:
            links = lnu.flip_link(links, l)

    if len(
            all_pars
    ) > 1:  # If there are multiple parallel pairs, more code needs to be written for these cases
        print(
            'Multiple parallel pairs in the same cycle. Not implemented yet.')
        return links, nodes, 0

    elif len(
            all_pars
    ) == 0:  # No aritifical node triads; just re-set all the cycle links and see if cycle is resolved
        certzero = cyclelinks
        orig_links = dy.cycle_get_original_orientation(links, certzero)
        for cz in certzero:
            lidx = links['id'].index(cz)
            if links['certain_alg'][lidx] not in dont_reset_algs:
                links['certain'][lidx] = 0

    # Resolve the unknown cycle links
    links, nodes = re_set_linkdirs(links, nodes, imshape)

    # See if the fix violated continuity - if not, reset to original
    post_sourcesink = dy.check_continuity(links, nodes)
    if len(set(post_sourcesink) - set(pre_sourcesink)) > 0:
        reset = 1

    # See if the fix resolved the cycle - if not, reset to original
    cyc_n, cyc_l = dy.get_cycles(links, nodes, checknode=cyclenodes[0])
    if cyc_n is not None and cyclenodes[0] in cyc_n[0]:
        reset = 1

    # Return the links to their original orientations if cycle could not
    # be resolved
    if reset == 1:

        links = dy.cycle_return_to_original_orientation(links, orig_links)

        # Try a second method to fix the cycle: unset all the links of the
        # cycle AND the links connected to those links
        set_to_zero = set()
        for cn in cyclenodes:
            conn = nodes['conn'][nodes['id'].index(cn)]
            set_to_zero.update(conn)
        set_to_zero = list(set_to_zero)

        # Save original orientation in case cycle cannot be fixed
        orig_links = dy.cycle_get_original_orientation(links, set_to_zero)

        for s in set_to_zero:
            lidx = links['id'].index(s)
            if links['certain_alg'][lidx] not in dont_reset_algs:
                links['certain'][lidx] = 0

        links, nodes = re_set_linkdirs(links, nodes, imshape)

        # See if the fix violated continuity - if not, reset to original
        post_sourcesink = dy.check_continuity(links, nodes)
        if len(set(post_sourcesink) - set(pre_sourcesink)) > 0:
            reset = 1

        # See if the fix resolved the cycle - if not, reset to original
        cyc_n, cyc_l = dy.get_cycles(links, nodes, checknode=cyclenodes[0])
        if cyc_n is not None and cyclenodes[0] in cyc_n[0]:
            reset = 1

        if reset == 1:
            links = dy.cycle_return_to_original_orientation(links, orig_links)
            fixed = 0

    return links, nodes, fixed