def cost_to_dist(C,g=g,monotonic_search=True):
    """
    given some cost metric C on the cells of the grid,
    use the shortest path from C.min() to C.max() to translate
    cost C into geographic distance.

    monotonic_search: shortest path only traverses edges of increasing
    cost.  Fails if there are local maxima along all paths between
    global min/max.
    """
    c_min=np.argmin(C)
    c_max=np.argmax(C)
    e2c=g.edge_to_cells()
    
    edge_selector=lambda j,direc: (direc*C[e2c[j,0]]<direc*C[e2c[j,1]])

    path=g.shortest_path(c_min, c_max, traverse='cells',edge_selector=edge_selector)
    
    path_xy=g.cells_centroid()[path]
    path_dists=utils.dist_along(path_xy)
    path_C=C[path]

    path_C_orig=path_C.copy()
    path_C.sort() # minor fudging, but this needs to be monotonic
    non_monotonic=np.std(path_C_orig-path_C)/(C[c_max]-C[c_min])
    print("Shortest path deviated from monotonic cost by %e"%non_monotonic)

    dist=np.interp(C, path_C,path_dists)
    return dist
Exemple #2
0
def pnts_to_xA(pnts, datum='MSL'):
    samples = linestring_utils.upsample_linearring(pnts, 5, closed_ring=False)
    z = dem(samples)
    dists = utils.dist_along(samples)
    z0 = ds.z.sel(datum=datum).item()
    depths = (z0 - z).clip(0, np.inf)

    xA = np.trapz(depths, dists)
    return xA
Exemple #3
0
def eval_pnt_pair(pnt_pair, node_depths):
    metrics = {}
    nodes = metrics['nodes'] = [g.select_nodes_nearest(xy) for xy in pnt_pair]
    node_path = metrics['node_path'] = g.shortest_path(nodes[0], nodes[1])
    path_xy = metrics['path_xy'] = g.nodes['x'][node_path]
    path_dist = metrics['path_dist'] = utils.dist_along(path_xy)
    path_z = metrics['path_z'] = node_depths[node_path]

    resamp_xy = linestring_utils.resample_linearring(path_xy,
                                                     2.0,
                                                     closed_ring=False)
    metrics['resamp_xy'] = resamp_xy

    metrics['resamp_z'] = resamp_z = dem(resamp_xy)
    metrics['resamp_dist'] = resamp_dist = utils.dist_along(resamp_xy)

    # edge depths with bedlevtyp3, sampled to higher resolution
    seg_z_typ3 = 0.5 * (path_z[:-1] + path_z[1:])
    resamp_z_typ3 = seg_z_typ3[
        np.searchsorted(path_dist, resamp_dist).clip(1,
                                                     len(path_dist) - 1) - 1]
    metrics['resamp_z_typ3'] = resamp_z_typ3

    metrics['ref_eta'] = ref_eta = 1.0

    A_dem = np.trapz((ref_eta - resamp_z).clip(0, np.inf), resamp_dist)
    L_dem = np.trapz(1. * (ref_eta > resamp_z), resamp_dist)
    A_typ3 = np.trapz((ref_eta - resamp_z_typ3).clip(0, np.inf), resamp_dist)
    L_typ3 = np.trapz(1. * (ref_eta > resamp_z_typ3), resamp_dist)

    metrics['A_dem'] = A_dem
    metrics['L_dem'] = L_dem
    metrics['A_typ3'] = A_typ3
    metrics['L_typ3'] = L_typ3

    metrics['A_err'] = A_typ3 - A_dem
    metrics['L_err'] = L_typ3 - L_dem
    metrics['z_err'] = metrics['A_err'] / (L_dem + 0.1)

    return metrics
Exemple #4
0
 def dem_analysis(self, bathy_fn):
     # 1.0 is from half the current DEM resolution
     pad = 10.0
     bounds = [
         self.section_ls[:, 0].min() - pad,
         self.section_ls[:, 0].max() + pad,
         self.section_ls[:, 1].min() - pad,
         self.section_ls[:, 1].max() + pad
     ]
     self.dem = field.GdalGrid(bathy_fn, geo_bounds=bounds)
     res = 0.5 * self.dem.dx
     self.section_segs = linestring_utils.resample_linearring(
         self.section_ls, res, closed_ring=0)
     self.section_z = self.dem(self.section_segs)
     self.section_s = utils.dist_along(self.section_segs)
    'y_utm':'y_sample',
    'z':'z_ctr',
    'cell':'laydim'
})

