示例#1
0
def re_set_linkdirs(links, nodes, imshape):
    """
    Reset link directions.

    Resets the link directions for a braided river channel network. This
    function is called to reset directions of links that belong to a cycle.

    Parameters
    ----------
    links : dict
        Network links and associated properties.
    nodes : dict
        Network nodes and associated properties.
    imshape : tuple
        Shape of binary mask as (nrows, ncols).

    Returns
    -------
    links : dict
        Network links and associated properties with the directions re-set.
    nodes : dict
        Network nodes and associated properties with the directions re-set.

    """
    links, nodes = dy.set_continuity(links, nodes)

    # Set the directions of the links that are more certain via centerline angle method
    # alg = 23.1
    alg = dy.algmap('cl_ang_rs')
    cl_angthresh = np.percentile(
        links['clangs'][np.isnan(links['clangs']) == 0], 40)
    for lid, cla, lg, lga, cert in zip(links['id'], links['clangs'],
                                       links['guess'], links['guess_alg'],
                                       links['certain']):
        if cert == 1:
            continue
        if np.isnan(cla) == True:
            continue
        if cla <= cl_angthresh:
            linkidx = links['id'].index(lid)
            if dy.algmap('cl_ang_guess') in lga:
                usnode = lg[lga.index(dy.algmap('cl_ang_guess'))]
                links, nodes = dy.set_link(links, nodes, linkidx, usnode, alg)

    angthreshs = np.linspace(0, 1.3, 20)
    for a in angthreshs:
        links, nodes = dy.set_by_known_flow_directions(
            links,
            nodes,
            imshape,
            angthresh=a,
            lenthresh=0,
            alg=dy.algmap('known_fdr_rs'))

    if np.sum(links['certain']) != len(links['id']):
        links_notset = links['id'][np.where(links['certain'] == 0)[0][0]]
        print('Links {} were not set by re_set_linkdirs.'.format(links_notset))

    return links, nodes
示例#2
0
def dir_link_widths(links):
    """
    Guess link directions based on link widths.

    Guesses each link's direction based on link widths at the endpoints. The
    node with the larger width is guessed to be the upstream node. The ratio
    of guessed upstream to guessed downstream node widths is appended to links.
    If the width at a link's endpoint is 0, the percent is set to 1000. This
    ratio is appended to the links dictionary as links['wid_pctdiff'].


    Parameters
    ----------
    links : dict
        Network links and associated properties.

    Returns
    -------
    links : dict
        Network links and associated properties with 'wid_pctdiff' property
        appended.

    """
    # alg = 26
    alg = dy.algmap('wid_pctdiff')

    widpcts = np.zeros((len(links['id']), 1))
    for i in range(len(links['id'])):

        lw = links['wid_pix'][i]

        if lw[0] > lw[-1]:
            links['guess'][i].append(links['conn'][i][0])
            links['guess_alg'][i].append(alg)
            if lw[-1] == 0 and lw[0] > 1:
                widpcts[i] = 10
            elif lw[-1] == 0:
                widpcts[i] = 0
            else:
                widpcts[i] = (lw[0] - lw[-1]) / lw[-1]
        else:
            links['guess'][i].append(links['conn'][i][1])
            links['guess_alg'][i].append(alg)
            if lw[0] == 0 and lw[-1] > 1:
                widpcts[i] = 10
            elif lw[0] == 0:
                widpcts[i] = 0
            else:
                widpcts[i] = (lw[-1] - lw[0]) / lw[0]

    # Convert to percent and store in links dict
    links['wid_pctdiff'] = widpcts * 100

    return links
示例#3
0
    def re_set_linkdirs(links, nodes, imshape):
        # Cycle links are attempted to be reset according to algorithms here.
        angthreshs = np.linspace(0, 1.2, 20)
        for a in angthreshs:
            links, nodes = dy.set_by_known_flow_directions(
                links,
                nodes,
                imshape,
                angthresh=a,
                lenthresh=0,
                alg=dy.algmap('known_fdr_rs'))

        return links, nodes
 def test_cl_dist_and_ang(self):
     assert di.algmap('cl_dist_and_ang') == 24
 def test_cl_ang_set(self):
     assert di.algmap('cl_ang_set') == 23
 def test_cl_ang_guess(self):
     assert di.algmap('cl_ang_guess') == 21
 def test_syn_dem_and_sp(self):
     assert di.algmap('syn_dem_and_sp') == 16
 def test_longest_steepest(self):
     assert di.algmap('longest_steepest') == 13
 def test_sp_links(self):
     assert di.algmap('sp_links') == 11
示例#10
0
 def test_continuity(self):
     assert di.algmap('continuity') == 1
示例#11
0
 def test_inletoutlet(self):
     assert di.algmap('inletoutlet') == 0
示例#12
0
 def test_manual_set(self):
     assert di.algmap('manual_set') == -1
示例#13
0
 def test_sourcesinkfix(self):
     assert di.algmap('sourcesinkfix') == -2
