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)
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)
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)