Ejemplo n.º 1
0
def __interp2_thread(rx, ry, data, zx, zy, pmap, weight, nx, ny, mask):
    """
    internal routine: 2D interpolation thread for parallel interpolation
    """
    data = np.ma.fix_invalid(data, copy=False)

    # Convolve the water over the land
    ksize = 2 * np.round(
        np.sqrt((nx / np.ma.median(np.ma.diff(rx)))**2 +
                (ny / np.ma.median(np.ma.diff(ry.T)))**2)) + 1
    if ksize < _ksize_range[0]:
        warn("nx or ny values are too small for stable OA, {:f}".format(ksize))
        ksize = _ksize_range[0]
    elif ksize > _ksize_range[1]:
        warn("nx or ny values are too large for stable OA, {:f}".format(ksize))
        ksize = _ksize_range[1]
    data = seapy.convolve_mask(data, ksize=ksize, copy=False)

    # Interpolate the field and return the result
    with timeout(minutes=30):
        res, pm = seapy.oasurf(rx, ry, data, zx, zy, pmap, weight, nx, ny)

    return np.ma.masked_where(np.logical_or(mask == 0,
                                            np.abs(res) > 9e4),
                              res,
                              copy=False)
Ejemplo n.º 2
0
Archivo: lib.py Proyecto: ocefpaf/seapy
def v2rho(v, fill=False):
    """
    Put the v field onto the rho field for the c-grid

    Parameters
    ----------
    v : masked array like
        Input v field
    fill : bool, optional
        Fill the masked data before moving grids

    Returns
    -------
    rho : masked array
    """
    v = np.ma.array(v, copy=False)
    if fill:
        v = seapy.convolve_mask(v, copy=True)
    shp = np.array(v.shape)
    nshp = shp.copy()
    nshp[-2] = nshp[-2] + 1
    fore = np.product([shp[i] for i in np.arange(0, v.ndim - 2)]).astype(int)
    nfld = np.ones([fore, nshp[-2], nshp[-1]])
    nfld[:, 1:-1, :] = 0.5 * \
        (v.reshape([fore, shp[-2], shp[-1]])[:, 0:-1, :].filled(np.nan) +
         v.reshape([fore, shp[-2], shp[-1]])[:, 1:, :].filled(np.nan))
    nfld[:, 0, :] = nfld[:, 1, :] + (nfld[:, 2, :] - nfld[:, 3, :])
    nfld[:, -1, :] = nfld[:, -2, :] + (nfld[:, -2, :] - nfld[:, -3, :])
    return np.ma.fix_invalid(nfld.reshape(nshp), copy=False, fill_value=1e+37)
Ejemplo n.º 3
0
def v2rho(v, fill=False):
    """
    Put the v field onto the rho field for the c-grid

    Parameters
    ----------
    v : masked array like
        Input v field
    fill : bool, optional
        Fill the masked data before moving grids

    Returns
    -------
    rho : masked array
    """
    v = np.ma.array(v, copy=False)
    if fill:
        v = seapy.convolve_mask(v, copy=True)
    shp = np.array(v.shape)
    nshp = shp.copy()
    nshp[-2] = nshp[-2] + 1
    fore = np.product([shp[i] for i in np.arange(0, v.ndim - 2)]).astype(int)
    nfld = np.ones([fore, nshp[-2], nshp[-1]])
    nfld[:, 1:-1, :] = 0.5 * \
        (v.reshape([fore, shp[-2], shp[-1]])[:, 0:-1, :].filled(np.nan) +
         v.reshape([fore, shp[-2], shp[-1]])[:, 1:, :].filled(np.nan))
    nfld[:, 0, :] = nfld[:, 1, :] + (nfld[:, 2, :] - nfld[:, 3, :])
    nfld[:, -1, :] = nfld[:, -2, :] + (nfld[:, -2, :] - nfld[:, -3, :])
    return np.ma.fix_invalid(nfld.reshape(nshp), copy=False, fill_value=1e+37)
