Source code for mpas_tools.seaice.regrid

import os
from netCDF4 import Dataset
import numpy as np
import numpy.ma as ma
import subprocess
import hashlib

from .mesh import make_mpas_scripfile_on_cells


[docs] def regrid_to_other_mesh(meshFilenameSrc, filenameData, meshFilenameDst, filenameOut, generateWeights=True, weightsFilename=None): # make scrip files print("Make scrip files...") SCRIPFilenameSrc = "scrip_src_tmp.nc" SCRIPFilenameDst = "scrip_dst_tmp.nc" titleSrc = "MPAS grid src" titleDst = "MPAS grid dst" make_mpas_scripfile_on_cells(meshFilenameSrc, SCRIPFilenameSrc, titleSrc) make_mpas_scripfile_on_cells(meshFilenameDst, SCRIPFilenameDst, titleDst) if weightsFilename is None: weightsFilename = os.getcwd() + "/weights_tmp.nc" if generateWeights: # generate weights file print("Generate weights...") _generate_weights_file(SCRIPFilenameSrc, SCRIPFilenameDst, weightsFilename, reuseWeights=False) else: assert os.path.exists(weightsFilename) # load output mesh print("Load output mesh...") meshFile = Dataset(meshFilenameDst, "r") nCells = len(meshFile.dimensions["nCells"]) cellsOnCell = meshFile.variables["cellsOnCell"][:] cellsOnCell[:] = cellsOnCell[:] - 1 meshFile.close() # load data print("Load input data...") fileIn = Dataset(filenameData, "r") iceFractionIn = fileIn.variables["iceFraction"][:] fileIn.close() # regrid print("Regrid array...") iceFractionOut, iceFractionOutMask = _regrid_mpas_array( weightsFilename, iceFractionIn) # output print("Output...") fileOut = Dataset(filenameOut, "w", format="NETCDF3_CLASSIC") fileOut.createDimension("nCells", nCells) iceFractionVar = fileOut.createVariable( "iceFraction", "d", dimensions=["nCells"]) iceFractionVar[:] = iceFractionOut[:] iceFractionMaskVar = fileOut.createVariable( "iceFractionMask", "i", dimensions=["nCells"]) iceFractionMaskVar[:] = iceFractionOutMask[:] fileOut.close()
# ------------------------------------------------------------------------------------ # Private functions # ------------------------------------------------------------------------------------ def _get_weights_filename(inputStrings): hashInput = "" for inputString in inputStrings: hashInput = hashInput + inputString hashOutput = hashlib.md5(hashInput).hexdigest() weightFilename = "weights_%s.nc" % hashOutput return weightFilename def _generate_weights_file( SCRIPFilenameSrc, SCRIPFilenameDst, weightsFilename, reuseWeights): if not reuseWeights or not os.path.isfile(weightsFilename): args = ["ESMF_RegridWeightGen", "--source", SCRIPFilenameSrc, "--destination", SCRIPFilenameDst, "--weight", weightsFilename, "--src_regional", "--dst_regional", "--ignore_unmapped"] subprocess.run(args, check=True) def _load_weights_file(weightsFilename): weights = {} weightsFile = Dataset(weightsFilename, "r") weights["n_s"] = len(weightsFile.dimensions["n_s"]) weights["col"] = weightsFile.variables["col"][:] weights["row"] = weightsFile.variables["row"][:] weights["S"] = weightsFile.variables["S"][:] dst_grid_dims = weightsFile.variables["dst_grid_dims"][:] weights["nRows"] = dst_grid_dims[0] weights["nColumns"] = dst_grid_dims[1] weightsFile.close() return weights def _regrid_obs_array(obsArray, weights): n_s = weights["n_s"] col = weights["col"] row = weights["row"] S = weights["S"] nColumns = weights["nColumns"] nRows = weights["nRows"] nRowsIn = obsArray.shape[0] # get two dimensional grid obsArrayRegrid = ma.zeros((nRows, nColumns)) for i_s in range(0, n_s): iRow = (row[i_s] - 1) / nRows iColumn = (row[i_s] - 1) % nRows iRowIn = (col[i_s] - 1) / nRowsIn iColumnIn = (col[i_s] - 1) % nRowsIn obsArrayRegrid[iRow, iColumn] = obsArrayRegrid[iRow, iColumn] + S[i_s] * obsArray[iRowIn, iColumnIn] return obsArrayRegrid def _regrid_mpas_array(weightsFilename, mpasArrayIn): # load weights print("Load weights...", weightsFilename) weightsFile = Dataset(weightsFilename, "r") n_s = len(weightsFile.dimensions["n_s"]) n_b = len(weightsFile.dimensions["n_b"]) col = weightsFile.variables["col"][:] row = weightsFile.variables["row"][:] S = weightsFile.variables["S"][:] weightsFile.close() # regrid print("Regrid array...") mpasArrayOut = np.zeros(n_b) mpasArrayOutMask = np.zeros(n_b, dtype="i") for i_s in range(0, n_s): mpasArrayOut[row[i_s] - 1] = mpasArrayOut[row[i_s] - 1] + \ S[i_s] * mpasArrayIn[col[i_s] - 1] mpasArrayOutMask[row[i_s] - 1] = 1 return mpasArrayOut, mpasArrayOutMask