@@ -197,6 +197,7 @@ def plot_feature_transects(
197197 flip = False ,
198198 write_netcdf = False ,
199199 method = 'flat' ,
200+ add_z = False ,
200201):
201202 """
202203 Plot images of the given variables on the given transects. One image
@@ -232,13 +233,19 @@ def plot_feature_transects(
232233 values over each MPAS cell. ``bilinear`` means smooth interpolation
233234 between horizontally between cell centers and vertical between the
234235 middle of layers.
236+
237+ add_z : bool, optional
238+ Whether to add zMid and zInterface to the mesh dataset
235239 """
236240 if 'Time' in ds .dims :
237241 ds = ds .isel (Time = 0 )
238242
239243 if 'Time' in ds_mesh .dims :
240244 ds_mesh = ds_mesh .isel (Time = 0 )
241245
246+ if add_z :
247+ _add_z (ds_mesh )
248+
242249 print ('\n Building transect geometry...' )
243250 transects = _compute_feature_transects (fc , ds_mesh , flip )
244251
@@ -253,13 +260,25 @@ def plot_feature_transects(
253260 variable_list = list ()
254261 for var_name in ds .data_vars :
255262 var = ds [var_name ]
256- if 'nCells' in var .dims and 'nVertLevels' in var .dims :
263+ if 'nCells' in var .dims and (
264+ 'nVertLevels' in var .dims or 'nVertLevelsP1' in var .dims
265+ ):
257266 variable_list .append (var_name )
258267
259268 print ('\n Plotting...' )
260269 for var_name in variable_list :
261- var = ds [var_name ]
262- assert 'nCells' in var .dims and 'nVertLevels' in var .dims
270+ if var_name in ds :
271+ var = ds [var_name ]
272+ elif var_name in ds_mesh :
273+ var = ds_mesh [var_name ]
274+ else :
275+ raise ValueError (
276+ f'{ var_name } not found in either the main or the '
277+ f'mesh dataset (if any)'
278+ )
279+ assert 'nCells' in var .dims and (
280+ 'nVertLevels' in var .dims or 'nVertLevelsP1' in var .dims
281+ )
263282 for transect_name , ds_transect in transects .items ():
264283 print (f' { transect_name } { var_name } ' )
265284 _plot_feature_transect (
@@ -334,6 +353,12 @@ def plot_feature_transects_main():
334353 help = 'The type of interpolation to use in plots. '
335354 'Options are "flat" and "bilinear"' ,
336355 )
356+ parser .add_argument (
357+ '--add_z' ,
358+ dest = 'add_z' ,
359+ action = 'store_true' ,
360+ help = 'Whether to add zMid and zInterface to the mesh' ,
361+ )
337362
338363 args = parser .parse_args ()
339364
@@ -361,6 +386,7 @@ def plot_feature_transects_main():
361386 flip = args .flip ,
362387 write_netcdf = args .write_netcdf ,
363388 method = args .method ,
389+ add_z = args .add_z ,
364390 )
365391
366392
@@ -564,3 +590,58 @@ def _plot_feature_transect(
564590 plt .close ()
565591 if write_netcdf :
566592 ds_transect .to_netcdf (f'{ transect_prefix } _{ var_name } .nc' )
593+
594+
595+ def _add_z (ds_mesh ):
596+ """
597+ Add zMid and zInterface to ``ds_mesh``, useful for debugging
598+ """
599+
600+ layer_thickness = ds_mesh .layerThickness
601+ bottom_depth = ds_mesh .bottomDepth
602+ max_level_cell = ds_mesh .maxLevelCell - 1
603+ if 'minLevelCell' in ds_mesh :
604+ min_level_cell = ds_mesh .minLevelCell - 1
605+ else :
606+ min_level_cell = xr .zeros_like (max_level_cell )
607+
608+ n_vert_levels = layer_thickness .sizes ['nVertLevels' ]
609+
610+ vert_index = xr .DataArray .from_dict (
611+ {'dims' : ('nVertLevels' ,), 'data' : np .arange (n_vert_levels )}
612+ )
613+
614+ cell_mask = np .logical_and (
615+ vert_index >= min_level_cell , vert_index <= max_level_cell
616+ )
617+ layer_thickness = layer_thickness .where (cell_mask )
618+
619+ thickness_sum = layer_thickness .sum (dim = 'nVertLevels' )
620+ thickness_cum_sum = layer_thickness .cumsum (dim = 'nVertLevels' )
621+ z_surface = - bottom_depth + thickness_sum
622+
623+ z_layer_bot = z_surface - thickness_cum_sum
624+
625+ z_interface_list = [z_surface ]
626+ for z_index in range (n_vert_levels ):
627+ z_interface_list .append (z_layer_bot .isel (nVertLevels = z_index ))
628+
629+ z_interface = xr .concat (z_interface_list , dim = 'nVertLevelsP1' )
630+
631+ vert_index = xr .DataArray .from_dict (
632+ {'dims' : ('nVertLevelsP1' ,), 'data' : np .arange (n_vert_levels + 1 )}
633+ )
634+ interface_mask = np .logical_and (
635+ vert_index >= min_level_cell , vert_index <= max_level_cell + 1
636+ )
637+
638+ z_interface = z_interface .where (interface_mask ).transpose (
639+ 'nCells' , 'nVertLevelsP1'
640+ )
641+
642+ z_mid = z_layer_bot + 0.5 * layer_thickness
643+
644+ z_mid = z_mid .where (cell_mask ).transpose ('nCells' , 'nVertLevels' )
645+
646+ ds_mesh .coords ['zMid' ] = z_mid
647+ ds_mesh .coords ['zInterface' ] = z_interface
0 commit comments