Ejemplo n.º 4
0
Archivo: lib.py Proyecto: ocefpaf/seapy
def u2rho(u, fill=False):
    """
    Put the u field onto the rho field for the c-grid

    Parameters
    ----------
    u : masked array like
        Input u field
    fill : bool, optional
        Fill the masked data before moving grids

    Returns
    -------
    rho : masked array
    """
    u = np.ma.array(u, copy=False)
    if fill:
        u = seapy.convolve_mask(u, copy=True)
    shp = np.array(u.shape)
    nshp = shp.copy()
    nshp[-1] = nshp[-1] + 1
    fore = np.product([shp[i] for i in np.arange(0, u.ndim - 1)]).astype(int)
    nfld = np.ones([fore, nshp[-1]])
    nfld[:, 1:-1] = 0.5 * \
        (u.reshape([fore, shp[-1]])[:, 0:-1].filled(np.nan) +
         u.reshape([fore, shp[-1]])[:, 1:].filled(np.nan))
    nfld[:, 0] = nfld[:, 1] + (nfld[:, 2] - nfld[:, 3])
    nfld[:, -1] = nfld[:, -2] + (nfld[:, -2] - nfld[:, -3])
    return np.ma.fix_invalid(nfld.reshape(nshp), copy=False, fill_value=1e+37)
Ejemplo n.º 5
0
def u2rho(u, fill=False):
    """
    Put the u field onto the rho field for the c-grid

    Parameters
    ----------
    u : masked array like
        Input u field
    fill : bool, optional
        Fill the masked data before moving grids

    Returns
    -------
    rho : masked array
    """
    u = np.ma.array(u, copy=False)
    if fill:
        u = seapy.convolve_mask(u, copy=True)
    shp = np.array(u.shape)
    nshp = shp.copy()
    nshp[-1] = nshp[-1] + 1
    fore = np.product([shp[i] for i in np.arange(0, u.ndim - 1)]).astype(int)
    nfld = np.ones([fore, nshp[-1]])
    nfld[:, 1:-1] = 0.5 * \
        (u.reshape([fore, shp[-1]])[:, 0:-1].filled(np.nan) +
         u.reshape([fore, shp[-1]])[:, 1:].filled(np.nan))
    nfld[:, 0] = nfld[:, 1] + (nfld[:, 2] - nfld[:, 3])
    nfld[:, -1] = nfld[:, -2] + (nfld[:, -2] - nfld[:, -3])
    return np.ma.fix_invalid(nfld.reshape(nshp), copy=False, fill_value=1e+37)
Ejemplo n.º 6
0
 def __init__(self, grid, dt, reftime=seapy.default_epoch, ssh_mean=None,
              ssh_error=0.05):
     if ssh_mean is not None:
         self.ssh_mean = seapy.convolve_mask(ssh_mean, ksize=5, copy=True)
     else:
         self.ssh_mean = None
     self.ssh_error = ssh_error
     super().__init__(grid, dt, reftime)
Ejemplo n.º 7
0
 def __init__(self, grid, dt, reftime=seapy.default_epoch, ssh_mean=None,
              ssh_error=0.05):
     if ssh_mean is not None:
         self.ssh_mean = seapy.convolve_mask(ssh_mean, ksize=5, copy=True)
     else:
         self.ssh_mean = None
     self.ssh_error = ssh_error
     super().__init__(grid, dt, reftime)
Ejemplo n.º 8
0
 def __init__(self, grid, dt, reftime=seapy.default_epoch, ssh_mean=None,
              ssh_error=None, repeat=3, provenance="SSH"):
     self.provenance = provenance.upper()
     self.repeat = repeat
     self.ssh_error = ssh_error if ssh_error else _aviso_sla_errors
     if ssh_mean is not None:
         self.ssh_mean = seapy.convolve_mask(ssh_mean, ksize=5, copy=True)
     else:
         self.ssh_mean = None
     super().__init__(grid, dt, reftime)
Ejemplo n.º 9
0
 def __init__(self, grid, dt, reftime=seapy.default_epoch, ssh_mean=None,
              ssh_error=None, repeat=3, provenance="SSH"):
     self.provenance = provenance.upper()
     self.repeat = repeat
     self.ssh_error = ssh_error if ssh_error else _aviso_sla_errors
     if ssh_mean is not None:
         self.ssh_mean = seapy.convolve_mask(ssh_mean, ksize=5, copy=True)
     else:
         self.ssh_mean = None
     super().__init__(grid, dt, reftime)
