Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve interpolation of uds/ugrid to plipoints #915

Closed
10 of 12 tasks
veenstrajelmer opened this issue Aug 1, 2024 · 0 comments
Closed
10 of 12 tasks

Improve interpolation of uds/ugrid to plipoints #915

veenstrajelmer opened this issue Aug 1, 2024 · 0 comments

Comments

@veenstrajelmer
Copy link
Collaborator

veenstrajelmer commented Aug 1, 2024

After fixing #912 and #911 the conversion_dict can be applied to a uds (ugriddataset) also. Furthermore, there are some additional improvements to the bc files (like depth correction and quantity renaming) via the conventions/conversion public functions:

import dfm_tools as dfmt
import hydrolib.core.dflowfm as hcdfm
import matplotlib.pyplot as plt
plt.close("all")
import xarray as xr

# read plifile as gdf
file_pli = r'P:\11209133-ultfarms\02-Simulations\North_Sea_runs_Loreta\pre-processing\offshore_boundaries\FuMA_scripts\DCSM-FM_OB_all_20181108.pli' # polygon containing open boundary forcing points
pli_obj = hcdfm.PolyFile(file_pli)
pli_gdf = dfmt.PolyFile_to_geodataframe_points(pli_obj)

# only take first points to speed up for testing
pli_gdf_test = pli_gdf.iloc[:6]
time_slice = slice(None,5) # use None to use all timesteps

scen = 'historical' # test
# yr = 2005#, 2006, 2007, 2008] # test

conversion_dict = dfmt.get_conversion_dict()
conversion_dict = {
    # conversion is phyc in mol/m3 to newvar in g/m3
    'tracerbndOXY'        : {'ncvarname': 'o2',          'unit': 'g/m3', 'conversion': 32.0 },
    'tracerbndNO3'        : {'ncvarname': 'no3',         'unit': 'g/m3', 'conversion': 14.0 },
    'tracerbndPO4'        : {'ncvarname': 'po4',         'unit': 'g/m3', 'conversion': 30.97 },
    'tracerbndSi'         : {'ncvarname': 'si',          'unit': 'g/m3', 'conversion': 28.08},
    'tracerbndPON1'       : {'ncvarname': 'phyc',        'unit': 'g/m3', 'conversion': 14.0}, # Caution: this empirical relation might not be applicable to your use case
    'tracerbndPOP1'       : {'ncvarname': 'phyc',        'unit': 'g/m3', 'conversion': 30.97}, # Caution: this empirical relation might not be applicable to your use case
    'tracerbndPOC1'       : {'ncvarname': 'phyc',        'unit': 'g/m3', 'conversion': 14.0 * (106 / 16)}, # Caution: this empirical relation might not be applicable to your use case
    'salinitybnd'         : {'ncvarname': 'so'},         #'1e-3'
    'temperaturebnd'      : {'ncvarname': 'thetao'},         #'degC'
    'ux'                  : {'ncvarname': 'uo'},          #'m/s'
    'uy'                  : {'ncvarname': 'vo'},          #'m/s'
    'waterlevelbnd'       : {'ncvarname': 'zos'},         #'m' #steric
    'tide'                : {'ncvarname': ''},            #'m' #tide (dummy entry)
}

ext_new = hcdfm.ExtModel()

quan_bnd_list = ['uxuyadvectionvelocitybnd','salinitybnd','temperaturebnd','waterlevelbnd']
# quan_bnd_list = ['tracerbndNO3'] # fails on "KeyError: 'units'" (will be fixed in dfm_tools 0.26.0)

for quantity in quan_bnd_list:
    # quantity_list = ['ux','uy']
    # TODO: consider avoiding the need to use private functions
    quantity_list = dfmt.modelbuilder.get_quantity_list(quantity)
    
    ds_points_list = []
    for quantity_one in quantity_list:
        ncvarname = conversion_dict[quantity_one]['ncvarname']
        
        dir_pattern = fr'P:\archivedprojects\11206304-futuremares-rawdata-preps\data\CMIP6_BC\CMCC-ESM2\{ncvarname}_Omon_CMCC-ESM2_{scen}_r1i1p1f1_gn_*.nc'
        
        uds = dfmt.open_dataset_curvilinear(dir_pattern, convert_360to180=True)
        
        # update refdate
        uds.time.encoding['units'] = 'days since 2004-01-01'
    
        uds = uds.ugrid.to_nonperiodic(xmax=180)
        
        # subset in time to speed up for testing
        uds_sel = uds.isel(time=time_slice)
        
        # # plot (first subset in space for visualization purposes)
        # buffer = 5
        # xmin = pli_gdf_test.geometry.x.min() - buffer
        # xmax = pli_gdf_test.geometry.x.max() + buffer
        # ymin = pli_gdf_test.geometry.y.min() - buffer
        # ymax = pli_gdf_test.geometry.y.max() + buffer
        # fig, ax = plt.subplots()
        # uds.ugrid.sel(x=slice(xmin,xmax), y=slice(ymin,ymax))[ncvarname].isel(time=0, lev=0).ugrid.plot(ax=ax)
        # dfmt.plot_coastlines(ax=ax, res='i')
        # pli_gdf_test.plot(ax=ax, color='r')
    
        # apply conventions and conversions
        # TODO: consider avoiding the need to use private functions
        uds_conv = dfmt.interpolate_grid2bnd.ds_apply_conventions(uds_sel)
        uds_conv = dfmt.interpolate_grid2bnd.ds_apply_conversion_dict(uds_conv, conversion_dict=conversion_dict, quantity=quantity_one)
        
        # interpolate to points of polyfile
        ds_points = dfmt.interp_uds_to_plipoints(uds=uds_conv, gdf=pli_gdf_test)
        
        # keep only relevant variable
        ds_points = ds_points[quantity_one]
        
        ds_points_list.append(ds_points)
    
    ds_points_onevar = xr.merge(ds_points_list)
    
    # convert to bc/forcing hydrolib-core object
    ForcingModel_object = dfmt.plipointsDataset_to_ForcingModel(ds_points_onevar)
    # save to bc file
    ForcingModel_object.save(f"test_{quantity}_{scen}.bc")
    
    # append to extfile
    boundary_object = hcdfm.Boundary(quantity=quantity,
                                     locationfile=file_pli, #placeholder, will be replaced later on
                                     forcingfile=ForcingModel_object)
    
    # TODO: consider doing this per polyline (required if there is more than one in the file)
    # with ext_add_boundary_object_per_polyline
    ext_new.boundary.append(boundary_object)

ext_new.save(f"test_{scen}.ext")

Todo:

@veenstrajelmer veenstrajelmer changed the title Improve interpolation of ugrid to plipoints Improve interpolation of uds/ugrid to plipoints Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant