From 160207ca814ea58e8c8e69501bad1b0b00eb04b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Friis-M=C3=B8ller?= <mikf@dtu.dk> Date: Wed, 13 Oct 2021 08:34:53 +0000 Subject: [PATCH] updated xrsite to export yml --- py_wake/site/xrsite.py | 51 +++++++++++++++++++++++++++ py_wake/tests/test_sites/test_site.py | 33 ++++++++++++++--- py_wake/utils/ieawind37_utils.py | 8 +++++ 3 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 py_wake/utils/ieawind37_utils.py diff --git a/py_wake/site/xrsite.py b/py_wake/site/xrsite.py index 458a2c7f0..214714f81 100644 --- a/py_wake/site/xrsite.py +++ b/py_wake/site/xrsite.py @@ -2,9 +2,13 @@ import numpy as np from numpy import newaxis as na import xarray as xr from requests import get +import yaml +import os +from pathlib import Path from py_wake.site._site import Site from py_wake.site.distance import StraightDistance from py_wake.utils import weibull +from py_wake.utils.ieawind37_utils import iea37_names from py_wake.utils.grid_interpolator import GridInterpolator, EqDistRegGrid2DInterpolator @@ -251,6 +255,53 @@ class XRSite(Site): lw['P'] = p_wd * self.weibull_weight(lw, A, k) return lw + def to_ieawind37_ontology(self, name='Wind Resource', filename='WindResource.yaml', data_in_netcdf=False): + name_map = {k: v for k, v in iea37_names()} + ds = self.ds.sel(wd=self.ds.wd[:-1]) + ds_keys = list(ds.keys()) + list(ds.coords) + map_dict = {key: name_map[key] for key in ds_keys if key in name_map} + ds = ds.rename(map_dict) + + def fmt(v): + if isinstance(v, dict): + return {k: fmt(v) for k, v in v.items() if fmt(v) != {}} + elif isinstance(v, tuple): + return list(v) + else: + return v + data_dict = fmt(ds.to_dict()) + + if not data_in_netcdf: + # yaml with all + yml = yaml.dump({'name': name, 'wind_resource': {**{k: v['data'] for k, v in data_dict['coords'].items()}, + **data_dict['data_vars']}}) + Path(filename).write_text(yml) + + else: + # yaml with data in netcdf + ds.to_netcdf(filename.replace('.yaml', '.nc')) + yml_nc = yaml.dump({'name': name, 'wind_resource': "!include %s" % os.path.basename(filename).replace('.yaml', '.nc')}).replace("'", "") + Path(filename).write_text(yml_nc) + + def from_iea37_ontology_yml(filename, data_in_netcdf=False): + name_map = {v: k for k, v in iea37_names()} + if not data_in_netcdf: + with open(filename) as fid: + yml_dict = yaml.safe_load(fid)['wind_resource'] + for k, v in yml_dict.items(): + if not isinstance(v, dict): # its a coord + yml_dict[k] = {'dims': [k], 'data': v} + ds = xr.Dataset.from_dict(yml_dict) + map_dict = {key: name_map[key] for key in list(ds.keys()) + list(ds.coords)} + ds = ds.rename(map_dict) + xr_site = XRSite(ds) + else: + with xr.open_dataset(filename.replace(".yaml", '.nc')).load() as ds: + map_dict = {key: name_map[key] for key in list(ds.keys()) + list(ds.coords)} + ds = ds.rename(map_dict) + xr_site = XRSite(ds) + return xr_site + class UniformSite(XRSite): """Site with uniform (same wind over all, i.e. flat uniform terrain) and diff --git a/py_wake/tests/test_sites/test_site.py b/py_wake/tests/test_sites/test_site.py index 7c41ffd0c..08208bef4 100644 --- a/py_wake/tests/test_sites/test_site.py +++ b/py_wake/tests/test_sites/test_site.py @@ -1,11 +1,13 @@ -from py_wake.site._site import UniformWeibullSite, UniformSite +import os +import pytest import numpy as np +import matplotlib.pyplot as plt from py_wake.tests import npt -import pytest +from py_wake.site._site import UniformWeibullSite, UniformSite from py_wake.site.shear import PowerShear -import matplotlib.pyplot as plt -from py_wake.examples.data.iea37._iea37 import IEA37Site from py_wake.site.xrsite import XRSite +from py_wake.tests.test_files import tfp +from py_wake.examples.data.iea37._iea37 import IEA37Site f = [0.035972, 0.039487, 0.051674, 0.070002, 0.083645, 0.064348, 0.086432, 0.117705, 0.151576, 0.147379, 0.10012, 0.05166] @@ -238,3 +240,26 @@ def test_uniform_site_probability(): site = UniformSite(p_wd, ti=1) lw = site.local_wind(0, 0, 0, wd=np.linspace(0, 360, p_wd.size, endpoint=False), ws=12) npt.assert_array_almost_equal(lw.P, p_wd) + + +def test_ieawind37_ontology_yaml_export(site): + dirname = 'test_export_temp' + filename = 'WindResource.yaml' + os.makedirs(os.path.join(tfp, dirname), exist_ok=True) + site.to_ieawind37_ontology(filename=os.path.join(tfp, dirname, filename), data_in_netcdf=False) + yml_site = XRSite.from_iea37_ontology_yml(filename=os.path.join(tfp, dirname, filename), data_in_netcdf=False) + os.remove(os.path.join(tfp, dirname, filename)) + os.rmdir(os.path.join(tfp, dirname)) + assert yml_site.ds.equals(site.ds) + + +def test_ieawind37_ontology_netcdf_export(site): + dirname = 'test_export_temp' + filenames = ['WindResource.yaml', 'WindResource.nc'] + os.makedirs(os.path.join(tfp, dirname), exist_ok=True) + site.to_ieawind37_ontology(filename=os.path.join(tfp, dirname, filenames[0]), data_in_netcdf=True) + yml_site = XRSite.from_iea37_ontology_yml(os.path.join(tfp, dirname, filenames[0]), data_in_netcdf=True) + for f in filenames: + os.remove(os.path.join(tfp, dirname, f)) + os.rmdir(os.path.join(tfp, dirname)) + assert yml_site.ds.equals(site.ds) diff --git a/py_wake/utils/ieawind37_utils.py b/py_wake/utils/ieawind37_utils.py new file mode 100644 index 000000000..9cef99bf0 --- /dev/null +++ b/py_wake/utils/ieawind37_utils.py @@ -0,0 +1,8 @@ +def iea37_names(): + return [('P', 'probability'), + ('TI', 'turbulence_intensity'), + ('wd', 'wind_direction'), + ('ws', 'wind_speed'), + ('Sector_frequency', 'sector_probability'), + ('Weibull_A', 'weibull_a'), + ('Weibull_k', 'weibull_k')] -- GitLab