Ejemplo n.º 10
0
def gen_direct_forcing(his_file, frc_file):
    """
    Generate a direct forcing file from a history (or other ROMS output) file. It requires
    that sustr, svstr, shflux, and ssflux (or swflux) with salt be available. This will
    generate a forcing file that contains: sustr, svstr, swflux, and ssflux.

    Parameters
    ----------
    his_file: string,
      The ROMS history (or other) file(s) (can use wildcards) that contains the fields to
      make forcing from
    frc_file: string,
      The output forcing file

    Returns
    -------
    None: Generates an output file of bulk forcings
    """
    import os

    infile = seapy.netcdf(his_file)
    ref, _ = seapy.roms.get_reftime(infile)

    # Create the output file
    nc = seapy.roms.ncgen.create_frc_direct(frc_file,
                                            eta_rho=infile.dimensions[
                                                'eta_rho'].size,
                                            xi_rho=infile.dimensions[
                                                'xi_rho'].size,
                                            reftime=ref,
                                            clobber=True,
                                            title="Forcing from " +
                                            os.path.basename(his_file))

    # Copy the data over
    nc.variables['SSS'][:] = infile.variables['salt'][:, -1, :, :]
    if 'EminusP' in infile.variables:
        nc.variables['swflux'][:] = infile.variables['EminusP'][:]
    elif 'swflux' in infile.variables:
        nc.variables['swflux'][:] = infile.variables['swflux'][:]
    else:
        nc.variables['swflux'][:] = infile.variables['ssflux'][:] \
            / nc.variables['SSS'][:]
    nc.variables['frc_time'][:] = netCDF4.date2num(netCDF4.num2date(
        infile.variables['ocean_time'][:],
        infile.variables['ocean_time'].units), nc.variables['frc_time'].units)

    for f in seapy.progressbar.progress(("sustr", "svstr", "shflux", "swrad",
                                         "lat_rho", "lat_u", "lat_v",
                                         "lon_rho", "lon_u", "lon_v")):
        if f in infile.variables:
            nc.variables[f][:] = seapy.convolve_mask(
                infile.variables[f][:], copy=False)

    nc.close()
Ejemplo n.º 11
0
def _cgrid_rho_vel(rho, dim, fill):
    """
    Private Method: Compute the u- or v-grid velocity from a rho-field for a c-grid
    """
    rho = np.ma.array(rho, copy=False)
    if fill:
        rho = seapy.convolve_mask(rho, copy=True)
    shp = np.array(rho.shape)
    fore = np.product([shp[i] for i in np.arange(0, dim)])
    aft = np.product([shp[i] for i in np.arange(dim + 1, rho.ndim)])
    nfld = 0.5 * (rho.reshape([fore, shp[dim], aft])[:, 0:-1, :].filled(np.nan) +
                  rho.reshape([fore, shp[dim], aft])[:, 1:, :].filled(np.nan))
    shp[dim] = shp[dim] - 1
    return np.ma.fix_invalid(nfld.reshape(shp), copy=False, fill_value=1e+37)
Ejemplo n.º 12
0
Archivo: lib.py Proyecto: ocefpaf/seapy
def _cgrid_rho_vel(rho, dim, fill):
    """
    Private Method: Compute the u- or v-grid velocity from a rho-field for a c-grid
    """
    rho = np.ma.array(rho, copy=False)
    if fill:
        rho = seapy.convolve_mask(rho, copy=True)
    shp = np.array(rho.shape)
    fore = np.product([shp[i] for i in np.arange(0, dim)]).astype(int)
    aft = np.product([shp[i]
                      for i in np.arange(dim + 1, rho.ndim)]).astype(int)
    nfld = 0.5 * (rho.reshape([fore, shp[dim], aft])[:, 0:-1, :].filled(
        np.nan) + rho.reshape([fore, shp[dim], aft])[:, 1:, :].filled(np.nan))
    shp[dim] = shp[dim] - 1
    return np.ma.fix_invalid(nfld.reshape(shp), copy=False, fill_value=1e+37)
Ejemplo n.º 13
0
def __interp2_thread(rx, ry, data, zx, zy, pmap, weight, nx, ny, mask):
    """
    internal routine: 2D interpolation thread for parallel interpolation
    """
    data = np.ma.fix_invalid(data, copy=False)

    # Convolve the water over the land
    ksize = 2 * np.round(np.sqrt((nx / np.median(np.diff(rx)))**2 +
                                 (ny / np.median(np.diff(ry.T)))**2)) + 1
    if ksize < _ksize_range[0]:
        warn("nx or ny values are too small for stable OA, {:f}".format(ksize))
        ksize = _ksize_range[0]
    elif ksize > _ksize_range[1]:
        warn("nx or ny values are too large for stable OA, {:f}".format(ksize))
        ksize = _ksize_range[1]
    data = seapy.convolve_mask(data, ksize=ksize, copy=False)

    # Interpolate the field and return the result
    with timeout(minutes=30):
        res, pm = seapy.oasurf(rx, ry, data, zx, zy, pmap, weight, nx, ny)

    return np.ma.masked_where(np.logical_or(mask == 0, np.abs(res) > 9e4), res,
                              copy=False)