示例#14
0
 def test_wid_pctdiff(self):
     assert di.algmap('wid_pctdiff') == 26
示例#15
0
def set_initial_directionality(links, nodes, imshape):
    """
    Make initial attempt to set flow directions.

    Makes an initial attempt to set all flow directions within the network.
    This represents the core of the "delta recipe" described in the following
    open access paper:
    https://esurf.copernicus.org/articles/8/87/2020/esurf-8-87-2020.pdf
    However, note that as RivGraph develops, this recipe may no longer match
    the one presented in that paper. The recipe chains together a number of
    exploitative algorithms to iteratively set flow directions for the most
    certain links first.


    Parameters
    ----------
    links : dict
        Network links and associated properties.
    nodes : dict
        Network nodes and associated properties.
    imshape : tuple
        Shape of binary mask as (nrows, ncols).

    Returns
    -------
    links : dict
        Network links and associated properties with initial directions set.
    nodes : dict
        Network nodes and associated properties with initial directions set.

    """
    # Compute all the "guesses"
    links, nodes = dy.dir_main_channel(links, nodes)
    links, nodes = dir_synthetic_DEM(links, nodes, imshape)
    links, nodes = dy.dir_shortest_paths_nodes(links, nodes)
    links, nodes = dy.dir_shortest_paths_links(links, nodes)
    links, nodes = dy.dir_bridges(links, nodes)

    # Set link directions
    # First, set inlet/outlet directions as they are always 100% accurate
    links, nodes = dy.set_inletoutlet(links, nodes)

    # Use bridges to set links as they are always 100% accurate
    # alg = 5
    alg = dy.algmap('bridges')
    for lid, idcs, lg, lga, cert in zip(links['id'], links['idx'],
                                        links['guess'], links['guess_alg'],
                                        links['certain']):
        # Only need to set links that haven't been set
        if cert == 1:
            continue
        linkidx = links['id'].index(lid)
        # Set all the links that are known from bridge links
        if alg in lga:
            links, nodes = dy.set_link(links, nodes, linkidx,
                                       lg[lga.index(alg)], alg)

    # Use main channels (4) to set links
    # alg = 4
    alg = dy.algmap('main_chans')
    for lid, idcs, lg, lga, cert in zip(links['id'], links['idx'],
                                        links['guess'], links['guess_alg'],
                                        links['certain']):
        # Only need to set links that haven't been set
        if cert == 1:
            continue
        linkidx = links['id'].index(lid)
        # Set all the links that are known from main_channel
        if alg in lga:
            links, nodes = dy.set_link(links, nodes, linkidx,
                                       lg[lga.index(alg)], alg)

    # Set the longest, steepest links according to io_surface
    # (these are those we are most certain of)
    # alg = 13
    alg = dy.algmap('longest_steepest')
    len75 = np.percentile(links['len_adj'], 75)
    slope50 = np.percentile(np.abs(links['slope']), 50)
    for lid, llen, lg, lga, cert, lslope in zip(links['id'], links['len_adj'],
                                                links['guess'],
                                                links['guess_alg'],
                                                links['certain'],
                                                links['slope']):
        if cert == 1:
            continue
        if llen > len75 and abs(lslope) > slope50:
            linkidx = links['id'].index(lid)
            if dy.algmap('syn_dem') in lga:
                usnode = lg[lga.index(dy.algmap('syn_dem'))]
                links, nodes = dy.set_link(links, nodes, linkidx, usnode, alg)

    # Set the most certain angles
    angthreshs = np.linspace(0, 0.5, 10)
    for a in angthreshs:
        links, nodes = dy.set_by_known_flow_directions(links,
                                                       nodes,
                                                       imshape,
                                                       angthresh=a)

    # Set using direction of nearest main channel
    links, nodes = dy.set_by_nearest_main_channel(links,
                                                  nodes,
                                                  imshape,
                                                  nodethresh=2)

    # Set the most certain angles
    angthreshs = np.linspace(0, 0.7, 10)
    for a in angthreshs:
        links, nodes = dy.set_by_known_flow_directions(links,
                                                       nodes,
                                                       imshape,
                                                       angthresh=a)

    # Set using direction of nearest main channel
    links, nodes = dy.set_by_nearest_main_channel(links,
                                                  nodes,
                                                  imshape,
                                                  nodethresh=1)

    angthreshs = np.linspace(0, 0.8, 10)
    for a in angthreshs:
        links, nodes = dy.set_by_known_flow_directions(links,
                                                       nodes,
                                                       imshape,
                                                       angthresh=a,
                                                       lenthresh=3)

    # Use io_surface (3) to set links that are longer
    # than the median link length
    alg = dy.algmap('syn_dem')
    medlinklen = np.median(links['len'])
    for lid, llen, lg, lga, cert in zip(links['id'], links['len'],
                                        links['guess'], links['guess_alg'],
                                        links['certain']):
        if cert == 1:
            continue
        if llen > medlinklen and dy.algmap('syn_dem') in lga:
            linkidx = links['id'].index(lid)
            usnode = lg[lga.index(dy.algmap('syn_dem'))]
            links, nodes = dy.set_link(links, nodes, linkidx, usnode, alg)

    # Set again by angles, but reduce the lenthresh
    # (shorter links will be set that were not previously)
    angthreshs = np.linspace(0, 0.6, 10)
    for a in angthreshs:
        links, nodes = dy.set_by_known_flow_directions(links,
                                                       nodes,
                                                       imshape,
                                                       angthresh=a,
                                                       lenthresh=0)

    # If any three methods agree, set that link to whatever they agree on
    # alg = 15
    alg = dy.algmap('three_agree')
    for lid, idcs, lg, lga, cert in zip(links['id'], links['idx'],
                                        links['guess'], links['guess_alg'],
                                        links['certain']):
        # Only need to set links that haven't been set
        if cert == 1:
            continue
        linkidx = links['id'].index(lid)
        # Set all the links with 3 or more guesses that agree
        m = mode(lg)
        if m.count[0] > 2:
            links, nodes = dy.set_link(links, nodes, linkidx, m.mode[0], alg)

    # Set again by angles, but reduce the lenthresh
    # (shorter links will be set that were not previously)
    angthreshs = np.linspace(0, 0.8, 10)
    for a in angthreshs:
        links, nodes = dy.set_by_known_flow_directions(links,
                                                       nodes,
                                                       imshape,
                                                       angthresh=a,
                                                       lenthresh=0)

    # If artificial DEM and at least one shortest path method agree,
    # set link to be their agreement
    # alg = 16
    alg = dy.algmap('syn_dem_and_sp')
    for lid, idcs, lg, lga, cert in zip(links['id'], links['idx'],
                                        links['guess'], links['guess_alg'],
                                        links['certain']):
        # Only need to set links that haven't been set
        if cert == 1:
            continue
        linkidx = links['id'].index(lid)
        # Set all the links with 2 or more same guesses that are not
        # shortest path (one may be shortest path)
        if dy.algmap('syn_dem') in lga and dy.algmap('sp_links') in lga:
            if lg[lga.index(dy.algmap('syn_dem'))] == lg[lga.index(
                    dy.algmap('sp_links'))]:
                links, nodes = dy.set_link(links, nodes, linkidx,
                                           lg[lga.index(dy.algmap('syn_dem'))],
                                           alg)
        elif dy.algmap('syn_dem') in lga and dy.algmap('sp_nodes') in lga:
            if lg[lga.index(dy.algmap('syn_dem'))] == lg[lga.index(
                    dy.algmap('sp_nodes'))]:
                links, nodes = dy.set_link(links, nodes, linkidx,
                                           lg[lga.index(dy.algmap('syn_dem'))],
                                           alg)

    # Find remaining uncertain links
    uncertain = [l for l, lc in zip(links['id'], links['certain']) if lc != 1]

    # Set remaining uncertains according to io_surface (3)
    # alg = 10 # change this one!
    alg = dy.algmap('syn_dem')
    for lid in uncertain:
        linkidx = links['id'].index(lid)
        if alg in links['guess_alg'][linkidx]:
            usnode = links['guess'][linkidx][links['guess_alg'][linkidx].index(
                alg)]
            links, nodes = dy.set_link(links, nodes, linkidx, usnode, alg)

    return links, nodes