##
# Is it really that hard to get ADCPy working?
# no, but it's not the right data model for any of the models
# or the Sontek ADCP.
six.moves.reload_module(xr_transect)

# Do this stuff again, but with the untrim data:
xr_utils.bundle_components(sec,'U',['Ve','Vn'],'en',['E','N'])

sec['U_avg']=xr_transect.depth_avg(sec,'U')
sec['d_sample']=('sample',), utils.dist_along( np.c_[sec.x_sample,sec.y_sample])

##
plt.figure(12).clf()
fig,ax=plt.subplots(num=12)

ax.quiver( sec.x_sample, sec.y_sample,
           sec.U_avg.sel(en='E'), sec.U_avg.sel(en='N'))

##

# Scatter with real z coordinate
plt.figure(13).clf()
fig,axs=plt.subplots(2,1,num=13,sharex=True,sharey=True)

x,y,Cu,Cv=xr.broadcast(sec.d_sample,sec.z_ctr,
Exemple #6
0
#
##

points = thalweg

tri, tsrcs = g.mpl_triangulation(return_sources=True)
tf = tri.get_trifinder()
cells = tf(points[:, 0], points[:, 1])
coeffs = tri.calculate_plane_coefficients(g.nodes['depth'])

z_interp = coeffs[cells, 0] * points[:, 0] + coeffs[
    cells, 1] * points[:, 1] + coeffs[cells, 2]
z_interp = -z_interp  # => elevation

dist = utils.dist_along(thalweg)

##

eta = 1.2 * np.ones_like(z_interp)

# parameters of a
hc = 0.1

plt.figure(1).clf()
fig, ax = plt.subplots(num=1)
ax.plot(dist, z_interp, label='bathy')
ax.plot(dist, eta, label='$\eta$')

ax.legend(loc='lower right')
##
ax.axis('off')
ax.set_position([0, 0, 1, 1])

qsets = []

highlights = [['7A96', 'k', 'Lateral'], ['7ACD', 'g', 'Passive'],
              ['75BA', 'r', 'Pos. Rheotaxis'], ['76AF', 'b', 'Neg. Rheotaxis']]

# Highlight a few tracks with swim quiver
for tag, color, label in highlights:
    track = df.loc[tag, 'track']
    xyuv = track.loc[:, ['x', 'y', 'swim_u', 'swim_v']].values

    ax.plot(xyuv[:, 0], xyuv[:, 1], color=color, lw=2., alpha=0.6, zorder=1)

    d = utils.dist_along(xyuv[:, :2])
    dx = 20.0  # put an arrow every dx meters along track.
    int_xyuv = interp1d(d, xyuv, axis=0)(np.arange(d.min(), d.max(), dx))
    qset = ax.quiver(
        int_xyuv[:, 0],
        int_xyuv[:, 1],
        int_xyuv[:, 2],
        int_xyuv[:, 3],
        angles='xy',
        width=0.007,
        color=color,
        headaxislength=2.5,
        headlength=2.5,
        headwidth=2.5,
        # scale_units='width', scale=7,
        scale_units='xy',
Exemple #8
0
feats = wkb2shp.shp2geom("../../grids/pesca_butano_v03/line_features.shp")
# [N,{x,y}] points from ocean to PC3
thalweg = np.array(feats[feats['name'] == 'thalweg_pesc'][0]['geom'])
#thalweg=linestring_utils.resample_linearring(thalweg,5,closed_ring=0)

## Get a node string that follow thalweg
nodes = g.select_edges_by_polyline(thalweg, return_nodes=True, boundary=False)

##
# plt.figure(1).clf()
# g.plot_edges(color='0.6',lw=0.3)
# plt.plot( g.nodes['x'][nodes,0],
#           g.nodes['x'][nodes,1],color='orange',lw=1.0)

dist = utils.dist_along(g.nodes['x'][nodes])
plt.figure(2).clf()

for ti in range(0, 72, 6):
    ax.plot(dist, -g.nodes['depth'][nodes], color='k', label='bed')
    eta = ms.elev.isel(nSCHISM_hgrid_node=nodes, time=ti).values
    ax.plot(dist, eta, color='b', label='eta')

    for ni, n in enumerate(nodes):
        zcors = ms.zcor.isel(time=ti, nSCHISM_hgrid_node=n).values
        ax.plot(dist[ni] * np.ones_like(zcors), zcors, 'g.')

    # Can I plot a salt transect?
    tran_salt = ms.salt.isel(time=ti, nSCHISM_hgrid_node=nodes)
    tran_z = ms.zcor.isel(time=ti, nSCHISM_hgrid_node=nodes)