Ejemplo n.º 14
0
def __interp3_thread(rx, ry, rz, data, zx, zy, zz, pmap,
                     weight, nx, ny, mask, up_factor=1.0, down_factor=1.0):
    """
    internal routine: 3D interpolation thread for parallel interpolation
    """
    # Make the mask 3D
    mask = seapy.adddim(mask, zz.shape[0])
    data = np.ma.fix_invalid(data, copy=False)

    # To avoid extrapolation, we are going to convolve ocean over the land
    # and add a new top and bottom layer that replicates the data of the
    # existing current and top. 1) iteratively convolve until we have
    # filled most of the points, 2) Determine which way the
    # depth goes and add/subtract new layers, and 3) fill in masked values
    # from the layer above/below.
    gradsrc = (rz[0, 1, 1] - rz[-1, 1, 1]) > 0

    # Convolve the water over the land
    ksize = 2 * np.round(np.sqrt((nx / np.median(np.diff(rx)))**2 +
                                 (ny / np.median(np.diff(ry.T)))**2)) + 1
    if ksize < _ksize_range[0]:
        warn("nx or ny values are too small for stable OA, {:f}".format(ksize))
        ksize = _ksize_range[0]
    elif ksize > _ksize_range[1]:
        warn("nx or ny values are too large for stable OA, {:f}".format(ksize))
        ksize = _ksize_range[1]

    # Iterate at most 5 times, but we will hopefully break out before that by
    # checking if we have filled at least 40% of the bottom to be like
    # the surface
    bot = -1 if gradsrc else 0
    top = 0 if gradsrc else -1
    topmask = np.maximum(1, np.ma.count_masked(data[top, :, :]))
    if np.ma.count_masked(data[bot, :, :]) > 0:
        for iter in range(5):
            # Check if we have most everything by checking the bottom
            data = seapy.convolve_mask(data, ksize=ksize + iter, copy=False)
            if topmask / np.maximum(1, np.ma.count_masked(data[bot, :, :])) > 0.4:
                break

    # Now fill vertically
    nrz = np.zeros((data.shape[0] + 2, data.shape[1], data.shape[2]))
    nrz[1:-1, :, :] = rz
    nrz[bot, :, :] = rz[bot, :, :] - 5000
    nrz[top, :, :] = 1

    if not gradsrc:
        # The first level is the bottom
        # factor = down_factor
        levs = np.arange(data.shape[0], 0, -1) - 1
    else:
        # The first level is the top
        # factor = up_factor
        levs = np.arange(0, data.shape[0])

    # Fill in missing values where we have them from the shallower layer
    for k in levs[1:]:
        if np.ma.count_masked(data[k, :, :]) == 0:
            continue
        idx = np.nonzero(np.logical_xor(data.mask[k, :, :],
                                        data.mask[k - 1, :, :]))
        data.mask[k, idx[0], idx[1]] = data.mask[k - 1, idx[0], idx[1]]
        data[k, idx[0], idx[1]] = data[k - 1, idx[0], idx[1]] * down_factor

    # Add upper and lower boundaries
    ndat = np.zeros((data.shape[0] + 2, data.shape[1], data.shape[2]))
    ndat[bot, :, :] = data[bot, :, :].filled(np.nan) * down_factor
    ndat[1:-1, :, :] = data.filled(np.nan)
    ndat[top, :, :] = data[top, :, :].filled(np.nan) * up_factor

    # Interpolate the field and return the result
    with timeout(minutes=30):
        if gradsrc:
            res, pm = seapy.oavol(rx, ry, nrz[::-1, :, :], ndat[::-1, :, :],
                                  zx, zy, zz, pmap, weight, nx, ny)
        else:
            res, pm = seapy.oavol(rx, ry, nrz, ndat, zx, zy, zz,
                                  pmap, weight, nx, ny)

    return np.ma.masked_where(np.logical_or(mask == 0, np.abs(res) > 9e4), res,
                              copy=False)
