def test_IFORMContour(seastate_model): """ Compare the coordinates of an IFORM contour with the results from Haselsteiner et al. (2017; DOI: 10.1016/j.coastaleng.2017.03.002) """ alpha = calculate_alpha(3, 25) my_contour = IFORMContour(seastate_model, alpha) my_coordinates = my_contour.coordinates np.testing.assert_allclose(max(my_coordinates[:, 0]), 15.23, atol=0.05) np.testing.assert_allclose(max(my_coordinates[:, 1]), 13.96, atol=0.05)
def test_IFORM(reference_coordinates_IFORM): # Logarithmic square function. def _lnsquare2(x, a=3.62, b=5.77): return np.log(a + b * np.sqrt(x / 9.81)) # 3-parameter function that asymptotically decreases (a dependence function). def _asymdecrease3(x, a=0, b=0.324, c=0.404): return a + b / (1 + c * x) lnsquare2 = DependenceFunction(_lnsquare2) asymdecrease3 = DependenceFunction(_asymdecrease3) dist_description_0 = { "distribution": ExponentiatedWeibullDistribution(alpha=0.207, beta=0.684, delta=7.79), } dist_description_1 = { "distribution": LogNormalDistribution(), "conditional_on": 0, "parameters": { "mu": lnsquare2, "sigma": asymdecrease3 }, } ghm = GlobalHierarchicalModel([dist_description_0, dist_description_1]) state_duration = 3 return_period = 20 alpha = calculate_alpha(state_duration, return_period) my_iform = IFORMContour(ghm, alpha) my_coordinates = my_iform.coordinates np.testing.assert_allclose(my_coordinates, reference_coordinates_IFORM)
plot_dependence_functions, plot_marginal_quantiles, ) # %% load data, prepare common variables data = pd.read_csv("datasets/NDBC_buoy_46025.csv", sep=",")[["Hs", "T"]] dist_descriptions, fit_descriptions, semantics = get_DNVGL_Hs_Tz() ghm = GlobalHierarchicalModel(dist_descriptions) ghm.fit(data, fit_descriptions=fit_descriptions) state_duration = 3 return_period = 50 alpha = calculate_alpha(state_duration, return_period) iform_contour = IFORMContour(ghm, alpha) plt.close("all") # %% plot_qq axes = plot_marginal_quantiles(ghm, data, semantics=semantics) # plt.show() # %% plot_dependence_functions par_rename = {"mu": r"$\mu$", "sigma": r"$\sigma$"} axes = plot_dependence_functions(ghm, semantics=semantics, par_rename=par_rename)
0.25, 'Cut-out wind speed', fontsize=fs, rotation=90, verticalalignment='center') axs[0].spines['right'].set_visible(False) axs[0].spines['top'].set_visible(False) axs[0].set_ylabel(r_label) axs[0].set_ylim([0, 1.1]) # Load data, fit joint model, compute contour. data = read_ec_benchmark_dataset('ec-benchmark_dataset_D.txt') dist_descriptions, fit_descriptions, semantics = get_OMAE2020_V_Hs() model = GlobalHierarchicalModel(dist_descriptions) model.fit(data, fit_descriptions) c = IFORMContour(model, 1 / (50 * 365.25 * 24)) contour_v = c.coordinates[:, 0] / 0.95 contour_hs = c.coordinates[:, 1] contour_v = contour_v * (90 / 10)**0.14 # Convert wind speed to hub height. axs[1].plot(np.append(contour_v, contour_v[0]), np.append(contour_hs, contour_hs[0]), '--b', label='Environmental contour') axs[1].annotate('environmental contour', xy=(7.4, 4.6), xytext=(3, 2.5), arrowprops=dict(arrowstyle="->", color='blue'), size=fs,
def test_hs_tz_iform_contour(): """ Use a sea state dataset with the variables Hs and Tz, fit the join distribution recommended in DNVGL-RP-C203 to it and compute an IFORM contour. This tests reproduces the results published in Haseltseiner et al. (2019). Such a work flow is for example typical in ship design. Haselsteiner, A. F., Coe, R. G., Manuel, L., Nguyen, P. T. T., Martin, N., & Eckert-Gallup, A. (2019). A benchmarking exercise on estimating extreme environmental conditions: Methodology & baseline results. Proc. 38th International Conference on Ocean, Offshore and Arctic Engineering (OMAE 2019). https://doi.org/10.1115/OMAE2019-96523 DNV GL. (2017). Recommended practice DNVGL-RP-C205: Environmental conditions and environmental loads. """ data = read_ec_benchmark_dataset("datasets/ec-benchmark_dataset_A.txt") # A 3-parameter power function (a dependence function). def _power3(x, a, b, c): return a + b * x**c # A 3-parameter exponential function (a dependence function). def _exp3(x, a, b, c): return a + b * np.exp(c * x) bounds = [(0, None), (0, None), (None, None)] power3 = DependenceFunction(_power3, bounds) exp3 = DependenceFunction(_exp3, bounds) dist_description_0 = { "distribution": WeibullDistribution(), "intervals": WidthOfIntervalSlicer(width=0.5), } dist_description_1 = { "distribution": LogNormalDistribution(), "conditional_on": 0, "parameters": { "mu": power3, "sigma": exp3 }, } model = GlobalHierarchicalModel([dist_description_0, dist_description_1]) model.fit(data) axs = plot_marginal_quantiles(model, data) axs = plot_dependence_functions(model) ax = plot_2D_isodensity(model, data) alpha = calculate_alpha(1, 20) contour = IFORMContour(model, alpha) coordinates = contour.coordinates np.testing.assert_allclose(max(coordinates[:, 0]), 5.0, atol=0.5) np.testing.assert_allclose(max(coordinates[:, 1]), 16.1, atol=0.5) ax = plot_2D_contour(contour, sample=data)
# Load dataset (this is dataset D from a benchmarking exercise on environmental # contours, see https://github.com/ec-benchmark-organizers/ec-benchmark data = read_ec_benchmark_dataset("datasets/ec-benchmark_dataset_D.txt") # Define the structure of the joint distribution model. dist_descriptions, fit_descriptions, semantics = get_OMAE2020_V_Hs() model = GlobalHierarchicalModel(dist_descriptions) # Fit the model to the data (estimate the model's parameter values). model.fit(data, fit_descriptions) # Compute four type of contours with a return period of 50 years. state_duration = 1 # hours return_period = 50 # years alpha = state_duration / (return_period * 365.25 * 24) iform = IFORMContour(model, alpha) isorm = ISORMContour(model, alpha) direct_samplig = DirectSamplingContour(model, alpha) highest_density = HighestDensityContour(model, alpha) # Plot the contours on top of the metocean data. fig, axs = plt.subplots(1, 4, figsize=[16, 3.5]) plot_2D_contour(iform, sample=data, semantics=semantics, ax=axs[0]) plot_2D_contour(isorm, sample=data, semantics=semantics, ax=axs[1]) plot_2D_contour(direct_samplig, sample=data, semantics=semantics, ax=axs[2]) plot_2D_contour(highest_density, sample=data, semantics=semantics, ax=axs[3]) titles = ['IFORM', 'ISORM', 'Direct sampling', 'Highest density'] for ax, title in zip(axs, titles): ax.set_title(title) plt.tight_layout()
def test_WES4(dataset_wes_sigmau, refdata_wes_sigmau): # https://doi.org/10.5194/wes-4-325-2019 class MyIntervalSlicer(WidthOfIntervalSlicer): def _slice(self, data): interval_slices, interval_references, interval_boundaries = super( )._slice(data) # discard slices below 4 m/s ok_slices = [] ok_references = [] ok_boundaries = [] for slice_, reference, boundaries in zip(interval_slices, interval_references, interval_boundaries): if reference >= 4: ok_slices.append(slice_) ok_references.append(reference) ok_boundaries.append(boundaries) return ok_slices, ok_references, ok_boundaries def _poly3(x, a, b, c, d): return a * x**3 + b * x**2 + c * x + d def _poly2(x, a, b, c): return a * x**2 + b * x + c poly3 = DependenceFunction(_poly3) poly2 = DependenceFunction(_poly2) dim0_description = { "distribution": WeibullDistribution(), "intervals": MyIntervalSlicer(width=1, reference="left", min_n_points=5), } dim1_description = { "distribution": LogNormalNormFitDistribution(), "conditional_on": 0, "parameters": { "mu_norm": poly3, "sigma_norm": poly2 }, } ghm = GlobalHierarchicalModel([dim0_description, dim1_description]) ghm.fit(dataset_wes_sigmau) alpha = 1 / (5 * len(dataset_wes_sigmau)) iform = IFORMContour(ghm, alpha) my_coordinates = iform.coordinates x_U = np.linspace(2, 40, num=100) x_sigma = np.linspace(0.02, 3.6, num=100) U_dist = ghm.distributions[0] my_weib_param = list(U_dist.parameters.values()) my_f_weib = U_dist.pdf(x_U) my_ln = ghm.distributions[1] my_intervals = my_ln.data_intervals my_givens = my_ln.conditioning_values my_f_ln = [] for given in my_givens: my_f_ln.append(my_ln.pdf(x_sigma, given)) my_f_ln = np.stack(my_f_ln, axis=1) my_mu_norms = np.array( [par["mu_norm"] for par in my_ln.parameters_per_interval]) my_sigma_norms = np.array( [par["sigma_norm"] for par in my_ln.parameters_per_interval]) my_intervals = my_ln.data_intervals my_sigmas = [dist.sigma for dist in my_ln.distributions_per_interval] my_mus = [dist.mu for dist in my_ln.distributions_per_interval] ref_weib_param = refdata_wes_sigmau["ref_weib_param"] ref_f_weib = refdata_wes_sigmau["ref_f_weib"] ref_intervals = refdata_wes_sigmau["ref_intervals"] ref_givens = refdata_wes_sigmau["ref_givens"] ref_mu_norms = refdata_wes_sigmau["ref_mu_norms"] ref_sigma_norms = refdata_wes_sigmau["ref_sigma_norms"] ref_mus = refdata_wes_sigmau["ref_mus"] ref_sigmas = refdata_wes_sigmau["ref_sigmas"] ref_f_ln = refdata_wes_sigmau["ref_f_ln"] ref_coordinates = refdata_wes_sigmau["ref_coordinates"] np.testing.assert_allclose(my_weib_param, ref_weib_param) np.testing.assert_allclose(my_f_weib, ref_f_weib) assert len(my_intervals) == len(ref_intervals) for i in range(len(ref_intervals)): assert sorted(my_intervals[i]) == sorted(ref_intervals[i]) np.testing.assert_allclose(my_givens, ref_givens) np.testing.assert_allclose(my_mu_norms, ref_mu_norms) np.testing.assert_allclose(my_sigma_norms, ref_sigma_norms) np.testing.assert_allclose(my_mus, ref_mus) np.testing.assert_allclose(my_sigmas, ref_sigmas) np.testing.assert_allclose(my_f_ln, ref_f_ln) np.testing.assert_allclose(my_coordinates, ref_coordinates)
# Define a dictionary that describes the model. semantics = { "names": ["Significant wave height", "Zero-crossing period"], "symbols": ["H_s", "T_z"], "units": ["m", "s"], } # Fit the model to the data (estimate the model's parameter values). model.fit(data) # Print the estimated parameter values print(model) # Create plots to inspect the model's goodness-of-fit. fig1, axs = plt.subplots(1, 2, figsize=[10, 4.8]) plot_marginal_quantiles(model, data, semantics, axes=axs) fig2, axs = plt.subplots(1, 2, figsize=[10, 4.8]) plot_dependence_functions(model, semantics, axes=axs) # Compute an IFORM contour with a return period of 20 years. state_duration = 1 # hours return_period = 20 # years alpha = state_duration / (return_period * 365.25 * 24) contour = IFORMContour(model, alpha) # Plot the contour on top of a scatter diagram of the metocean data. ax = plot_2D_contour(contour, sample=data, semantics=semantics, swap_axis=True) plt.show()
ghm.distributions[0].beta, ghm.distributions[0].alpha, ) my_ln = ghm.distributions[1] my_given = np.arange(1, 10) my_f_ln = [] for given in my_given: my_f_ln.append(my_ln.pdf(x[:, 1], given)) my_f_ln = np.stack(my_f_ln, axis=1) state_duration = 3 return_period = 20 alpha = calculate_alpha(state_duration, return_period) my_iform = IFORMContour(ghm, alpha) my_coordinates = my_iform.coordinates # %% import sys sys.path.append("../viroconcom") from viroconcom.params import FunctionParam from viroconcom.distributions import ( ExponentiatedWeibullDistribution, LognormalDistribution, MultivariateDistribution, ) from viroconcom.contours import IFormContour