AJMR-Python-Baird/EWR_D3D/EWR_PlotHD_D3D_Profile.py

306 lines
10 KiB
Python

#%% Plotting script for LSU D3D data
# Alexander Rey, 2022
import os
import pandas as pd
import geopandas as gp
import netCDF4 as nc
import math
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.cm as cm
import datetime as datetime
from scipy.interpolate import LinearNDInterpolator, interp1d
from dfm_tools.get_nc import get_netdata, get_ncmodeldata, plot_netmapdata
from dfm_tools.get_nc_helpers import get_timesfromnc, get_ncfilelist, get_hisstationlist, get_ncvardimlist, get_timesfromnc
import cartopy.crs as ccrs
import contextily as ctx
from dfm_tools.regulargrid import scatter_to_regulargrid
import pathlib as pl
import alphashape
import rioxarray
import xarray as xr
from shapely import geometry, ops
#%% Read in centerline shapefile
river_centerline = gp.read_file('//srv-ott3.baird.com/Projects/12828.101 English Wabigoon River/03_Data/02_Physical/16_Waterline/Centerline_for_Modelling_UTMZ15.shp')
river_centerlineExploded = river_centerline.explode(ignore_index=True)
river_centerlineExploded.reset_index(inplace=True)
tempMulti = river_centerlineExploded.iloc[[5,0,1,2,3,4,6,7,9], 4]
# Put the sub-line coordinates into a list of sublists
outcoords = [list(i.coords) for i in tempMulti]
# Flatten the list of sublists and use it to make a new line
river_centerline_merge = geometry.LineString([i for sublist in outcoords for i in sublist])
river_centerline_merge_gpd = gp.GeoSeries(river_centerline_merge)
river_centerline_merge_gpd2 =\
gp.GeoDataFrame(geometry=gp.points_from_xy(
river_centerline_merge.xy[0], river_centerline_merge.xy[1], crs="EPSG:32615"))
# Add distance along centerline
river_centerline_merge_gpd2['DistanceFromPrevious'] = river_centerline_merge_gpd2.distance(river_centerline_merge_gpd2.shift(1))
river_centerline_merge_gpd2['RiverKM'] = river_centerline_merge_gpd2['DistanceFromPrevious'].cumsum()
river_centerline_merge_gpd2.iloc[0, 1] = 0
river_centerline_merge_gpd2.iloc[0, 2] = 0
#%% Save River Centerline as Shapefile
river_centerline_merge_gpd2.to_file('//srv-ott3.baird.com/Projects/12828.101 English Wabigoon River/03_Data/02_Physical/16_Waterline/Centerline_for_Modelling_UTMZ15_RiverKM.shp')
#%% Read Model Log
pth = pl.Path("//srv-ott3.baird.com/", "Projects", "12828.101 English Wabigoon River", "06_Models", "00_Delft3D", "ModelRuns.xlsx")
runLog = pd.read_excel(pth.as_posix(), "Test runs", skiprows=1)
dataPath = "FlowFM_map.nc"
#%% Import using DFM functions
#modelPlot = [35, 36, 37, 39, 40, 41, 42, 43, 44, 45]
modelPlot = [18, 35]
dataIN_gp = [None] * (max(modelPlot)+1)
dataOUT = [None] * (max(modelPlot)+1)
for i in modelPlot:
if (i == 39) or (i == 40) or (i == 41) or (i == 42) or (i == 43) or (i == 44) or (i == 45):
Flume = True
else:
Flume = False
# Find Map File in Output Folder
outputFiles = os.listdir(os.path.join(runLog['Run Location'][i],
'output'))
for file in outputFiles:
if file.endswith("map.nc"):
mapFile = file
file_nc_map = os.path.join(runLog['Run Location'][i],
'output', mapFile)
tSteps = get_timesfromnc(file_nc=file_nc_map, varname='time')
# Find nearest time step to desired time
# tStep = []
# for s in stormTime:
# abs_deltas_from_target_date = np.absolute(tSteps - s)
# tStep.append(np.argmin(abs_deltas_from_target_date))
# Otherwise, define a timestep
tStep = len(tSteps)-2
# Get Var info
vars_pd, dims_pd = get_ncvardimlist(file_nc=file_nc_map)
# Define extraction variables
# if (i == 37) or (i == 39):
# dataVars = ['s1', 'waterdepth', 'taus', 'ucmaga']
# else:
dataVars = ['s1', 'waterdepth', 'taus', 'ucmag']
# Create Pandas Output Array
dataIN_x = get_ncmodeldata(file_nc=file_nc_map,
varname='mesh2d_face_x',
silent=True)
dataIN_y = get_ncmodeldata(file_nc=file_nc_map,
varname='mesh2d_face_y',
silent=True)
dataIN_gp[i] = gp.GeoDataFrame(geometry=gp.points_from_xy(dataIN_x, dataIN_y, crs="EPSG:32615"))
# Extract variables
for vIDX, v in enumerate(dataVars):
# Extract data from NetCDF file
if len(vars_pd.loc['mesh2d_' + v, 'shape']) == 3:
dataIN = get_ncmodeldata(file_nc=file_nc_map,
varname='mesh2d_' + v, timestep=len(tSteps) - 1,
silent=True, layer='all')
dataIN = dataIN.mean(axis=2)
else:
dataIN = get_ncmodeldata(file_nc=file_nc_map,
varname='mesh2d_' + v, timestep=len(tSteps) - 1,
silent=True) # , layer=0
dataIN_gp[i][v] = np.array(dataIN[0][:])
print(v)
# Extract Bed Level
dataIN = get_ncmodeldata(file_nc=file_nc_map,
varname='mesh2d_flowelem_bl',
silent=True) # , layer=0
dataIN_gp[i]['mesh2d_flowelem_bl'] = np.array(dataIN[:])
print('mesh2d_flowelem_bl')
# Create Dataframe along river centerline for plotting
if Flume == True:
dataOUT[i] = dataIN_gp[i]
dataOUT[i]['RiverKM'] = dataIN_x
else:
dataOUT[i] = gp.sjoin_nearest(river_centerline_merge_gpd2, dataIN_gp[i], how='left', max_distance=100)
dataOUT[i].set_index('RiverKM', inplace=True)
#%% Key Profile Sites
KeySites = dict()
KeySites['Dryden'] = 0
KeySites['Rugby Creek'] = 2650
KeySites['Eagle River'] = 44200
KeySites['Beaver Creek'] = 38600
KeySites['Clay Lake'] = 90000
KeySites['Gullwing River'] = 20100
KeySites['Cowamula'] = 57400
# KeySites['Buller Creek'] = 66000
# Structure Sites
StructureSites = dict()
StructureSites['Mutrie Lake'] = 54214
StructureSites['Highway 105'] = 64998
StructureSites['Quibell'] = 70000
StructureSites['Wainwright Dam'] = 6013
#%% Plot Data along centerline
fig, axes = plt.subplots(nrows=5, ncols=1, figsize=(9, 9), sharex=True)
fig.patch.set_facecolor('white')
fig.tight_layout(pad=3)
ax = axes.flat
modelPlot = [35, 37, 40, 41, 42, 43, 44]
modelPlot = [40, 41, 42, 43, 44]
modelPlot = [35, 37, 40, 45]
modelPlot = [18, 35]
for i in modelPlot:
# S1
ax[0].set_title('Water Level')
ax[0].plot(dataOUT[i].index, dataOUT[i]['s1'], linewidth=3, label=runLog['Run Title'][i])
ax[0].set_ylim([330, 345])
# ax[0].set_xlim([0, 10000])
ax[0].set_xlim([0, 90000])
ax[0].legend(loc='upper right')
ax[0].set_ylabel('Water Level [m]')
# Shear
ax[1].set_title('Shear Stress')
ax[1].plot(dataOUT[i].index, dataOUT[i]['taus'], linewidth=3, label=runLog['Run Title'][i])
ax[1].set_ylim([0, 2])
ax[1].legend(loc='upper right')
ax[1].set_ylabel('Shear Stress [N/m^2]')
# Water Depth
ax[2].set_title('Water Depth')
ax[2].plot(dataOUT[i].index, dataOUT[i]['waterdepth'], linewidth=3, label=runLog['Run Title'][i])
ax[2].set_ylim([0, 20])
ax[2].legend(loc='upper right')
ax[2].set_ylabel('Water Depth [m]')
# Bed Level
ax[3].set_title('Bed Level')
ax[3].plot(dataOUT[i].index, dataOUT[i]['mesh2d_flowelem_bl'], linewidth=3, label=runLog['Run Title'][i])
# ax[3].set_ylim([320, 340])
ax[3].legend(loc='upper right')
ax[3].set_ylabel('Bed Level [m]')
# Velocity
ax[4].set_title('Depth Averaged Velocity')
ax[4].plot(dataOUT[i].index, dataOUT[i]['ucmag'], linewidth=3, label=runLog['Run Title'][i])
ax[4].set_ylim([0, 2])
ax[4].legend(loc='upper right')
ax[4].set_ylabel('Velocity [m/s]')
ax[4].set_xlabel('Distance Along River [m]')
plt.show()
# fig.savefig('//srv-ott3.baird.com/Projects/12828.101 English Wabigoon River/06_Models/00_Delft3D/12_WAQ/FullDomainFigures/DomainHDCompare.png',
# bbox_inches='tight', dpi=200)
fig.savefig('//srv-ott3.baird.com/Projects/12828.101 English Wabigoon River/06_Models/00_Delft3D/07_PostProcessing/HD_Profile_Compare.png',
bbox_inches='tight', dpi=200)
#%% Plot select data along centerline
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(9, 6), sharex=True)
ax = axes.flat
# fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(9, 4), sharex=True)
# ax[0] = axes
fig.patch.set_facecolor('white')
# Expand plot to allow space for legend
# fig.subplots_adjust(left=-2)
modelPlot = [18, 35]
for i in modelPlot:
# Velocity
ax[0].set_title('Depth Averaged Velocity Along River Centerline')
ax[0].plot(dataOUT[i].index / 1000, dataOUT[i]['ucmag'], linewidth=3, label=runLog['Run Title'][i], zorder=1)
ax[0].set_ylim([0, 2])
ax[0].set_xlim([0, 90])
ax[0].set_ylabel('Velocity [m/s]')
# Shear
ax[1].set_title('Shear Stress Along River Centerline')
ax[1].plot(dataOUT[i].index/1000, dataOUT[i]['taus'], linewidth=3, label=runLog['Run Title'][i], zorder=1)
ax[1].set_ylim([0, 2])
ax[1].set_xlim([0, 90])
ax[1].set_ylabel('Shear Stress [N/$\mathregular{m^2}$]')
ax[1].set_xlabel('Distance Along River [km]')
# Add in structure sites and key sites
for site in KeySites.keys():
for axID in range(0, 2):
if site == 'Dryden':
ax[axID].scatter(KeySites[site]/1000, 1, marker='^', color='k', s=30, label='Inflow', zorder=2)
else:
ax[axID].scatter(KeySites[site]/1000, 1, marker='^', color='k', s=30, zorder=10)
ax[axID].text(KeySites[site]/1000, 1.1, site, rotation=45)
for structureSite in StructureSites.keys():
for axID in range(0, 2):
if structureSite == 'Mutrie Lake':
ax[axID].scatter(StructureSites[structureSite]/1000, 1, marker='s', color='k', label='Hydraulic Structure',
s=30, zorder=10)
else:
ax[axID].scatter(StructureSites[structureSite]/1000, 1, marker='s', color='k', s=30, zorder=10)
ax[axID].text(StructureSites[structureSite] / 1000, 1.1, structureSite, rotation=45)
# Add remobilization threshold lines
ax[0].plot([0, 90000], [0.1, 0.1], linestyle='--', linewidth=1, label='Silt Remobilization Threshold', zorder=5)
ax[0].plot([0, 90000], [1.3, 1.3], linestyle='--', linewidth=1, label='Sand Remobilization Threshold', zorder=5)
ax[0].legend(bbox_to_anchor=(1.01, 0.5), loc="upper left")
fig.tight_layout(pad=1)
plt.show()
# fig.savefig('//srv-ott3.baird.com/Projects/12828.101 English Wabigoon River/06_Models/00_Delft3D/07_PostProcessing/HD_Profile_Compare_DAV.png',
# bbox_inches='tight', dpi=300)
fig.savefig('//srv-ott3.baird.com/Projects/12828.101 English Wabigoon River/06_Models/00_Delft3D/07_PostProcessing/HD_Profile_Compare_RevD.png',
bbox_inches='tight', dpi=300)