Ejemplo n.º 15
0
def __interp3_thread(rx, ry, rz, data, zx, zy, zz, pmap,
                     weight, nx, ny, mask, up_factor=1.0, down_factor=1.0):
    """
    internal routine: 3D interpolation thread for parallel interpolation
    """
    # Make the mask 3D
    mask = seapy.adddim(mask, zz.shape[0])
    data = np.ma.fix_invalid(data, copy=False)

    # To avoid extrapolation, we are going to convolve ocean over the land
    # and add a new top and bottom layer that replicates the data of the
    # existing current and top. 1) iteratively convolve until we have
    # filled most of the points, 2) Determine which way the
    # depth goes and add/subtract new layers, and 3) fill in masked values
    # from the layer above/below.
    gradsrc = (rz[0, 1, 1] - rz[-1, 1, 1]) > 0

    # Convolve the water over the land
    ksize = 2 * np.round(np.sqrt((nx / np.median(np.diff(rx)))**2 +
                                 (ny / np.median(np.diff(ry.T)))**2)) + 1
    if ksize < _ksize_range[0]:
        warn("nx or ny values are too small for stable OA, {:f}".format(ksize))
        ksize = _ksize_range[0]
    elif ksize > _ksize_range[1]:
        warn("nx or ny values are too large for stable OA, {:f}".format(ksize))
        ksize = _ksize_range[1]

    # Iterate at most 5 times, but we will hopefully break out before that by
    # checking if we have filled at least 40% of the bottom to be like
    # the surface
    bot = -1 if gradsrc else 0
    top = 0 if gradsrc else -1
    topmask = np.maximum(1, np.ma.count_masked(data[top, :, :]))
    if np.ma.count_masked(data[bot, :, :]) > 0:
        for iter in range(5):
            # Check if we have most everything by checking the bottom
            data = seapy.convolve_mask(data, ksize=ksize + iter, copy=False)
            if topmask / np.maximum(1, np.ma.count_masked(data[bot, :, :])) > 0.4:
                break

    # Now fill vertically
    nrz = np.zeros((data.shape[0] + 2, data.shape[1], data.shape[2]))
    nrz[1:-1, :, :] = rz
    nrz[bot, :, :] = rz[bot, :, :] - 5000
    nrz[top, :, :] = 1

    if not gradsrc:
        # The first level is the bottom
        # factor = down_factor
        levs = np.arange(data.shape[0], 0, -1) - 1
    else:
        # The first level is the top
        # factor = up_factor
        levs = np.arange(0, data.shape[0])

    # Fill in missing values where we have them from the shallower layer
    for k in levs[1:]:
        if np.ma.count_masked(data[k, :, :]) == 0:
            continue
        idx = np.nonzero(np.logical_xor(data.mask[k, :, :],
                                        data.mask[k - 1, :, :]))
        data.mask[k, idx[0], idx[1]] = data.mask[k - 1, idx[0], idx[1]]
        data[k, idx[0], idx[1]] = data[k - 1, idx[0], idx[1]] * down_factor

    # Add upper and lower boundaries
    ndat = np.zeros((data.shape[0] + 2, data.shape[1], data.shape[2]))
    ndat[bot, :, :] = data[bot, :, :].filled(np.nan) * down_factor
    ndat[1:-1, :, :] = data.filled(np.nan)
    ndat[top, :, :] = data[top, :, :].filled(np.nan) * up_factor

    # Interpolate the field and return the result
    with timeout(minutes=30):
        if gradsrc:
            res, pm = seapy.oavol(rx, ry, nrz[::-1, :, :], ndat[::-1, :, :],
                                  zx, zy, zz, pmap, weight, nx, ny)
        else:
            res, pm = seapy.oavol(rx, ry, nrz, ndat, zx, zy, zz,
                                  pmap, weight, nx, ny)

    return np.ma.masked_where(np.logical_or(mask == 0, np.abs(res) > 9e4), res,
                              copy=False)
