diff --git a/docs/grid.md b/docs/grid.md index f76a2d0b..452b7727 100644 --- a/docs/grid.md +++ b/docs/grid.md @@ -95,17 +95,18 @@ Calculate the missing horizontal grid variables and add them to grid. @author Ryan Patmore @author Anthony Wise -## *class* grid.zgr.Z_Grid(zgr_file, name_map_file, hgr_type, e_dict, logger, dst=1) +## *class* grid.zgr.Z_Grid(zgr_file, zgr_type, name_map_file, hgr_type, e_dict, logger, dst=1) > Bases: `object`
-### *method* \_\_init\_\_(zgr_file, name_map_file, hgr_type, e_dict, logger, dst=1) +### *method* \_\_init\_\_(zgr_file, zgr_type, name_map_file, hgr_type, e_dict, logger, dst=1) Master depth class. > ### Parameters
> zgr_file (str) : string of file for loading zgr data
+> zgr_type (str) : zgr type from namelist zco, zps or sco
> name_map_file (str) : string of file for mapping variable names
> hgr_type (str) : horizontal grid type
> e_dict (dict) : dictionary of e1 and e2 scale factors
@@ -116,7 +117,7 @@ Master depth class. > Depth (object) : Depth object
-### *method* find_zgrid_type() +### *method* find_zgrid_type(zgr_type) Find out what type of vertical grid is provided zco, zps or sigma levels (sco). diff --git a/docs/index.md b/docs/index.md index 455ec11a..2f185d7a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -59,6 +59,7 @@ The changes relative to the previous version (0.3.0) are: - Bug fix for 90 boundaries that meet diagonally to produce a 90 degree corner. - Some unit tests have been added and full integration tests. - Documentation has been updated and restructured. +- sn_src_zgr_type and sn_dst_zgr_type are defined in the namelist.bdy **There is a new library for generating NEMO initial conditions called pyIC.** pyIC can be found at: [https://github.com/NOC-MSM/pyIC](https://github.com/NOC-MSM/pyIC) @@ -198,6 +199,8 @@ Here we will summarise the main variables that will need changing to get started #### Key Namelist Parameters +- `sn_src_zgr_type` +- `sn_dst_zgr_type` - `sn_src_hgr` - `sn_src_zgr` - `sn_dst_hgr` @@ -211,6 +214,11 @@ Here we will summarise the main variables that will need changing to get started - `ln_zinterp` - `nn_rimwidth` +##### Vertical grid type + +- **`sn_src_zgr_type`**: The source vertical coordinate type. This can be 'zco', 'zps' or 'sco'. 'zco' for the z-coordinate full step which are not spatially verying, 'zps' for z-coordinate - partial steps which have some adjustment in height near the seabed and 'sco' for sigma or hybrid z-sigma-coordinates which get thicker or thinner depending on the bathymetry. +- **`sn_dst_zgr_type`**: Same as `sn_src_zgr_type` but for destination vertical coordinate type. + ##### File Paths Directory paths in bdy file can be relative or absolute. @@ -448,6 +456,10 @@ Summary of minimum requirements: "e3uw" = * vertical scale factor distance between w-levels on u-grid (dims [t, z, y, x]) "e3vw" = * vertical scale factor distance between w-levels on v-grid (dims [t, z, y, x]) "e3fw" = * vertical scale factor distance between w-levels on f-grid (dims [t, z, y, x]) + +"ln_zco" = * flag for zco vertical coordinates 1 for true, 0 for false often provided in domain_cfg.nc +"ln_zps" = * flag for zps vertical coordinates 1 for true, 0 for false often provided in domain_cfg.nc +"ln_sco" = * flag for sco vertical coordinates 1 for true, 0 for false often provided in domain_cfg.nc ``` ### Step 5: Running pyBDY @@ -473,6 +485,19 @@ The example child (destination) here is a regional NEMO model that covers the In Below is excerpts from an example *namelist.bdy*. +This sections tells pybdy the vertical coordinate type of the parent (src) and child (dst). In this case the the parent is on constant z-levels and the child is on spatially varying sigma-levels. + +``` +!------------------------------------------------------------------------------ +! vertical coordinate +!------------------------------------------------------------------------------ + sn_src_zgr_type = 'zco' ! vertical coordinate type: 'zco', 'zps' or 'sco' + sn_dst_zgr_type = 'sco' ! vertical coordinate type: 'zco', 'zps' or 'sco' + ! 'zco' is z-coordinate - full steps + ! 'zps' is z-coordinate - partial steps + ! 'sco' is s- or hybrid z-s-coordinate +``` + Here the file paths are set. These can be absolute (i.e. starting with "/") or relative (i.e. starting with "./"). For help with what variables are needed in these files see [How to use pyBDY :student:](#how-to-use-pybdy-student). In the example case, the bathmetry file needed to be calculated before running pybdy. It may also be the case that you need to calculate variables like gdept for the sn_src_zgr file fore running pybdy. For setting up the grid_name_map.json see the JSON file example section below. ``` @@ -637,7 +662,10 @@ This is an example .json file: *grid_name_map.json*. It specifise the names of v "e3f": "e3f", "e3uw": "e3uw", "e3vw": "e3vw", - "e3fw": "e3fw" + "e3fw": "e3fw", + "ln_zco": "ln_zco", + "ln_zps": "ln_zps", + "ln_sco": "ln_sco" }, "dst_variable_map": { "nav_lon": "nav_lon", @@ -674,7 +702,10 @@ This is an example .json file: *grid_name_map.json*. It specifise the names of v "e3f": "e3f_0", "e3uw": "e3uw_0", "e3vw": "e3vw_0", - "e3fw": "e3fw" + "e3fw": "e3fw", + "ln_zco": "ln_zco", + "ln_zps": "ln_zps", + "ln_sco": "ln_sco" } } ``` diff --git a/docs/pybdy.gui.md b/docs/pybdy.gui.md index 9dbc1581..125f4921 100644 --- a/docs/pybdy.gui.md +++ b/docs/pybdy.gui.md @@ -17,24 +17,24 @@ Initialise an APLpyNormalize instance. > Optional Keyword Parametersument
> *vmin*: [ None | float ]
-> : Minimum pixel value to use for the scaling.
+> : Minimum pixel value to use for the scaling.
> *vmax*: [ None | float ]
-> : Maximum pixel value to use for the scaling.
+> : Maximum pixel value to use for the scaling.
> *stretch*: [ ‘linear’ | ‘log’ | ‘sqrt’ | ‘arcsinh’ | ‘power’ ]
-> : The stretch function to use (default is ‘linear’).
+> : The stretch function to use (default is ‘linear’).
> *vmid*: [ None | float ]
-> : Mid-pixel value used for the log and arcsinh stretches. If
-> set to None, a default value is picked.
+> : Mid-pixel value used for the log and arcsinh stretches. If
+> set to None, a default value is picked.
> *exponent*: [ float ]
-> : if self.stretch is set to ‘power’, this is the exponent to use.
+> : if self.stretch is set to ‘power’, this is the exponent to use.
> *clip*: [ True | False ]
-> : If clip is True and the given value falls outside the range,
-> the returned value will be 0 or 1, whichever is closer.
+> : If clip is True and the given value falls outside the range,
+> the returned value will be 0 or 1, whichever is closer.
### *method* inverse(value) @@ -45,7 +45,7 @@ data value. value -> : Normalized value.
+> \: Normalized value.
# pybdy.gui.nemo_bdy_input_window module @@ -286,7 +286,7 @@ Run callback for the dropdown in the settings. Run callback when the True/False dropdown for the settings, -> : which has a boolean value, is changed.
+> \: which has a boolean value, is changed.
### *method* init_ui() @@ -494,7 +494,7 @@ Refresh the canvas. This method looks at the list of points available and depending on the number of points -> : in the list creates a point or line or a polygon and draws them.
+> \: in the list creates a point or line or a polygon and draws them.
### *method* reset() diff --git a/docs/pybdy.md b/docs/pybdy.md index 90b6455b..aa93a215 100644 --- a/docs/pybdy.md +++ b/docs/pybdy.md @@ -445,7 +445,7 @@ Interpolate source data onto destination vertical levels. > sc_bdy (np.array) : souce data [nz_sc, nbdy, 9]
> dst_dep (np.array) : the depth of the destination grid chunk [nz, nbdy]
> bdy_bathy (np.array): the destination grid bdy points bathymetry
-> z_ind (np.array) : the indices of the sc depth above and below bdy
+> z_ind (np.array) : the indices of the sc depth above and below bdy point
> z_dist (np.array) : the distance weights of the selected points
> num_bdy (int) : number of boundary points in chunk
> zinterp (bool) : vertical interpolation flag
@@ -498,8 +498,8 @@ weightings for vector quantities. > DstCoord (obj) : destination grid information
> Grid (dict) : containing grid type ‘t’, ‘u’, ‘v’ and source time
> var_name (list) : netcdf file variable names (str)
-> years (list) : years to extract (default [1979])
-> months (list) : months to extract (default [11])
+> grd (str) : grid to process ‘t’, ‘u’, ‘v’
+> pair (str) : None or ‘uv’
> ### Returns
diff --git a/docs/pybdy.tide.md b/docs/pybdy.tide.md index e113fcf0..798e6fb7 100644 --- a/docs/pybdy.tide.md +++ b/docs/pybdy.tide.md @@ -71,15 +71,15 @@ Convert the input contituents to index in the tidal constituents. > ### Parameters
> constituents: The list of constituents available from the source data
-> : e.g. TPXO: [‘m2’, ‘s2’, ‘n2’, ‘k2’, ‘k1’, ‘o1’, ‘p1’, ‘q1’, ‘mf’, ‘mm’, ‘m4’, ‘ms4’, ‘mn4’]
+> : e.g. TPXO: [‘m2’, ‘s2’, ‘n2’, ‘k2’, ‘k1’, ‘o1’, ‘p1’, ‘q1’, ‘mf’, ‘mm’, ‘m4’, ‘ms4’, ‘mn4’]
> inputcons: The dictionary of constituents from the namelist with their numbers
-> : e.g. {‘1’: “‘M2’”, ‘3’: “‘K2’”, ‘2’: “‘S2’”, ‘4’: “‘M4’”}
+> : e.g. {‘1’: “‘M2’”, ‘3’: “‘K2’”, ‘2’: “‘S2’”, ‘4’: “‘M4’”}
> ### Returns
> retindx: The indices (relative to the source data list) of the dictionary items from the namelist
-> : e.g. [ 0. 3. 1. 10.]
+> : e.g. [ 0. 3. 1. 10.]
## pybdy.tide.nemo_bdy_tide3.nemo_bdy_tide_rot(setup, DstCoord, Grid_T, Grid_U, Grid_V, comp) @@ -140,7 +140,7 @@ TPXO9v5 only carries the bathymetry variable > return: mask dataarray.
> Useage:
-> : self.grid[mask_name] = generate_landmask(bathy_name)
+> : self.grid[mask_name] = generate_landmask(bathy_name)
### *method* interpolate_constituents(nc_dataset, real_var_name, img_var_name, lon_var_name, lat_var_name, lon, lat, height_data=None, maskname=None) diff --git a/inputs/grid_name_map.json b/inputs/grid_name_map.json index 5dd25411..df2f54d1 100644 --- a/inputs/grid_name_map.json +++ b/inputs/grid_name_map.json @@ -40,7 +40,10 @@ "e3f": "e3f", "e3uw": "e3uw", "e3vw": "e3vw", - "e3fw": "e3fw" + "e3fw": "e3fw", + "ln_zco": "ln_zco", + "ln_zps": "ln_zps", + "ln_sco": "ln_sco" }, "dst_variable_map": { "nav_lon": "nav_lon", @@ -77,6 +80,9 @@ "e3f": "e3f", "e3uw": "e3uw", "e3vw": "e3vw", - "e3fw": "e3fw" + "e3fw": "e3fw", + "ln_zco": "ln_zco", + "ln_zps": "ln_zps", + "ln_sco": "ln_sco" } } diff --git a/inputs/grid_name_map_readme.txt b/inputs/grid_name_map_readme.txt index 73fa017f..55383afe 100644 --- a/inputs/grid_name_map_readme.txt +++ b/inputs/grid_name_map_readme.txt @@ -75,3 +75,7 @@ In all cases "t" should be size 1. Pybdy does not deal with time varying grids. "e3uw" = * vertical scale factor distance between w-levels on u-grid (dims [t, z, y, x]) "e3vw" = * vertical scale factor distance between w-levels on v-grid (dims [t, z, y, x]) "e3fw" = * vertical scale factor distance between w-levels on f-grid (dims [t, z, y, x]) + +"ln_zco" = * flag for zco vertical coordinates 1 for true, 0 for false often provided in domain_cfg.nc +"ln_zps" = * flag for zps vertical coordinates 1 for true, 0 for false often provided in domain_cfg.nc +"ln_sco" = * flag for sco vertical coordinates 1 for true, 0 for false often provided in domain_cfg.nc diff --git a/inputs/namelist_local.bdy b/inputs/namelist_local.bdy index 0d1db96a..8fd4033e 100644 --- a/inputs/namelist_local.bdy +++ b/inputs/namelist_local.bdy @@ -9,6 +9,15 @@ !! !!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +!------------------------------------------------------------------------------ +! vertical coordinate +!------------------------------------------------------------------------------ + sn_src_zgr_type = 'zps' ! vertical coordinate type: 'zco', 'zps' or 'sco' + sn_dst_zgr_type = 'zps' ! vertical coordinate type: 'zco', 'zps' or 'sco' + ! 'zco' is z-coordinate - full steps + ! 'zps' is z-coordinate - partial steps + ! 'sco' is s- or hybrid z-s-coordinate + !------------------------------------------------------------------------------ ! grid information !------------------------------------------------------------------------------ diff --git a/inputs/namelist_remote.bdy b/inputs/namelist_remote.bdy index b9c60947..165cb66f 100644 --- a/inputs/namelist_remote.bdy +++ b/inputs/namelist_remote.bdy @@ -9,6 +9,15 @@ !! !!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +!------------------------------------------------------------------------------ +! vertical coordinate +!------------------------------------------------------------------------------ + sn_src_zgr_type = 'sco' ! vertical coordinate type: 'zco', 'zps' or 'sco' + sn_dst_zgr_type = 'sco' ! vertical coordinate type: 'zco', 'zps' or 'sco' + ! 'zco' is z-coordinate - full steps + ! 'zps' is z-coordinate - partial steps + ! 'sco' is s- or hybrid z-s-coordinate + !------------------------------------------------------------------------------ ! grid information !------------------------------------------------------------------------------ diff --git a/src/grid/zgr.py b/src/grid/zgr.py index 669f130e..efd816e3 100644 --- a/src/grid/zgr.py +++ b/src/grid/zgr.py @@ -32,13 +32,16 @@ class Z_Grid: - def __init__(self, zgr_file, name_map_file, hgr_type, e_dict, logger, dst=1): + def __init__( + self, zgr_file, zgr_type, name_map_file, hgr_type, e_dict, logger, dst=1 + ): """ Master depth class. Parameters ---------- zgr_file (str) : string of file for loading zgr data + zgr_type (str) : zgr type from namelist zco, zps or sco name_map_file (str) : string of file for mapping variable names hgr_type (str) : horizontal grid type e_dict (dict) : dictionary of e1 and e2 scale factors @@ -84,15 +87,15 @@ def __init__(self, zgr_file, name_map_file, hgr_type, e_dict, logger, dst=1): "e3uw", "e3vw", "e3fw", + "ln_zco", + "ln_zps", + "ln_sco", ] - # "gdepw_0", - # "e3t_0", - # "e3w_0", self.get_vars(vars_want) # Work out what sort of source grid we have - self.find_zgrid_type() + self.find_zgrid_type(zgr_type) # Fill in missing variables we need for the grid type missing_vars = sorted(list(set(vars_want) - set(self.var_list))) @@ -138,59 +141,36 @@ def get_vars(self, vars_want): nc.close() self.var_list = list(self.grid.keys()) - def find_zgrid_type(self): + def find_zgrid_type(self, zgr_type): """Find out what type of vertical grid is provided zco, zps or sigma levels (sco).""" - if ("gdept" not in self.var_list) & ("gdept_0" not in self.var_list): - if "e3t" in self.var_list: - self.grid["gdept"] = np.cumsum(self.grid["e3t"], axis=1) - self.var_list.append("gdept") - else: - raise Exception("No gdept or gdept_0 variable present in zgr file.") - - if "gdept" not in self.var_list: - self.grid_type = "zco" + if zgr_type in ["zco", "zps", "sco"]: + # Check namelist for user specified zgr type + self.grid_type = zgr_type else: - if "mbathy" not in self.var_list: - raise Exception("No mbathy variable present in zgr file.") - # Could still be z, z-partial-step (zps) or sigma - # "z" - Check if all levels are equal - x_diff = np.diff(self.grid["gdept"], axis=3).sum() == 0 - y_diff = np.diff(self.grid["gdept"], axis=2).sum() == 0 - dep_test_z = x_diff & y_diff - - # "zps" - Select levels 2 above bathy to remove partial steps. - # Then check if levels of deepest profile are equal to all levels - z_ind = np.indices(self.grid["gdept"].shape)[1] - m_tile = np.tile(self.grid["mbathy"], (self.grid["gdept"].shape[1], 1, 1))[ - np.newaxis, ... - ] - mask_bottom = z_ind >= (m_tile - 2) - dep_mask = np.ma.masked_where(mask_bottom, self.grid["gdept"]) - - sel = np.nonzero(np.ma.max(dep_mask) == dep_mask) - dep_deepest = np.tile( - dep_mask[sel[0][0], :, sel[2][0], sel[3][0]], - (self.grid["gdept"].shape[3], self.grid["gdept"].shape[2], 1), - ).T[np.newaxis, :, :, :] - dep_test_zps = ( - dep_deepest[mask_bottom is False] - == self.grid["gdept"][mask_bottom is False] - ) - - # Check if all levels are inside the bathy anywhere - lev_deepest = np.ma.max(self.grid["mbathy"]) - dep_test_sigma = lev_deepest >= (self.grid["gdept"].shape[1] - 1) - if dep_test_z: - # z-level - self.grid_type = "zco" - elif dep_test_zps.all(): - # z-partial-step - self.grid_type = "zps" - elif dep_test_sigma: - # sigma-level - self.grid_type = "sco" - else: - raise Exception("Unknown/unaccounted for vertical grid type.") + raise Exception("zgr_type not specified in namelist or file.") + + file_zgr = "" + if "ln_zco" in self.var_list: + # Check the zgr netcdf file for ln flags + if self.grid["ln_zco"]: + file_zgr = "zco" + elif "ln_zps" in self.var_list: + if self.grid["ln_zps"]: + file_zgr = "zps" + elif "ln_sco" in self.var_list: + if self.grid["ln_sco"]: + file_zgr = "sco" + + if file_zgr != "": + if file_zgr != self.grid_type: + print( + "Warning: the vertical grid in the zgr file (" + + file_zgr + + ") does not match the user defined" + + "zgr type in the namelist (" + + self.grid_type + + ")" + ) self.logger.info("Vertical grid is type: " + self.grid_type) diff --git a/src/pybdy/nemo_bdy_extr_assist.py b/src/pybdy/nemo_bdy_extr_assist.py index b11dc3c0..a264d68a 100644 --- a/src/pybdy/nemo_bdy_extr_assist.py +++ b/src/pybdy/nemo_bdy_extr_assist.py @@ -332,6 +332,7 @@ def flood_fill(sc_bdy, isslab, logger): sc_shape = sc_bdy.shape for i in range(sc_shape[0]): + # Check if layer centre-point has both nans and values while np.isnan(sc_bdy[i, :, 0]).any() & (~np.isnan(sc_bdy[i, :, 0])).any(): # Flood sc land horizontally within the chunk for the centre point. # This may not be perfect but better than filling with zeros @@ -351,6 +352,12 @@ def flood_fill(sc_bdy, isslab, logger): np.isnan(sc_bdy[:, :, 0]) ] + # Replace nans around centre-point with value. + sc_nan = np.isnan(sc_bdy) + sc_bdy[:, :, 1:][sc_nan[:, :, 1:]] = np.tile(sc_bdy[:, :, 0:1], (1, 1, 8))[ + sc_nan[:, :, 1:] + ] + return sc_bdy @@ -363,7 +370,7 @@ def interp_vertical(sc_bdy, dst_dep, bdy_bathy, z_ind, z_dist, num_bdy, zinterp= sc_bdy (np.array) : souce data [nz_sc, nbdy, 9] dst_dep (np.array) : the depth of the destination grid chunk [nz, nbdy] bdy_bathy (np.array): the destination grid bdy points bathymetry - z_ind (np.array) : the indices of the sc depth above and below bdy + z_ind (np.array) : the indices of the sc depth above and below bdy point z_dist (np.array) : the distance weights of the selected points num_bdy (int) : number of boundary points in chunk zinterp (bool) : vertical interpolation flag diff --git a/src/pybdy/nemo_bdy_extr_tm3.py b/src/pybdy/nemo_bdy_extr_tm3.py index 76bff9eb..0126b05d 100644 --- a/src/pybdy/nemo_bdy_extr_tm3.py +++ b/src/pybdy/nemo_bdy_extr_tm3.py @@ -61,8 +61,8 @@ def __init__(self, setup, SourceCoord, DstCoord, Grid, var_nam, grd, pair): DstCoord (obj) : destination grid information Grid (dict) : containing grid type 't', 'u', 'v' and source time var_name (list) : netcdf file variable names (str) - years (list) : years to extract (default [1979]) - months (list) : months to extract (default [11]) + grd (str) : grid to process 't', 'u', 'v' + pair (str) : None or 'uv' Returns ------- @@ -982,6 +982,7 @@ def extract_month(self, year, month): self.logger.info( "%s en to %s %s", self.rot_dir, self.rot_dir, dst_bdy.shape ) + dst_bdy = rot_rep( dst_bdy, dst_bdy_2, diff --git a/src/pybdy/nemo_bdy_zgrv2.py b/src/pybdy/nemo_bdy_zgrv2.py index 1dee6c46..376b73a5 100644 --- a/src/pybdy/nemo_bdy_zgrv2.py +++ b/src/pybdy/nemo_bdy_zgrv2.py @@ -169,9 +169,9 @@ def get_bdy_depths(DstCoord, bdy_i, grd): bdy_tz = np.ma.zeros((m_t.shape[0], len(g_ind))) bdy_e3 = np.ma.zeros((m_e.shape[0], len(g_ind))) for k in range(m_w.shape[0]): - tmp_w = np.ma.masked_where(mbathy + 1 < k + 1, m_w[k, :, :]) - tmp_t = np.ma.masked_where(mbathy < k + 1, m_t[k, :, :]) - tmp_e = np.ma.masked_where(mbathy < k + 1, m_e[k, :, :]) + tmp_w = np.ma.masked_where(mbathy + 1 < (k + 1), m_w[k, :, :]) + tmp_t = np.ma.masked_where(mbathy < (k + 1), m_t[k, :, :]) + tmp_e = np.ma.masked_where(mbathy < (k + 1), m_e[k, :, :]) tmp_w = tmp_w.flatten("F") tmp_t = tmp_t.flatten("F") diff --git a/src/pybdy/profiler.py b/src/pybdy/profiler.py index 4a4eabac..418853c1 100644 --- a/src/pybdy/profiler.py +++ b/src/pybdy/profiler.py @@ -107,6 +107,7 @@ def process_bdy(setup_filepath=0, mask_gui=False): DstCoord.hgr = hgr.H_Grid(settings["dst_hgr"], settings["nme_map"], logger, dst=1) DstCoord.zgr = zgr.Z_Grid( settings["dst_zgr"], + settings["dst_zgr_type"], settings["nme_map"], DstCoord.hgr.grid_type, DstCoord.hgr.grid, @@ -175,6 +176,7 @@ def process_bdy(setup_filepath=0, mask_gui=False): ) SourceCoord.zgr = zgr.Z_Grid( settings["src_zgr"], + settings["src_zgr_type"], settings["nme_map"], SourceCoord.hgr.grid_type, SourceCoord.hgr.grid, diff --git a/tests/data/grid_name_map.json b/tests/data/grid_name_map.json index 5dd25411..df2f54d1 100644 --- a/tests/data/grid_name_map.json +++ b/tests/data/grid_name_map.json @@ -40,7 +40,10 @@ "e3f": "e3f", "e3uw": "e3uw", "e3vw": "e3vw", - "e3fw": "e3fw" + "e3fw": "e3fw", + "ln_zco": "ln_zco", + "ln_zps": "ln_zps", + "ln_sco": "ln_sco" }, "dst_variable_map": { "nav_lon": "nav_lon", @@ -77,6 +80,9 @@ "e3f": "e3f", "e3uw": "e3uw", "e3vw": "e3vw", - "e3fw": "e3fw" + "e3fw": "e3fw", + "ln_zco": "ln_zco", + "ln_zps": "ln_zps", + "ln_sco": "ln_sco" } } diff --git a/tests/data/namelist_zz_end_to_end.bdy b/tests/data/namelist_zz_end_to_end.bdy index 1c909d80..e3e5b72a 100644 --- a/tests/data/namelist_zz_end_to_end.bdy +++ b/tests/data/namelist_zz_end_to_end.bdy @@ -9,6 +9,15 @@ !! !!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +!------------------------------------------------------------------------------ +! vertical coordinate +!------------------------------------------------------------------------------ + sn_src_zgr_type = 'zco' ! vertical coordinate type: 'zco', 'zps' or 'sco' + sn_dst_zgr_type = 'zco' ! vertical coordinate type: 'zco', 'zps' or 'sco' + ! 'zco' is z-coordinate - full steps + ! 'zps' is z-coordinate - partial steps + ! 'sco' is s- or hybrid z-s-coordinate + !------------------------------------------------------------------------------ ! grid information !------------------------------------------------------------------------------ diff --git a/tests/test_zgr.py b/tests/test_zgr.py index d573c5eb..4c9cbe76 100644 --- a/tests/test_zgr.py +++ b/tests/test_zgr.py @@ -65,7 +65,7 @@ def test_depth_file_zps(): e_dict = {k: hg.grid[k] for k in keys} # calc vertical grid - zg = zgr.Z_Grid(in_file, name_map, hg.grid_type, e_dict, logger) + zg = zgr.Z_Grid(in_file, "zps", name_map, hg.grid_type, e_dict, logger) nc = GetFile(bench_file) e3t = nc.nc["e3t"][:] diff --git a/tests/test_zz_end_to_end.py b/tests/test_zz_end_to_end.py index a5b42f80..ed0778d8 100644 --- a/tests/test_zz_end_to_end.py +++ b/tests/test_zz_end_to_end.py @@ -44,7 +44,7 @@ def test_zco_zco(): """ path1, path2, path3 = generate_sc_test_case(zco=True) path4 = generate_dst_test_case(zco=True) - name_list_path = modify_namelist(path1, path3, path4) + name_list_path = modify_namelist(path1, path3, path4, "zco", "zco") # Run pybdy subprocess.run( @@ -108,8 +108,8 @@ def test_zco_zco(): "Sum_mask": 740490, "Shape_u": (30, 25, 1, 1566), "Shape_v": (30, 25, 1, 1566), - "Mean_u": 0.9975701570510864, - "Mean_v": 0.9893443584442139, + "Mean_u": 0.997593879699707, + "Mean_v": 0.9893401861190796, } assert summary_grid == test_grid, "May need to update regression values." @@ -124,7 +124,7 @@ def test_sco_sco(): """ path1, path2, path3 = generate_sc_test_case(zco=False) path4 = generate_dst_test_case(zco=False) - name_list_path = modify_namelist(path1, path3, path4) + name_list_path = modify_namelist(path1, path3, path4, "sco", "sco") # Run pybdy subprocess.run( @@ -182,14 +182,14 @@ def test_sco_sco(): "Shape_temp": (30, 15, 1, 1584), "Shape_ssh": (30, 1, 1584), "Shape_mask": (60, 50), - "Mean_temp": 18.054542541503906, + "Mean_temp": 18.054527282714844, "Mean_sal": 34.12153625488281, "Sum_unmask": 665280, "Sum_mask": 47520, "Shape_u": (30, 15, 1, 1566), "Shape_v": (30, 15, 1, 1566), - "Mean_u": 0.7764930725097656, - "Mean_v": 0.7688539624214172, + "Mean_u": 0.7650341987609863, + "Mean_v": 0.7656515836715698, } assert summary_grid == test_grid, "May need to update regression values." @@ -204,7 +204,7 @@ def test_sco_zco(): """ path1, path2, path3 = generate_sc_test_case(zco=False) path4 = generate_dst_test_case(zco=True) - name_list_path = modify_namelist(path1, path3, path4) + name_list_path = modify_namelist(path1, path3, path4, "sco", "zco") # Run pybdy subprocess.run( @@ -262,7 +262,7 @@ def test_sco_zco(): "Shape_temp": (30, 25, 1, 1584), "Shape_ssh": (30, 1, 1584), "Shape_mask": (60, 50), - "Mean_temp": 18.122085571289062, + "Mean_temp": 18.122074127197266, "Mean_sal": 34.09104537963867, "Sum_unmask": 447510, "Sum_mask": 740490, @@ -285,7 +285,7 @@ def test_wrap_sc(): """ path1, path2, path3 = generate_sc_test_case(zco=True, wrap=1) path4 = generate_dst_test_case(zco=True) - name_list_path = modify_namelist(path1, path3, path4) + name_list_path = modify_namelist(path1, path3, path4, "zco", "zco") # Run pybdy subprocess.run( @@ -609,7 +609,7 @@ def generate_dst_test_case(zco): return path1 -def modify_namelist(path_src, path_sc_data, path_dst): +def modify_namelist(path_src, path_sc_data, path_dst, src_zgr, dst_zgr): # Modify paths in a namelist file for testing. namelist_file = "./tests/data/namelist_zz_end_to_end.bdy" @@ -617,11 +617,20 @@ def modify_namelist(path_src, path_sc_data, path_dst): with open(namelist_file, "r") as f: lines = f.readlines() for li in range(len(lines)): - if "sn_src_hgr" in lines[li]: + if "sn_src_zgr_type" in lines[li]: + st = lines[li].split("=")[0] + en = lines[li].split("!")[-1] + lines[li] = st + "= '" + src_zgr + "' !" + en + if "sn_dst_zgr_type" in lines[li]: + st = lines[li].split("=")[0] + en = lines[li].split("!")[-1] + lines[li] = st + "= '" + dst_zgr + "' !" + en + + if "sn_src_hgr " in lines[li]: st = lines[li].split("=")[0] en = lines[li].split("!")[-1] lines[li] = st + "= '" + path_src + "' !" + en - if "sn_src_zgr" in lines[li]: + if "sn_src_zgr " in lines[li]: st = lines[li].split("=")[0] en = lines[li].split("!")[-1] lines[li] = st + "= '" + path_src + "' !" + en @@ -630,11 +639,11 @@ def modify_namelist(path_src, path_sc_data, path_dst): en = lines[li].split("!")[-1] lines[li] = st + "= '" + path_src + "' !" + en - if "sn_dst_hgr" in lines[li]: + if "sn_dst_hgr " in lines[li]: st = lines[li].split("=")[0] en = lines[li].split("!")[-1] lines[li] = st + "= '" + path_dst + "' !" + en - if "sn_dst_zgr" in lines[li]: + if "sn_dst_zgr " in lines[li]: st = lines[li].split("=")[0] en = lines[li].split("!")[-1] lines[li] = st + "= '" + path_dst + "' !" + en