From 9c5c96588788cf51abbfb0069add39bb5a4209d5 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 17 May 2023 10:32:50 -0600 Subject: [PATCH] Per #2545, added range checking for the MODE interest_function piecewise linear functions, and updated the MODE documentation accordingly. --- docs/Users_Guide/mode.rst | 2 +- src/libcode/vx_shapedata/mode_conf_info.cc | 59 ++++++++++++++++++---- src/libcode/vx_shapedata/mode_conf_info.h | 2 + 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/docs/Users_Guide/mode.rst b/docs/Users_Guide/mode.rst index f5e4caf33f..2e3b93a08f 100644 --- a/docs/Users_Guide/mode.rst +++ b/docs/Users_Guide/mode.rst @@ -410,7 +410,7 @@ _____________________ inten_perc_ratio = ratio_if; } -The set of interest function entries listed above define which values are of interest for each pairwise attribute measured. The interest functions may be defined as a piecewise linear function or as an algebraic expression. A piecewise linear function is defined by specifying the corner points of its graph. An algebraic function may be defined in terms of several built-in mathematical functions. See :numref:`MODE_A-Scientific-and-statistical` for how interest values are used by the fuzzy logic engine. By default, many of these functions are defined in terms of the previously defined **grid_res** entry. +The interest function entries listed above define which values are of interest for each pairwise attribute measured. Each interest function is defined as a piecewise linear function by specifying the corner points of its graph. The range of each function must be within **0** and **1**. Including (x, y) points with y-values outside this range results in a runtime error. See :numref:`MODE_A-Scientific-and-statistical` for how interest values are used by the fuzzy logic engine. By default, many of these functions are defined in terms of the previously defined **grid_res** entry. _____________________ diff --git a/src/libcode/vx_shapedata/mode_conf_info.cc b/src/libcode/vx_shapedata/mode_conf_info.cc index eec28a0445..af16067528 100644 --- a/src/libcode/vx_shapedata/mode_conf_info.cc +++ b/src/libcode/vx_shapedata/mode_conf_info.cc @@ -468,16 +468,16 @@ PlotInfo plot_info; // Parse the interest functions - centroid_dist_if = dict->lookup_pwl(conf_key_centroid_dist); - boundary_dist_if = dict->lookup_pwl(conf_key_boundary_dist); - convex_hull_dist_if = dict->lookup_pwl(conf_key_convex_hull_dist); - angle_diff_if = dict->lookup_pwl(conf_key_angle_diff); - aspect_diff_if = dict->lookup_pwl(conf_key_aspect_diff); - area_ratio_if = dict->lookup_pwl(conf_key_area_ratio); - int_area_ratio_if = dict->lookup_pwl(conf_key_int_area_ratio); - curvature_ratio_if = dict->lookup_pwl(conf_key_curvature_ratio); - complexity_ratio_if = dict->lookup_pwl(conf_key_complexity_ratio); - inten_perc_ratio_if = dict->lookup_pwl(conf_key_inten_perc_ratio); + centroid_dist_if = parse_interest_function(dict, conf_key_centroid_dist); + boundary_dist_if = parse_interest_function(dict, conf_key_boundary_dist); + convex_hull_dist_if = parse_interest_function(dict, conf_key_convex_hull_dist); + angle_diff_if = parse_interest_function(dict, conf_key_angle_diff); + aspect_diff_if = parse_interest_function(dict, conf_key_aspect_diff); + area_ratio_if = parse_interest_function(dict, conf_key_area_ratio); + int_area_ratio_if = parse_interest_function(dict, conf_key_int_area_ratio); + curvature_ratio_if = parse_interest_function(dict, conf_key_curvature_ratio); + complexity_ratio_if = parse_interest_function(dict, conf_key_complexity_ratio); + inten_perc_ratio_if = parse_interest_function(dict, conf_key_inten_perc_ratio); // Conf: total_interest_thresh @@ -487,7 +487,7 @@ PlotInfo plot_info; if(total_interest_thresh < 0 || total_interest_thresh > 1) { mlog << Error << "\nModeConfInfo::process_config() -> " - << "total_interest_thresh (" << total_interest_thresh + << "\"total_interest_thresh\" (" << total_interest_thresh << ") must be set between 0 and 1.\n\n"; exit(1); } @@ -644,6 +644,43 @@ return; //////////////////////////////////////////////////////////////////////// +PiecewiseLinear * ModeConfInfo::parse_interest_function(Dictionary * dict, const char * conf_key_if) + +{ + + // + // lookup piecewise linear interest function + // + +PiecewiseLinear * pwl_if = dict->lookup_pwl(conf_key_if); + + // + // range check the points + // + +for (int j=0; jn_points(); ++j) { + + if ( pwl_if->y(j) < 0 || pwl_if->y(j) > 1 ) { + + mlog << Error << "\nModeConfInfo::parse_interest_function() -> " + << "all \"" << conf_key_if << "\" interest function points (" + << pwl_if->x(j) << ", " << pwl_if->y(j) + << ") must be in the range of 0 and 1.\n\n"; + + exit(1); + + } + +} // for j + +return ( pwl_if ); + +} + + +//////////////////////////////////////////////////////////////////////// + + void ModeConfInfo::set_field_index(int k) { diff --git a/src/libcode/vx_shapedata/mode_conf_info.h b/src/libcode/vx_shapedata/mode_conf_info.h index 136ac0641d..c9c063477a 100644 --- a/src/libcode/vx_shapedata/mode_conf_info.h +++ b/src/libcode/vx_shapedata/mode_conf_info.h @@ -117,6 +117,8 @@ class ModeConfInfo { void read_fields (Mode_Field_Info * &, Dictionary * dict, GrdFileType, char _fo); + PiecewiseLinear * parse_interest_function(Dictionary * dict, const char * conf_key_if); + // // weights //