def test_build_z(self):
     fpath_mesh = os.path.join(self.dir_cur,
                               'testdata/testmesh/testmesh.gr3')
     fpath_vmesh = os.path.join(self.dir_cur, 'testdata/testmesh/vgrid.in')
     mesh = read_mesh(fpath_mesh, fpath_vmesh)
     z = mesh.build_z()
     desired = np.arange(-100.0, 0.1, 10.0)
     np.testing.assert_allclose(z[0], desired)
     node_i = 5
     desired = np.full((mesh.vmesh.n_vert_levels(), ), -80.0)
     desired[2:] = np.arange(-80.0, 0.1, 10.0)
     np.testing.assert_allclose(z[node_i], desired)
Esempio n. 2
0
def plot_vgrid(hgrid_file, vgrid0_file, vgrid_file, eta, transectfiles):
    from schimpy.lsc2 import default_num_layers, plot_mesh
    from schimpy.schism_vertical_mesh import read_vmesh
    import matplotlib.pylab as plt
    import os.path as ospath

    mesh = read_mesh(hgrid_file)
    x = mesh.nodes[:, 0:2]
    vmesh0 = read_vmesh(vgrid0_file)
    vmesh1 = read_vmesh(vgrid_file)
    h0 = mesh.nodes[:, 2]
    depth = eta + h0

    zcor0 = vmesh0.build_z(mesh, eta)[:, ::-1]
    zcor1 = vmesh1.build_z(mesh, eta)[:, ::-1]
    for transectfile in transectfiles:
        base = ospath.splitext(ospath.basename(transectfile))[0]
        transect = np.loadtxt(transectfile, skiprows=1, delimiter=",")
        path = []
        transx = transect[:, 1:3]
        for p in range(transx.shape[0]):
            path.append(mesh.find_closest_nodes(transx[p, :]))
        #zcorsub = zcor[path,:]
        xx = x[path]
        xpath = np.zeros(xx.shape[0])

        for i in range(1, len(path)):
            dist = np.linalg.norm(xx[i, :] - xx[i - 1, :])
            xpath[i] = xpath[i - 1] + dist
        try:
            fig, (ax0,
                  ax1) = plt.subplots(2, 1,
                                      figsize=(10,
                                               8))  #,sharex=True,sharey=True)
            ax0.set_title(transectfile)
            #plot_mesh(ax0,xpath,zcor0[path,:],0,len(xpath),c="0.5",linewidth=2)
            plot_mesh(ax0, xpath, zcor0[path, :], 0, len(xpath), c="red")
            plot_mesh(ax1, xpath, zcor1[path, :], 0, len(xpath), c="blue")
            ax0.plot(xpath, -h0[path], linewidth=2, c="black")
            ax1.plot(xpath, -h0[path], linewidth=2, c="black")
            plt.savefig(ospath.join("images", base + ".png"))
            plt.show()
        except:
            print("Plotting of grid failed for transectfile: {}".format(
                transectfile))