Ejemplo n.º 16
0
def gen_direct_forcing(his_file, frc_file, cdl=None):
    """
    Generate a direct forcing file from a history (or other ROMS output) file. It requires
    that sustr, svstr, shflux, and ssflux (or swflux) with salt be available. This will
    generate a forcing file that contains: sustr, svstr, swflux, and ssflux.

    Parameters
    ----------
    his_file: string,
      The ROMS history (or other) file(s) (can use wildcards) that contains the fields to
      make forcing from
    frc_file: string,
      The output forcing file
    cdl: string, optional,
        Use the specified CDL file as the definition for the new
        netCDF file.

    Returns
    -------
    None: Generates an output file of bulk forcings
    """
    import os

    infile = seapy.netcdf(his_file)
    ref, _ = seapy.roms.get_reftime(infile)

    # Create the output file
    nc = seapy.roms.ncgen.create_frc_direct(
        frc_file,
        eta_rho=infile.dimensions['eta_rho'].size,
        xi_rho=infile.dimensions['xi_rho'].size,
        reftime=ref,
        clobber=True,
        title="Forcing from " + os.path.basename(his_file),
        cdl=cdl)

    # Copy the data over
    time = seapy.roms.num2date(infile, 'ocean_time')
    nc.variables['frc_time'][:] = seapy.roms.date2num(time, nc, 'frc_time')
    for x in seapy.progressbar.progress(seapy.chunker(range(len(time)), 1000)):
        nc.variables['SSS'][x, :, :] = seapy.convolve_mask(
            infile.variables['salt'][x, -1, :, :], copy=False)
        if 'EminusP' in infile.variables:
            nc.variables['swflux'][x, :, :] = seapy.convolve_mask(
                infile.variables['EminusP'][x, :, :], copy=False) * 86400
        elif 'swflux' in infile.variables:
            nc.variables['swflux'][x, :, :] = seapy.convolve_mask(
                infile.variables['swflux'][x, :, :], copy=False)
        else:
            nc.variables['swflux'][x, :, :] = seapy.convolve_mask(
                infile.variables['ssflux'][x, :, :] /
                nc.variables['SSS'][x, :, :],
                copy=False)

        nc.sync()
        for f in ("sustr", "svstr", "shflux", "swrad"):
            if f in infile.variables:
                nc.variables[f][x, :, :] = seapy.convolve_mask(
                    infile.variables[f][x, :, :], copy=False)
                nc.sync()

    for f in ("lat_rho", "lat_u", "lat_v", "lon_rho", "lon_u", "lon_v"):
        if f in infile.variables:
            nc.variables[f][:] = infile.variables[f][:]
    nc.close()
Ejemplo n.º 17
0
def gen_direct_forcing(his_file, frc_file, cdl=None):
    """
    Generate a direct forcing file from a history (or other ROMS output) file. It requires
    that sustr, svstr, shflux, and ssflux (or swflux) with salt be available. This will
    generate a forcing file that contains: sustr, svstr, swflux, and ssflux.

    Parameters
    ----------
    his_file: string,
      The ROMS history (or other) file(s) (can use wildcards) that contains the fields to
      make forcing from
    frc_file: string,
      The output forcing file
    cdl: string, optional,
        Use the specified CDL file as the definition for the new
        netCDF file.

    Returns
    -------
    None: Generates an output file of bulk forcings
    """
    import os

    infile = seapy.netcdf(his_file)
    ref, _ = seapy.roms.get_reftime(infile)

    # Create the output file
    nc = seapy.roms.ncgen.create_frc_direct(frc_file,
                                            eta_rho=infile.dimensions[
                                                'eta_rho'].size,
                                            xi_rho=infile.dimensions[
                                                'xi_rho'].size,
                                            reftime=ref,
                                            clobber=True,
                                            title="Forcing from " +
                                            os.path.basename(his_file),
                                            cdl=cdl)

    # Copy the data over
    time = seapy.roms.num2date(infile, 'ocean_time')
    nc.variables['frc_time'][:] = seapy.roms.date2num(time, nc, 'frc_time')
    for x in seapy.progressbar.progress(seapy.chunker(range(len(time)), 1000)):
        nc.variables['SSS'][x, :, :] = seapy.convolve_mask(
            infile.variables['salt'][x, -1, :, :], copy=False)
        if 'EminusP' in infile.variables:
            nc.variables['swflux'][x, :, :] = seapy.convolve_mask(
                infile.variables['EminusP'][x, :, :], copy=False) * 86400
        elif 'swflux' in infile.variables:
            nc.variables['swflux'][x, :, :] = seapy.convolve_mask(
                infile.variables['swflux'][x, :, :], copy=False)
        else:
            nc.variables['swflux'][x, :, :] = seapy.convolve_mask(
                infile.variables['ssflux'][x, :, :]
                / nc.variables['SSS'][x, :, :], copy=False)

        nc.sync()
        for f in ("sustr", "svstr", "shflux", "swrad"):
            if f in infile.variables:
                nc.variables[f][x, :, :] = seapy.convolve_mask(
                    infile.variables[f][x, :, :], copy=False)
                nc.sync()

    for f in ("lat_rho", "lat_u", "lat_v", "lon_rho", "lon_u", "lon_v"):
        if f in infile.variables:
            nc.variables[f][:] = infile.variables[f][:]
    nc.close()