Skip to content

Commit 397b4d4

Browse files
committed
Add support for transect fields on layer interfaces
These are fields with dimension `nVertLevelsP1`.
1 parent e77a83f commit 397b4d4

File tree

2 files changed

+390
-108
lines changed

2 files changed

+390
-108
lines changed

conda_package/mpas_tools/ocean/viz/transect/plot.py

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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('\nBuilding 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('\nPlotting...')
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

Comments
 (0)