Esempio n. 3
0
def vgrid_gen(hgrid,
              vgrid_out,
              eta,
              minmaxlayerfile,
              archive_nlayer='out',
              nlayer_gr3='nlayer.gr3'):

    meshfun = BilinearMeshDensity()

    dummydepth = np.linspace(0, 14, 15)
    dummyk = np.linspace(0, 14, 15)
    dummyout = meshfun.depth(dummyk, dummydepth, 0.)

    print("Reading the mesh ")
    mesh = read_mesh(hgrid)
    h0 = mesh.nodes[:, 2]

    places_on = np.array(
        [[626573.490000, 4260349.590000], [626635.000000, 4260391.7]],
        dtype='d')
    dists_on = np.min(scipy.spatial.distance.cdist(mesh.nodes[:, 0:2],
                                                   places_on),
                      axis=1)
    print(np.where(dists_on < 100))

    depth = eta + h0

    print("Reading the polygons...")
    polygons = read_polygons(minmaxlayerfile)
    minlayer = np.ones_like(h0, dtype='int')
    #minlayer[:] = 8 # todo need polygons
    maxlayer = np.ones_like(h0, dtype='int') * 10000
    dztarget = np.full_like(h0, 100., dtype='d')
    print("Assign min/max layers to nodes based on polygons...")
    for polygon in polygons:
        box = [polygon.bounds[i] for i in (0, 2, 1, 3)]
        candidates = mesh.find_nodes_in_box(box)
        n_layers_min = int(polygon.prop['minlayer'])
        n_layers_max = int(polygon.prop['maxlayer'])
        dz0 = float(polygon.prop['dz_target'])
        for node_i in candidates:
            if polygon.intersects(mesh.nodes[node_i, :2]):
                minlayer[node_i] = n_layers_min
                maxlayer[node_i] = n_layers_max
                dztarget[node_i] = dz0

    if np.any(np.isnan(minlayer)):
        print((np.where(np.isnan(minlayer))))
        raise ValueError('Nan value in minlayer')

    if archive_nlayer == 'out':

        dztarget = 0.
        #todo: these will ruin the code
        if fix_minmax:
            minlayer = minlayer * 0 + fixed_min
            maxlayer = maxlayer * 0 + fixed_max  #np.max(maxlayer)

        xdummy = 0.
        nlayer_default = default_num_layers(xdummy, eta, h0, minlayer,
                                            maxlayer, dztarget, meshfun)
        nlayer = nlayer_default

        if archive_nlayer == "out":
            print("writing out number of layers")
            write_mesh(mesh,
                       nlayer_gr3.replace(".gr3", "_default.gr3"),
                       node_attr=nlayer_default)
            write_mesh(mesh, nlayer_gr3, node_attr=nlayer)
            #write_mesh(mesh,nlayer_gr3.replace(".gr3","_dztarget.gr3"),node_attr=dztarget)
    elif archive_nlayer == "in":
        nlayer_mesh = read_mesh(nlayer_gr3)
        #dztarget=read_mesh(nlayer_gr3.replace(".gr3","_dztarget.gr3")).nodes[:,2]
        nlayer = nlayer_mesh.nodes[:, 2].astype('i')
        if int(nlayer_mesh.n_nodes()) != int(mesh.n_nodes()):
            raise ValueError(
                "NLayer gr3 file (%s)\nhas %s nodes, hgrid file (%s) has %s" %
                (nlayer_gr3, nlayer_mesh.n_nodes(), hgrid, mesh.n_nodes()))
    else:
        raise ValueError("archive_nlayer must be one of 'out', 'in' or None")

    # inclusion of minlayer and maxlayer has to do with experiment regenerating # layers after smoothing
    # this will ruin code generally, and if the experiment goes well we need to make sure this is available when archive_nlayer="in"
    if fix_minmax:
        minlayer = nlayer * 0 + fixed_min
        maxlayer = nlayer * 0 + fixed_max  #np.max(maxlayer)

    sigma2, nlayer_revised = gen_sigma(nlayer, minlayer, maxlayer, eta, h0,
                                       mesh, meshfun)
    print("Returned nlayer revised: {}".format(np.max(nlayer_revised)))
    nlayer = nlayer_revised
    nlevel = nlayer + 1

    vmesh = SchismLocalVerticalMesh(flip_sigma(sigma2))
    #vgrid0 = vgrid_out.replace(".in", "_int.in")
    #write_vmesh(vmesh, vgrid0)
    #vmesh1 = SchismLocalVerticalMesh(flip_sigma(sigma1))
    print("Writing vgrid.in output file...")
    write_vmesh(vmesh, vgrid_out)
    print("Done")
Esempio n. 4
0
def convert_mesh(args):
    mesh = read_mesh(args.input)
    write_mesh(mesh, args.output, proj4=args.proj4)