示例#16
0
 def test_syn_dem_med(self):
     assert di.algmap('syn_dem_med') == 10.1
示例#17
0
 def test_sym_dem_leftover(self):
     assert di.algmap('sym_dem_leftover') == 10.2
示例#18
0
 def test_parallels(self):
     assert di.algmap('parallels') == 2
示例#19
0
 def test_sp_nodes(self):
     assert di.algmap('sp_nodes') == 12
示例#20
0
 def test_artificials(self):
     assert di.algmap('artificials') == 2.1
示例#21
0
 def test_three_agree(self):
     assert di.algmap('three_agree') == 15
示例#22
0
 def test_main_chans(self):
     assert di.algmap('main_chans') == 4
示例#23
0
 def test_cl_dist_guess(self):
     assert di.algmap('cl_dist_guess') == 20
示例#24
0
 def test_bridges(self):
     assert di.algmap('bridges') == 5
示例#25
0
 def test_cl_dist_set(self):
     assert di.algmap('cl_dist_set') == 22
示例#26
0
 def test_known_fdr(self):
     assert di.algmap('known_fdr') == 6
示例#27
0
 def test_cl_ang_rs(self):
     assert di.algmap('cl_ang_rs') == 23.1
示例#28
0
 def test_known_fdr_rs(self):
     assert di.algmap('known_fdr_rs') == 6.1
示例#29
0
 def test_short_no_bktrck(self):
     assert di.algmap('short_no_bktrck') == 25
示例#30
0
 def test_syn_dem(self):
     assert di.algmap('syn_dem') == 10