def smoothing_Laplacian_rx0(MSK, Hobs, rx0max): """ This program use Laplacian filter. The bathymetry is optimized for a given rx0 factor by doing an iterated sequence of Laplacian filterings. Usage: RetBathy = smoothing_Laplacian_rx0(MSK, Hobs, rx0max) ---MSK(eta_rho,xi_rho) is the mask of the grid 1 for sea 0 for land ---Hobs(eta_rho,xi_rho) is the raw depth of the grid ---rx0max is the target rx0 roughness factor """ eta_rho, xi_rho = Hobs.shape ListNeigh = np.array([[1, 0], [0, 1], [-1, 0], [0, -1]]) RetBathy = Hobs.copy() tol = 0.00001 WeightMatrix = np.zeros((eta_rho, xi_rho)) for iEta in range(eta_rho): for iXi in range(xi_rho): WeightSum = 0 for ineigh in range(4): iEtaN = iEta + ListNeigh[ineigh, 0] iXiN = iXi + ListNeigh[ineigh, 1] if (iEtaN <= eta_rho-1 and iEtaN >= 0 and iXiN <= xi_rho-1 \ and iXiN >= 0 and MSK[iEtaN,iXiN] == 1): WeightSum = WeightSum + 1 WeightMatrix[iEta, iXi] = WeightSum Iter = 1 NumberDones = np.zeros((eta_rho, xi_rho)) while (True): RoughMat = bathy_tools.RoughnessMatrix(RetBathy, MSK) Kbefore = np.where(RoughMat > rx0max) nbPtBefore = np.size(Kbefore, 1) realR = RoughMat.max() TheCorrect = np.zeros((eta_rho, xi_rho)) IsFinished = 1 nbPointMod = 0 AdditionalDone = np.zeros((eta_rho, xi_rho)) for iEta in range(eta_rho): for iXi in range(xi_rho): Weight = 0 WeightSum = 0 for ineigh in range(4): iEtaN = iEta + ListNeigh[ineigh, 0] iXiN = iXi + ListNeigh[ineigh, 1] if (iEtaN <= eta_rho-1 and iEtaN >= 0 and iXiN <= xi_rho-1 \ and iXiN >= 0 and MSK[iEtaN,iXiN] == 1): Weight = Weight + RetBathy[iEtaN, iXiN] AdditionalDone[iEtaN, iXiN] = AdditionalDone[ iEtaN, iXiN] + NumberDones[iEta, iXi] TheWeight = WeightMatrix[iEta, iXi] WeDo = 0 if TheWeight > tol: if RoughMat[iEta, iXi] > rx0max: WeDo = 1 if NumberDones[iEta, iXi] > 0: WeDo = 1 if WeDo == 1: IsFinished = 0 TheDelta = (Weight - TheWeight * RetBathy[iEta, iXi]) / ( 2 * TheWeight) TheCorrect[iEta, iXi] = TheCorrect[iEta, iXi] + TheDelta nbPointMod = nbPointMod + 1 NumberDones[iEta, iXi] = 1 NumberDones = NumberDones + AdditionalDone RetBathy = RetBathy + TheCorrect NewRoughMat = bathy_tools.RoughnessMatrix(RetBathy, MSK) Kafter = np.where(NewRoughMat > rx0max) nbPtAfter = np.size(Kafter, 1) TheProd = (RoughMat > rx0max) * (NewRoughMat > rx0max) nbPtInt = TheProd.sum() if (nbPtInt == nbPtAfter and nbPtBefore == nbPtAfter): eStr = ' no erase' else: eStr = '' NumberDones = np.zeros((eta_rho, xi_rho)) print 'Iteration #', Iter print 'current r=', realR, ' nbPointMod=', nbPointMod, eStr print ' ' Iter = Iter + 1 if (IsFinished == 1): break return RetBathy
def LP_smoothing_rx0_heuristic(MSK, Hobs, rx0max, SignConst, AmpConst): """ This program perform a linear programming method in order to optimize the bathymetry for a fixed factor r. The inequality |H(e)-H(e')| / (H(e)-H(e')) <= r where H(e)=h(e)+dh(e) can be rewritten as two linear inequalities on dh(e) and dh(e'). The optimal bathymetry is obtain by minimising the perturbation P = sum_e(|dh(e)| under the above inequalitie constraintes. In order to reduce the computation time, an heurastic method is used. Usage: NewBathy = LP_smoothing_rx0_heuristic(MSK, Hobs, rx0max, SignConst, AmpConst) ---MSK(eta_rho,xi_rho) is the mask of the grd 1 for sea 0 for land ---Hobs(eta_rho,xi_rho) is the raw depth of the grid ---rx0max is the target rx0 roughness factor ---SignConst(eta_rho,xi_rho) matrix of 0, +1, -1 +1 only bathymetry increase are allowed. -1 only bathymetry decrease are allowed. 0 increase and decrease are allowed. (put 0 if you are indifferent) ---AmpConst(eta_rho,xi_rho) matrix of reals. coefficient alpha such that the new bathymetry should satisfy to |h^{new} - h^{raw}| <= alpha h^{raw} (put 10000 if you are indifferent) """ # the points that need to be modified MSKbad = LP_bathy_tools.GetBadPoints(MSK, Hobs, rx0max) eta_rho, xi_rho = MSK.shape Kdist = 5 Kbad = np.where(MSKbad == 1) nbKbad = np.size(Kbad,1) ListIdx = np.zeros((eta_rho,xi_rho), dtype=np.int) ListIdx[Kbad] = list(range(nbKbad)) ListEdges = [] nbEdge = 0 for iK in range(nbKbad): iEta, iXi = Kbad[0][iK], Kbad[1][iK] ListNeigh = LP_bathy_tools.Neighborhood(MSK, iEta, iXi, 2*Kdist+1) nbNeigh = np.size(ListNeigh, 0) for iNeigh in range(nbNeigh): iEtaN, iXiN = ListNeigh[iNeigh] if (MSKbad[iEtaN,iXiN] == 1): idx = ListIdx[iEtaN,iXiN] if (idx > iK): nbEdge = nbEdge + 1 ListEdges.append([iK, idx]) ListEdges = np.array(ListEdges) ListVertexStatus = LP_bathy_tools.ConnectedComponent(ListEdges, nbKbad) nbColor = ListVertexStatus.max() NewBathy = Hobs.copy() for iColor in range(1,nbColor+1): print('---------------------------------------------------------------') MSKcolor = np.zeros((eta_rho, xi_rho)) K = np.where(ListVertexStatus == iColor) nbK = np.size(K,1) print('iColor = ', iColor, ' nbK = ', nbK) for iVertex in range(nbKbad): if (ListVertexStatus[iVertex,0] == iColor): iEta, iXi = Kbad[0][iVertex], Kbad[1][iVertex] MSKcolor[iEta, iXi] = 1 ListNeigh = LP_bathy_tools.Neighborhood(MSK, iEta, iXi, Kdist) nbNeigh = np.size(ListNeigh, 0) for iNeigh in range(nbNeigh): iEtaN, iXiN = ListNeigh[iNeigh] MSKcolor[iEtaN,iXiN] = 1 K = np.where(MSKcolor == 1) MSKHobs = np.zeros((eta_rho, xi_rho)) MSKHobs[K] = Hobs[K].copy() TheNewBathy = LP_smoothing_rx0(MSKcolor, MSKHobs, rx0max, SignConst, AmpConst) NewBathy[K] = TheNewBathy[K].copy() print('Final obtained bathymetry') RMat = bathy_tools.RoughnessMatrix(NewBathy, MSK) MaxRx0 = RMat.max() print('rx0max = ', rx0max, ' MaxRx0 = ', MaxRx0) return NewBathy
hgrd.lat_rho, checkbounds=False, masked=False, order=0) # Save raw bathymetry. hraw = h.copy() # ROMS depth is positive. hh = -h # Depth deeper than hmin. h = np.where(hh < hmin, hmin, hh) # Smooth the raw bathy using the direct iterative method from Martinho and Batteen (2006). RoughMat = bathy_tools.RoughnessMatrix(h, hgrd.mask_rho) print('Currently, the max roughness value is: ', RoughMat.max()) h = bathy_smoothing.smoothing_Positive_rx0(hgrd.mask_rho, h, rmax) h = bathy_smoothing.smoothing_Laplacian_rx0(hgrd.mask_rho, h, rmax) RoughMat = bathy_tools.RoughnessMatrix(h, hgrd.mask_rho) print(('After the filters, the max roughness value is: ', RoughMat.max())) hgrd.h = h # Vertical levels. vgrd = pyroms.vgrid.s_coordinate_4(h, theta_b, theta_s, Tcline, N, hraw=hraw) # ROMS grid. grd = pyroms.grid.ROMS_Grid(grd_name, hgrd, vgrd) # Write grid to netcdf file. pyroms.grid.write_ROMS_grid(grd, grd_final)
def LP_smoothing_rx0(MSK, Hobs, rx0max, SignConst, AmpConst): """ This program perform a linear programming method in order to optimize the bathymetry for a fixed factor r. The inequality |H(e)-H(e')| / (H(e)-H(e')) <= r where H(e)=h(e)+dh(e) can be rewritten as two linear inequalities on dh(e) and dh(e'). The optimal bathymetry is obtain by minimising the perturbation P = sum_e(|dh(e)| under the above inequalitie constraintes. Usage: NewBathy = LP_smoothing_rx0(MSK, Hobs, rx0max, SignConst, AmpConst) ---MSK(eta_rho,xi_rho) is the mask of the grd 1 for sea 0 for land ---Hobs(eta_rho,xi_rho) is the raw depth of the grid ---rx0max is the target rx0 roughness factor ---SignConst(eta_rho,xi_rho) matrix of 0, +1, -1 +1 only bathymetry increase are allowed. -1 only bathymetry decrease are allowed. 0 increase and decrease are allowed. (put 0 if you are indifferent) ---AmpConst(eta_rho,xi_rho) matrix of reals. coefficient alpha such that the new bathymetry should satisfy to |h^{new} - h^{raw}| <= alpha h^{raw} (put 10000 if you are indifferent) """ eta_rho, xi_rho = MSK.shape iList, jList, sList, Constant = LP_bathy_tools.GetIJS_rx0(MSK, Hobs, rx0max) iListApp, jListApp, sListApp, ConstantApp = LP_bathy_tools.GetIJS_maxamp(MSK, Hobs, AmpConst) iList, jList, sList, Constant = LP_bathy_tools.MergeIJS_listings(iList, jList, sList, Constant, iListApp, jListApp, sListApp, ConstantApp) iListApp, jListApp, sListApp, ConstantApp = LP_bathy_tools.GetIJS_signs(MSK, SignConst) iList, jList, sList, Constant = LP_bathy_tools.MergeIJS_listings(iList, jList, sList, Constant, iListApp, jListApp, sListApp, ConstantApp) TotalNbVert = int(MSK.sum()) ObjectiveFct = np.zeros((2*TotalNbVert,1)) for iVert in range(TotalNbVert): ObjectiveFct[TotalNbVert+iVert,0] = 1 ValueFct, ValueVar, testfeasibility = LP_tools.SolveLinearProgram(iList, jList, sList, Constant, ObjectiveFct) if (testfeasibility == 0): NewBathy = NaN * np.ones((eta_rho,xi_rho)) raise ValueError('Feasibility test failed. testfeasibility = 0.') correctionBathy = np.zeros((eta_rho,xi_rho)) nbVert = 0 for iEta in range(eta_rho): for iXi in range(xi_rho): if (MSK[iEta,iXi] == 1): correctionBathy[iEta,iXi] = ValueVar[nbVert] nbVert = nbVert + 1 NewBathy = Hobs + correctionBathy RMat = bathy_tools.RoughnessMatrix(NewBathy, MSK) MaxRx0 = RMat.max() print('rx0max = ', rx0max, ' MaxRx0 = ', MaxRx0) return NewBathy