Esempio n. 5
0
def gen_elev2D(hgrid_fpath, outfile, pt_reyes_fpath, monterey_fpath, start,
               end, slr):
    max_gap = 5
    stime = start
    etime = end
    fpath_out = outfile

    #todo: hardwire
    nnode = 83

    tbuf = days(16)
    # convert start time string input to datetime
    sdate = pd.Timestamp(stime)

    if not etime is None:
        # convert start time string input to datetime
        edate = pd.Timestamp(etime)
        bufend = edate + tbuf
    else:
        edate = None
        bufend = None

    # UTM positions of Point Reyes, Monterey, SF
    pos_pr = np.array([502195.03, 4205445.47])
    pos_mt = np.array([599422.84, 4051630.37])
    pos_sf = np.array([547094.79, 4184499.42])

    var_subtidal = np.array([0.938, 0.905, 0.969])  # pr, mt, sf
    var_semi = np.array([0.554, 0.493, 0.580])

    # Assume 45 degree from north-west to south-east
    tangent = np.array([1, -1])
    tangent = tangent / np.linalg.norm(tangent)  # Normalize
    # Rotate 90 cw to get normal vec
    normal = np.array([tangent[1], -tangent[0]])
    print("tangent: {}".format(tangent))
    print("normal: {}".format(normal))

    mt_rel = pos_mt - pos_pr
    x_mt = np.dot(tangent, mt_rel)  # In pr-mt direction
    y_mt = np.dot(normal, mt_rel)  # Normal to x-direction to the

    # Grid
    #todo: what is the difference between this and m = read_grid()??
    mesh = read_mesh(hgrid_fpath)

    ocean_boundary = mesh.boundaries[0]  # First one is ocean

    # Data
    print("Reading Point Reyes...")
    pt_reyes = read_noaa(pt_reyes_fpath,
                         start=sdate - tbuf,
                         end=bufend,
                         force_regular=True)
    pt_reyes.interpolate(limit=max_gap, inplace=True)
    if pt_reyes.isna().any(axis=None):
        raise ValueError("pt_reyes has gaps larger than fill limit")
    ts_pr_subtidal, ts_pr_diurnal, ts_pr_semi, noise = separate_species(
        pt_reyes, noise_thresh_min=150)

    del noise

    print("Reading Monterey...")
    monterey = read_noaa(monterey_fpath,
                         start=sdate - tbuf,
                         end=bufend,
                         force_regular=True)
    monterey.interpolate(limit=max_gap, inplace=True)
    if pt_reyes.isna().any(axis=None):
        raise ValueError("monterey has gaps larger than fill limit")

    if pt_reyes.index.freq != monterey.index.freq:
        raise ValueError(
            "Point Reyes and Monterey time step must be the same in gen_elev2D.py"
        )

    ts_mt_subtidal, ts_mt_diurnal, ts_mt_semi, noise = separate_species(
        monterey, noise_thresh_min=150)
    del noise

    dt = monterey.index.freq / seconds(1)

    print("Done Reading")

    print("Interpolating and subsetting Point Reyes")
    # interpolate_ts(ts_pr_subtidal.window(sdate,edate),step)
    ts_pr_subtidal = ts_pr_subtidal.loc[sdate:edate]
    ts_pr_diurnal = ts_pr_diurnal.loc[sdate:edate]
    # interpolate_ts(ts_pr_semi.window(sdate,edate),step)
    ts_pr_semi = ts_pr_semi.loc[sdate:edate]

    print("Interpolating and subsetting Monterey")
    # interpolate_ts(ts_mt_subtidal.window(sdate,edate),step)
    ts_mt_subtidal = ts_mt_subtidal.loc[sdate:edate]
    # interpolate_ts(ts_mt_diurnal.window(sdate,edate),step)
    ts_mt_diurnal = ts_mt_diurnal.loc[sdate:edate]
    # interpolate_ts(ts_mt_semi.window(sdate,edate),step)
    ts_mt_semi = ts_mt_semi.loc[sdate:edate]

    print("Creating writer")  # requires dt be known for netcdf
    if fpath_out.endswith("th"):
        thwriter = BinaryTHWriter(fpath_out, nnode, None)
    elif fpath_out.endswith("nc"):
        thwriter = NetCDFTHWriter(fpath_out, nnode, sdate, dt)
    else:
        raise ValueError(
            "File extension for output not recognized in file: {}".format(
                fpath_out))

    # Grid
    boundaries = mesh.nodes[ocean_boundary.nodes]
    pos_rel = boundaries[:, :2] - pos_pr

    # x, y in a new principal axes
    x = np.dot(pos_rel, tangent.reshape((2, -1)))
    y = np.dot(pos_rel, normal.reshape((2, -1)))
    theta_x = x / x_mt
    theta_x_comp = 1. - theta_x
    theta_y = y / y_mt
    theta_y_comp = 1. - theta_y

    var_y = (theta_y_comp * var_semi[0] + theta_y * var_semi[1])

    # adj_subtidal_mt = 0.08  # Adjustment in Monterey subtidal signal
    # scaling_diurnal_mt = 0.95 # Scaling of Monterey diurnal signal (for K1/Q1)
    # Used this up to v75
    adj_subtidal_mt = 0.  # Adjustment in Monterey subtidal signal
    scaling_diurnal_mt = 1.  # Scaling of Monterey diurnal signal (for K1/Q1)
    # New trial for LSC2 with v75
    adj_subtidal_mt = -0.07  # Adjustment in Monterey subtidal signal
    scaling_diurnal_mt = 0.95  # Scaling of Monterey diurnal signal (for K1/Q1)
    scaling_semidiurnal_mt = 1.03

    adj_subtidal_mt = -0.14  # Adjustment in Monterey subtidal signal
    scaling_diurnal_mt = 0.90  # Scaling of Monterey diurnal signal (for K1/Q1)
    scaling_semidiurnal_mt = 1.07

    adj_subtidal_mt = 0.10  # Adjustment in Monterey subtidal signal
    scaling_diurnal_mt = 0.90  # Scaling of Monterey diurnal signal (for K1/Q1)
    scaling_semidiurnal_mt = 1.03

    adj_subtidal_mt = 0.10  # Adjustment in Monterey subtidal signal
    scaling_diurnal_mt = 0.97  # Scaling of Monterey diurnal signal (for K1/Q1)
    # Scaling of Point Reyes diurnal signal (for K1/Q1)
    scaling_diurnal_pr = 0.97
    scaling_semidiurnal_mt = 1.025  # Scaling at Monterey semi-diurnal signal

    adj_subtidal_mt = 0.09  # Adjustment in Monterey subtidal signal
    scaling_diurnal_mt = 0.94  # Scaling of Monterey diurnal signal (for K1/Q1)
    # Scaling of Point Reyes diurnal signal (for K1/Q1)
    scaling_diurnal_pr = 0.94
    scaling_semidiurnal_mt = 1.0  # Scaling at Monterey semi-diurnal signal

    if ts_pr_semi.isna().any(axis=None):
        print(ts_pr_semi[ts_pr_semi.isna()])
        raise ValueError('Above times are missing in Point Reyes data')

    for i in range(len(ts_pr_semi)):
        t = float(dt * i)
        # semi-diurnal
        # Scaling
        pr = ts_pr_semi.iloc[i, 0]
        mt = ts_mt_semi.iloc[i, 0] * scaling_semidiurnal_mt

        if np.isnan(pr) or np.isnan(mt):
            raise ValueError("One of values is numpy.nan.")

        eta_pr_side = var_y / var_semi[0] * pr
        eta_mt_side = var_y / var_semi[1] * mt
        eta = eta_pr_side * theta_x_comp + eta_mt_side * theta_x

        # diurnal
        # Interpolate in x-direction only to get a better phase
        pr = ts_pr_diurnal.iloc[i, 0] * scaling_diurnal_pr
        mt = ts_mt_diurnal.iloc[i, 0] * scaling_diurnal_mt
        #if i < 5:
        #    print("yu")
        #    print(pr)
        #    print(mt)

        if np.isnan(pr) or np.isnan(mt):
            raise ValueError("One of values is numpy.nan.")

        eta += pr * theta_x_comp + mt * theta_x

        # Subtidal
        # No phase change in x-direction. Simply interpolate in
        # y-direction.
        pr = ts_pr_subtidal.iloc[i, 0]
        mt = ts_mt_subtidal.iloc[i, 0] + adj_subtidal_mt

        if np.isnan(pr) or np.isnan(mt):
            raise ValueError("One of values is numpy.nan.")
        eta += pr * theta_y_comp + mt * theta_y + slr

        # write data to netCDF file
        thwriter.write_step(i, t, eta)

    # Delete class
    del thwriter