From 142cdd05cb9145562a84d5dce13b0166bc99b980 Mon Sep 17 00:00:00 2001 From: Emily Howell Date: Thu, 5 Feb 2026 13:54:30 -0800 Subject: [PATCH 1/6] Save state post resolving conpilation bug :( --- .../ascent_runtime_param_check.cpp | 74 ++++++ .../ascent_runtime_param_check.hpp | 13 ++ .../ascent_runtime_vtkh_filters.cpp | 218 +++++++++--------- src/libs/flow/flow_filter.cpp | 28 ++- src/libs/flow/flow_filter.hpp | 1 + 5 files changed, 218 insertions(+), 116 deletions(-) diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp index fa8c76a3c..9291cb84e 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp @@ -58,6 +58,42 @@ bool is_valid_expression(const std::string expr, std::string &err_msg) return res; } +conduit::Node number_schema() +{ + conduit::Node n; + n["type"] = "number"; + return n; +} + +conduit::Node string_schema() +{ + conduit::Node n; + n["type"] = "string"; + return n; +} + +conduit::Node vec3_schema(const std::string var1, const std::string var2, const std::string var3) +{ + conduit::Node n; + n["type"] = "object"; + n["additionalProperties"] = false; + + n["properties/" + var1].set(number_schema()); + n["properties/" + var2].set(number_schema()); + n["properties/" + var3].set(number_schema()); + + n["required"].append() = var1; + n["required"].append() = var2; + n["required"].append() = var3; + + return n; +} + +conduit::Node vec3_schema() +{ + return vec3_schema("x", "y", "z"); +} + //----------------------------------------------------------------------------- bool check_numeric(const std::string path, @@ -322,6 +358,44 @@ surprise_check(const std::vector &valid_paths, return ss.str(); } +//----------------------------------------------------------------------------- +std::string +surprise_check(const conduit::Node &properties, + const conduit::Node ¶ms) +{ + // only children can surprise us + if(params.number_of_children() == 0) + { + return ""; + } + + std::stringstream ss; +// std::vector paths; +// path_helper(paths, params); +// const int num_paths = static_cast(paths.size()); +// // const int num_valid_paths = static_cast(properties.size()); +// std::string curr_path = params.path() == "" ? "" :params.path() + "/"; +// for(int i = 0; i < num_paths; ++i) +// { +// bool found = false; +// for(int f = 0; f < num_valid_paths; ++f) +// { +// if(curr_path + valid_paths[f] == paths[i]) +// { +// found = true; +// break; +// } +// } + +// if(!found) +// { +// ss<<"Surprise parameter '"< &paths, const conduit::Node &node) diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp index c2874fe43..9c0c557f3 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp @@ -41,6 +41,16 @@ namespace runtime namespace filters { +conduit::Node ASCENT_API number_schema(); + +conduit::Node ASCENT_API string_schema(); + +conduit::Node ASCENT_API vec3_schema(); + +conduit::Node ASCENT_API vec3_schema(const std::string var1, + const std::string var2, + const std::string var3); + bool ASCENT_API check_numeric(const std::string path, const conduit::Node ¶ms, conduit::Node &info, @@ -77,6 +87,9 @@ void ASCENT_API path_helper(std::vector &paths, std::string ASCENT_API surprise_check(const std::vector &valid_paths, const conduit::Node &node); + +std::string ASCENT_API surprise_check(const conduit::Node &properties, + const conduit::Node &node); // // Ignore paths only ignores top level paths, differing lower level // paths to another surprise check. diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp index 6f4684f10..2a3b91b5b 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp @@ -806,6 +806,102 @@ VTKHSlice::declare_interface(Node &i) i["type_name"] = "vtkh_slice"; i["port_names"].append() = "in"; i["output_port"] = "true"; + + // ----------- Define Param Schema ----------- + conduit::Node vtkhslice_schema; + vtkhslice_schema["type"] = "object"; + vtkhslice_schema["additionalProperties"] = false; + vtkhslice_schema["constraints/exclusiveChildren"].append() = "sphere"; + vtkhslice_schema["constraints/exclusiveChildren"].append() = "cylinder"; + vtkhslice_schema["constraints/exclusiveChildren"].append() = "box"; + vtkhslice_schema["constraints/exclusiveChildren"].append() = "plane"; + vtkhslice_schema["constraints/exclusiveChildren"].append() = "point"; + vtkhslice_schema["constraints/allowNoneInExclusiveGroup"] = false; + + // optional + vtkhslice_schema["properties/topology"].set(string_schema()); + + // --- sphere --- + conduit::Node sphere_schema; + sphere_schema["type"] = "object"; + sphere_schema["additionalProperties"] = false; + sphere_schema["properties/center"].set(vec3_schema()); + sphere_schema["properties/radius"].set(number_schema()); + sphere_schema["required"].append() = "center"; + sphere_schema["required"].append() = "radius"; + vtkhslice_schema["properties/sphere"].set(sphere_schema); + + // --- cylinder --- + conduit::Node cylinder_schema; + cylinder_schema["type"] = "object"; + cylinder_schema["additionalProperties"] = false; + cylinder_schema["properties/center"].set(vec3_schema()); + cylinder_schema["properties/axis"].set(vec3_schema()); + cylinder_schema["properties/radius"].set(number_schema()); + cylinder_schema["required"].append() = "center"; + cylinder_schema["required"].append() = "axis"; + cylinder_schema["required"].append() = "radius"; + vtkhslice_schema["properties/cylinder"].set(cylinder_schema); + + // --- box --- + conduit::Node box_schema; + box_schema["type"] = "object"; + box_schema["additionalProperties"] = false; + box_schema["properties/min"].set(vec3_schema()); + box_schema["properties/max"].set(vec3_schema()); + box_schema["required"].append() = "min"; + box_schema["required"].append() = "max"; + vtkhslice_schema["properties/box"].set(box_schema); + + // --- plane --- + conduit::Node plane_schema; + plane_schema["type"] = "object"; + plane_schema["additionalProperties"] = false; + plane_schema["properties/point"].set(vec3_schema()); + plane_schema["properties/normal"].set(vec3_schema()); + plane_schema["required"].append() = "point"; + plane_schema["required"].append() = "normal"; + vtkhslice_schema["properties/plane"].set(plane_schema); + + // --- old point style + conduit::Node point_schema; + point_schema["type"] = "object"; + point_schema["additionalProperties"] = false; + + point_schema["properties/x"].set(number_schema()); + point_schema["properties/y"].set(number_schema()); + point_schema["properties/z"].set(number_schema()); + point_schema["properties/x_offset"].set(number_schema()); + point_schema["properties/y_offset"].set(number_schema()); + point_schema["properties/z_offset"].set(number_schema()); + + // Option A: explicit + conduit::Node option_1_explicit; + option_1_explicit["type"] = "object"; + option_1_explicit["required"].append() = "x"; + option_1_explicit["required"].append() = "y"; + option_1_explicit["required"].append() = "z"; + option_1_explicit["constraints/forbid"].append() = "x_offset"; + option_1_explicit["constraints/forbid"].append() = "y_offset"; + option_1_explicit["constraints/forbid"].append() = "z_offset"; + point_schema["oneOf"].append().set(option_1_explicit); + + // Option B: offset + conduit::Node option_2_offset; + option_2_offset["type"] = "object"; + option_2_offset["required"].append() = "x_offset"; + option_2_offset["required"].append() = "y_offset"; + option_2_offset["required"].append() = "z_offset"; + option_2_offset["constraints/forbid"].append() = "x"; + option_2_offset["constraints/forbid"].append() = "y"; + option_2_offset["constraints/forbid"].append() = "z"; + point_schema["oneOf"].append().set(option_2_offset); + + vtkhslice_schema["properties/point"].set(point_schema); + vtkhslice_schema["properties/normal"].set(vec3_schema()); + vtkhslice_schema["constraints/dependencies/normal"].append() = "point"; + + i["param_schema"].set(vtkhslice_schema); } //----------------------------------------------------------------------------- @@ -815,129 +911,21 @@ VTKHSlice::verify_params(const conduit::Node ¶ms, { info.reset(); - bool res = true; - - res &= check_string("topology",params, info, false); - if(params.has_child("sphere")) - { - res = check_numeric("sphere/center/x",params, info, true, true) && res; - res = check_numeric("sphere/center/y",params, info, true, true) && res; - res = check_numeric("sphere/center/z",params, info, true, true) && res; - res = check_numeric("sphere/radius",params, info, true, true) && res; - } - else if(params.has_child("cylinder")) - { - res = check_numeric("cylinder/center/x",params, info, true, true) && res; - res = check_numeric("cylinder/center/y",params, info, true, true) && res; - res = check_numeric("cylinder/center/z",params, info, true, true) && res; - res = check_numeric("cylinder/axis/x",params, info, true, true) && res; - res = check_numeric("cylinder/axis/y",params, info, true, true) && res; - res = check_numeric("cylinder/axis/z",params, info, true, true) && res; - res = check_numeric("cylinder/radius",params, info, true, true) && res; - } - else if(params.has_child("box")) - { - res = check_numeric("box/min/x",params, info, true, true) && res; - res = check_numeric("box/min/y",params, info, true, true) && res; - res = check_numeric("box/min/z",params, info, true, true) && res; - res = check_numeric("box/max/x",params, info, true, true) && res; - res = check_numeric("box/max/y",params, info, true, true) && res; - res = check_numeric("box/max/z",params, info, true, true) && res; - } - else if(params.has_child("plane")) - { - res = check_numeric("plane/point/x",params, info, true, true) && res; - res = check_numeric("plane/point/y",params, info, true, true) && res; - res = check_numeric("plane/point/z",params, info, true, true) && res; - res = check_numeric("plane/normal/x",params, info, true, true) && res; - res = check_numeric("plane/normal/y",params, info, true, true) && res; - res = check_numeric("plane/normal/z",params, info, true, true) && res; - } - - // old style plane - if(params.has_path("point/x_offset") && params.has_path("point/x")) - { - info["errors"] - .append() = "Cannot specify the plane point as both an offset and explicit point"; - res = false; - } - - if(params.has_path("point/x")) - { - res &= check_numeric("point/x",params, info, true, true); - res = check_numeric("point/y",params, info, true, true) && res; - res = check_numeric("point/z",params, info, true, true) && res; - } - else if(params.has_path("point/x_offset")) - { - res &= check_numeric("point/x_offset",params, info, true, true); - res = check_numeric("point/y_offset",params, info, true, true) && res; - res = check_numeric("point/z_offset",params, info, true, true) && res; - } - // else - // { - // info["errors"] - // .append() = "Slice must specify a point for the plane."; - // res = false; - // } - if(params.has_path("normal/x")) - { - res = check_numeric("normal/x",params, info, true, true) && res; - res = check_numeric("normal/y",params, info, true, true) && res; - res = check_numeric("normal/z",params, info, true, true) && res; - } - - std::vector valid_paths; - // old style plane - valid_paths.push_back("point/x"); - valid_paths.push_back("point/y"); - valid_paths.push_back("point/z"); - valid_paths.push_back("point/x_offset"); - valid_paths.push_back("point/y_offset"); - valid_paths.push_back("point/z_offset"); - valid_paths.push_back("normal/x"); - valid_paths.push_back("normal/y"); - valid_paths.push_back("normal/z"); - valid_paths.push_back("topology"); - - // sphere - valid_paths.push_back("sphere/center/x"); - valid_paths.push_back("sphere/center/y"); - valid_paths.push_back("sphere/center/z"); - valid_paths.push_back("sphere/radius"); - // cylinder - valid_paths.push_back("cylinder/center/x"); - valid_paths.push_back("cylinder/center/y"); - valid_paths.push_back("cylinder/center/z"); - valid_paths.push_back("cylinder/axis/x"); - valid_paths.push_back("cylinder/axis/y"); - valid_paths.push_back("cylinder/axis/z"); - valid_paths.push_back("cylinder/radius"); - // box - valid_paths.push_back("box/min/x"); - valid_paths.push_back("box/min/y"); - valid_paths.push_back("box/min/z"); - valid_paths.push_back("box/max/x"); - valid_paths.push_back("box/max/y"); - valid_paths.push_back("box/max/z"); - // new style plane - valid_paths.push_back("plane/point/x"); - valid_paths.push_back("plane/point/y"); - valid_paths.push_back("plane/point/z"); - valid_paths.push_back("plane/normal/x"); - valid_paths.push_back("plane/normal/y"); - valid_paths.push_back("plane/normal/z"); + std::cout << "\nSlice Properties!!" << std::endl; + param_schema().print(); + std::cout << "\nParams!!" << std::endl; + params.print(); - std::string surprises = surprise_check(valid_paths, params); + std::string surprises = surprise_check(param_schema(), params); if(surprises != "") { - res = false; info["errors"].append() = surprises; + return false; } - return res; + return true; } //----------------------------------------------------------------------------- diff --git a/src/libs/flow/flow_filter.cpp b/src/libs/flow/flow_filter.cpp index 4bce67aa1..39691752b 100644 --- a/src/libs/flow/flow_filter.cpp +++ b/src/libs/flow/flow_filter.cpp @@ -111,6 +111,10 @@ Filter::init(Graph *g, n_iface["port_names"] = DataType::empty(); } + if( !n_iface.has_child("param_schema") ) + { + n_iface["param_schema"] = DataType::empty(); + } params().update(default_params()); params().update(p); @@ -137,6 +141,13 @@ Filter::default_params() const return properties()["interface/default_params"]; } +//----------------------------------------------------------------------------- +const Node & +Filter::param_schema() const +{ + return properties()["interface/param_schema"]; +} + //----------------------------------------------------------------------------- const Node & Filter::port_names() const @@ -209,10 +220,25 @@ Filter::params() //----------------------------------------------------------------------------- bool -Filter::verify_params(const Node &, // unused: params, +Filter::verify_params(const Node ¶ms, Node &info) { info.reset(); + + std::cout << "\nSlice Properties!!" << std::endl; + param_schema().print(); + + std::cout << "\nParams!!" << std::endl; + params.print(); + + std::string surprises = "";// surprise_check(param_schema(), params); + + if(surprises != "") + { + info["errors"].append() = surprises; + return false; + } + return true; } diff --git a/src/libs/flow/flow_filter.hpp b/src/libs/flow/flow_filter.hpp index 7fbccd00c..f5d7258e5 100644 --- a/src/libs/flow/flow_filter.hpp +++ b/src/libs/flow/flow_filter.hpp @@ -138,6 +138,7 @@ class FLOW_API Filter bool output_port() const; const conduit::Node &default_params() const; + const conduit::Node ¶m_schema() const; int number_of_input_ports() const; bool has_port(const std::string &name) const; From f11830765edcf8f08d7e2957c3e913390627819d Mon Sep 17 00:00:00 2001 From: Emily Howell Date: Thu, 5 Feb 2026 14:42:33 -0800 Subject: [PATCH 2/6] Removing slide verify_params --- .../ascent_runtime_vtkh_filters.cpp | 24 ------------------- .../ascent_runtime_vtkh_filters.hpp | 2 -- 2 files changed, 26 deletions(-) diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp index 2a3b91b5b..9a4e85016 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp @@ -904,30 +904,6 @@ VTKHSlice::declare_interface(Node &i) i["param_schema"].set(vtkhslice_schema); } -//----------------------------------------------------------------------------- -bool -VTKHSlice::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - std::cout << "\nSlice Properties!!" << std::endl; - param_schema().print(); - - std::cout << "\nParams!!" << std::endl; - params.print(); - - std::string surprises = surprise_check(param_schema(), params); - - if(surprises != "") - { - info["errors"].append() = surprises; - return false; - } - - return true; -} - //----------------------------------------------------------------------------- void VTKHSlice::execute() diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp index b52f95815..1c5386777 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp @@ -90,8 +90,6 @@ class ASCENT_API VTKHSlice : public ::flow::Filter virtual ~VTKHSlice(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; From 736daf9a6bf88bbff2ab2a66f498e2c5458430b4 Mon Sep 17 00:00:00 2001 From: Emily Howell Date: Tue, 24 Feb 2026 12:37:06 -0800 Subject: [PATCH 3/6] Adding some more json schema examples --- .../ascent_runtime_vtkh_filters.cpp | 667 ++++++------------ .../ascent_runtime_vtkh_filters.hpp | 14 - 2 files changed, 207 insertions(+), 474 deletions(-) diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp index 9a4e85016..8fcbee5f7 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp @@ -708,32 +708,16 @@ VTKHCleanGrid::declare_interface(Node &i) i["type_name"] = "vtkh_clean"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHCleanGrid::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = true; - - res = check_string("topology",params, info, false) && res; - - std::vector valid_paths; - valid_paths.push_back("topology"); - - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + // optional + param_schema["properties/topology"].set(string_schema()); + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -808,18 +792,18 @@ VTKHSlice::declare_interface(Node &i) i["output_port"] = "true"; // ----------- Define Param Schema ----------- - conduit::Node vtkhslice_schema; - vtkhslice_schema["type"] = "object"; - vtkhslice_schema["additionalProperties"] = false; - vtkhslice_schema["constraints/exclusiveChildren"].append() = "sphere"; - vtkhslice_schema["constraints/exclusiveChildren"].append() = "cylinder"; - vtkhslice_schema["constraints/exclusiveChildren"].append() = "box"; - vtkhslice_schema["constraints/exclusiveChildren"].append() = "plane"; - vtkhslice_schema["constraints/exclusiveChildren"].append() = "point"; - vtkhslice_schema["constraints/allowNoneInExclusiveGroup"] = false; + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + param_schema["constraints/exclusiveChildren"].append() = "sphere"; + param_schema["constraints/exclusiveChildren"].append() = "cylinder"; + param_schema["constraints/exclusiveChildren"].append() = "box"; + param_schema["constraints/exclusiveChildren"].append() = "plane"; + param_schema["constraints/exclusiveChildren"].append() = "point"; + param_schema["constraints/allowNoneInExclusiveGroup"] = false; // optional - vtkhslice_schema["properties/topology"].set(string_schema()); + param_schema["properties/topology"].set(string_schema()); // --- sphere --- conduit::Node sphere_schema; @@ -829,7 +813,7 @@ VTKHSlice::declare_interface(Node &i) sphere_schema["properties/radius"].set(number_schema()); sphere_schema["required"].append() = "center"; sphere_schema["required"].append() = "radius"; - vtkhslice_schema["properties/sphere"].set(sphere_schema); + param_schema["properties/sphere"].set(sphere_schema); // --- cylinder --- conduit::Node cylinder_schema; @@ -841,7 +825,7 @@ VTKHSlice::declare_interface(Node &i) cylinder_schema["required"].append() = "center"; cylinder_schema["required"].append() = "axis"; cylinder_schema["required"].append() = "radius"; - vtkhslice_schema["properties/cylinder"].set(cylinder_schema); + param_schema["properties/cylinder"].set(cylinder_schema); // --- box --- conduit::Node box_schema; @@ -851,7 +835,7 @@ VTKHSlice::declare_interface(Node &i) box_schema["properties/max"].set(vec3_schema()); box_schema["required"].append() = "min"; box_schema["required"].append() = "max"; - vtkhslice_schema["properties/box"].set(box_schema); + param_schema["properties/box"].set(box_schema); // --- plane --- conduit::Node plane_schema; @@ -861,7 +845,7 @@ VTKHSlice::declare_interface(Node &i) plane_schema["properties/normal"].set(vec3_schema()); plane_schema["required"].append() = "point"; plane_schema["required"].append() = "normal"; - vtkhslice_schema["properties/plane"].set(plane_schema); + param_schema["properties/plane"].set(plane_schema); // --- old point style conduit::Node point_schema; @@ -897,11 +881,11 @@ VTKHSlice::declare_interface(Node &i) option_2_offset["constraints/forbid"].append() = "z"; point_schema["oneOf"].append().set(option_2_offset); - vtkhslice_schema["properties/point"].set(point_schema); - vtkhslice_schema["properties/normal"].set(vec3_schema()); - vtkhslice_schema["constraints/dependencies/normal"].append() = "point"; + param_schema["properties/point"].set(point_schema); + param_schema["properties/normal"].set(vec3_schema()); + param_schema["constraints/dependencies/normal"].append() = "point"; - i["param_schema"].set(vtkhslice_schema); + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1082,48 +1066,21 @@ VTKHAutoSliceLevels::declare_interface(Node &i) i["type_name"] = "vtkh_autoslicelevels"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHAutoSliceLevels::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_string("field",params, info, true); - - if(!params.has_path("levels")) - { - info["errors"] - .append() = "AutoSliceLevels must specify number of slices to consider via 'levels'."; - res = false; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - res = check_numeric("normal/x",params, info, true, true) && res; - res = check_numeric("normal/y",params, info, true, true) && res; - res = check_numeric("normal/z",params, info, true, true) && res; - - res = check_numeric("levels",params, info, true, true) && res; - - std::vector valid_paths; - valid_paths.push_back("levels"); - valid_paths.push_back("field"); - valid_paths.push_back("normal/x"); - valid_paths.push_back("normal/y"); - valid_paths.push_back("normal/z"); - + param_schema["properties/field"].set(string_schema()); + param_schema["properties/normal"].set(vec3_schema()); + param_schema["properties/levels"].set(number_schema()); - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; + param_schema["required"].append() = "field"; + param_schema["required"].append() = "normal"; + param_schema["required"].append() = "levels"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1283,33 +1240,21 @@ VTKHGhostStripper::declare_interface(Node &i) i["type_name"] = "vtkh_ghost_stripper"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHGhostStripper::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - - res = check_numeric("min_value",params, info, true, true) && res; - res = check_numeric("max_value",params, info, true, true) && res; - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("min_value"); - valid_paths.push_back("max_value"); - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/min_value"].set(number_schema()); + param_schema["properties/max_value"].set(number_schema()); - return res; + param_schema["required"].append() = "field"; + param_schema["required"].append() = "min_value"; + param_schema["required"].append() = "max_value"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1396,31 +1341,17 @@ VTKHAddRanks::declare_interface(Node &i) i["type_name"] = "vtkh_add_mpi_ranks"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHAddRanks::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("topology",params, info, false); - res = check_string("output",params, info, false); - - std::vector valid_paths; - valid_paths.push_back("output"); - valid_paths.push_back("topology"); - - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + // optional + param_schema["properties/topology"].set(string_schema()); + param_schema["properties/output"].set(string_schema()); + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1505,31 +1436,17 @@ VTKHAddDomains::declare_interface(Node &i) i["type_name"] = "vtkh_add_domain_ids"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -VTKHAddDomains::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_string("topology",params, info, false); - res = check_string("output",params, info, false); - - std::vector valid_paths; - valid_paths.push_back("output"); - valid_paths.push_back("topology"); - - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + // optional + param_schema["properties/topology"].set(string_schema()); + param_schema["properties/output"].set(string_schema()); + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1609,177 +1526,86 @@ VTKHThreshold::declare_interface(Node &i) i["type_name"] = "vtkh_threshold"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHThreshold::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - - bool type_present = false; - - if(params.has_child("field")) - { - type_present = true; - } - else if(params.has_child("sphere")) - { - type_present = true; - } - else if(params.has_child("cylinder")) - { - type_present = true; - } - else if(params.has_child("box")) - { - type_present = true; - } - else if(params.has_child("plane")) - { - type_present = true; - } - else if(params.has_child("multi_plane")) - { - type_present = true; - } - - if(!type_present) - { - info["errors"].append() = "Missing required parameter. Threshold must specify 'field', 'sphere', 'cylinder', 'box', or 'plane'"; - res = false; - } - else - { - if(params.has_child("sphere")) - { - res = check_numeric("sphere/center/x",params, info, true, true) && res; - res = check_numeric("sphere/center/y",params, info, true, true) && res; - res = check_numeric("sphere/center/z",params, info, true, true) && res; - res = check_numeric("sphere/radius",params, info, true, true) && res; - } - else if(params.has_child("cylinder")) - { - res = check_numeric("cylinder/center/x",params, info, true, true) && res; - res = check_numeric("cylinder/center/y",params, info, true, true) && res; - res = check_numeric("cylinder/center/z",params, info, true, true) && res; - res = check_numeric("cylinder/axis/x",params, info, true, true) && res; - res = check_numeric("cylinder/axis/y",params, info, true, true) && res; - res = check_numeric("cylinder/axis/z",params, info, true, true) && res; - res = check_numeric("cylinder/radius",params, info, true, true) && res; - } - else if(params.has_child("box")) - { - res = check_numeric("box/min/x",params, info, true, true) && res; - res = check_numeric("box/min/y",params, info, true, true) && res; - res = check_numeric("box/min/z",params, info, true, true) && res; - res = check_numeric("box/max/x",params, info, true, true) && res; - res = check_numeric("box/max/y",params, info, true, true) && res; - res = check_numeric("box/max/z",params, info, true, true) && res; - } - else if(params.has_child("plane")) - { - res = check_numeric("plane/point/x",params, info, true, true) && res; - res = check_numeric("plane/point/y",params, info, true, true) && res; - res = check_numeric("plane/point/z",params, info, true, true) && res; - res = check_numeric("plane/normal/x",params, info, true, true) && res; - res = check_numeric("plane/normal/y",params, info, true, true) && res; - res = check_numeric("plane/normal/z",params, info, true, true) && res; - } - else if(params.has_child("multi_plane")) - { - res = check_numeric("multi_plane/point1/x",params, info, true, true) && res; - res = check_numeric("multi_plane/point1/y",params, info, true, true) && res; - res = check_numeric("multi_plane/point1/z",params, info, true, true) && res; - res = check_numeric("multi_plane/normal1/x",params, info, true, true) && res; - res = check_numeric("multi_plane/normal1/y",params, info, true, true) && res; - res = check_numeric("multi_plane/normal1/z",params, info, true, true) && res; - - res = check_numeric("multi_plane/point2/x",params, info, true, true) && res; - res = check_numeric("multi_plane/point2/y",params, info, true, true) && res; - res = check_numeric("multi_plane/point2/z",params, info, true, true) && res; - res = check_numeric("multi_plane/normal2/x",params, info, true, true) && res; - res = check_numeric("multi_plane/normal2/y",params, info, true, true) && res; - res = check_numeric("multi_plane/normal2/z",params, info, true, true) && res; - } - } - // we either need 'field` or `topology` - if(!params.has_child("field")) - { - res &= check_string("topology",params, info, false); - } - - // field case - res = check_string("field",params, info, false); - res = check_numeric("min_value",params, info, false, true) && res; - res = check_numeric("max_value",params, info, false, true) && res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + param_schema["constraints/exclusiveChildren"].append() = "field"; + param_schema["constraints/exclusiveChildren"].append() = "sphere"; + param_schema["constraints/exclusiveChildren"].append() = "cylinder"; + param_schema["constraints/exclusiveChildren"].append() = "box"; + param_schema["constraints/exclusiveChildren"].append() = "plane"; + param_schema["constraints/exclusiveChildren"].append() = "multi_plane"; + param_schema["constraints/allowNoneInExclusiveGroup"] = false; - res = check_string("invert",params, info, false) && res; + // optional + param_schema["properties/field"].set(string_schema()); + param_schema["properties/topology"].set(string_schema()); + param_schema["properties/min_value"].set(number_schema()); + param_schema["properties/max_value"].set(number_schema()); + param_schema["properties/invert"].set(string_schema()); + param_schema["properties/extract"].set(string_schema()); - std::vector valid_paths; - valid_paths.push_back("invert"); - valid_paths.push_back("field"); - valid_paths.push_back("min_value"); - valid_paths.push_back("max_value"); + // --- sphere --- + conduit::Node sphere_schema; + sphere_schema["type"] = "object"; + sphere_schema["additionalProperties"] = false; + sphere_schema["properties/center"].set(vec3_schema()); + sphere_schema["properties/radius"].set(number_schema()); + sphere_schema["required"].append() = "center"; + sphere_schema["required"].append() = "radius"; + param_schema["properties/sphere"].set(sphere_schema); - valid_paths.push_back("topology"); - valid_paths.push_back("extract"); - - valid_paths.push_back("sphere/center/x"); - valid_paths.push_back("sphere/center/y"); - valid_paths.push_back("sphere/center/z"); - valid_paths.push_back("sphere/radius"); - - valid_paths.push_back("cylinder/center/x"); - valid_paths.push_back("cylinder/center/y"); - valid_paths.push_back("cylinder/center/z"); - valid_paths.push_back("cylinder/axis/x"); - valid_paths.push_back("cylinder/axis/y"); - valid_paths.push_back("cylinder/axis/z"); - valid_paths.push_back("cylinder/radius"); - - valid_paths.push_back("box/min/x"); - valid_paths.push_back("box/min/y"); - valid_paths.push_back("box/min/z"); - valid_paths.push_back("box/max/x"); - valid_paths.push_back("box/max/y"); - valid_paths.push_back("box/max/z"); - - valid_paths.push_back("plane/point/x"); - valid_paths.push_back("plane/point/y"); - valid_paths.push_back("plane/point/z"); - valid_paths.push_back("plane/normal/x"); - valid_paths.push_back("plane/normal/y"); - valid_paths.push_back("plane/normal/z"); - - valid_paths.push_back("multi_plane/point1/x"); - valid_paths.push_back("multi_plane/point1/y"); - valid_paths.push_back("multi_plane/point1/z"); - valid_paths.push_back("multi_plane/normal1/x"); - valid_paths.push_back("multi_plane/normal1/y"); - valid_paths.push_back("multi_plane/normal1/z"); - - valid_paths.push_back("multi_plane/point2/x"); - valid_paths.push_back("multi_plane/point2/y"); - valid_paths.push_back("multi_plane/point2/z"); - valid_paths.push_back("multi_plane/normal2/x"); - valid_paths.push_back("multi_plane/normal2/y"); - valid_paths.push_back("multi_plane/normal2/z"); - std::string surprises = surprise_check(valid_paths, params); + // --- cylinder --- + conduit::Node cylinder_schema; + cylinder_schema["type"] = "object"; + cylinder_schema["additionalProperties"] = false; + cylinder_schema["properties/center"].set(vec3_schema()); + cylinder_schema["properties/axis"].set(vec3_schema()); + cylinder_schema["properties/radius"].set(number_schema()); + cylinder_schema["required"].append() = "center"; + cylinder_schema["required"].append() = "axis"; + cylinder_schema["required"].append() = "radius"; + param_schema["properties/cylinder"].set(cylinder_schema); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // --- box --- + conduit::Node box_schema; + box_schema["type"] = "object"; + box_schema["additionalProperties"] = false; + box_schema["properties/min"].set(vec3_schema()); + box_schema["properties/max"].set(vec3_schema()); + box_schema["required"].append() = "min"; + box_schema["required"].append() = "max"; + param_schema["properties/box"].set(box_schema); - return res; + // --- plane --- + conduit::Node plane_schema; + plane_schema["type"] = "object"; + plane_schema["additionalProperties"] = false; + plane_schema["properties/point"].set(vec3_schema()); + plane_schema["properties/normal"].set(vec3_schema()); + plane_schema["required"].append() = "point"; + plane_schema["required"].append() = "normal"; + param_schema["properties/plane"].set(plane_schema); + + // --- multi plane --- + conduit::Node multi_plane_schema; + multi_plane_schema["type"] = "object"; + multi_plane_schema["additionalProperties"] = false; + multi_plane_schema["properties/point1"].set(vec3_schema()); + multi_plane_schema["properties/point2"].set(vec3_schema()); + multi_plane_schema["properties/normal1"].set(vec3_schema()); + multi_plane_schema["properties/normal2"].set(vec3_schema()); + multi_plane_schema["required"].append() = "point1"; + multi_plane_schema["required"].append() = "point2"; + multi_plane_schema["required"].append() = "normal1"; + multi_plane_schema["required"].append() = "normal2"; + param_schema["properties/multi_plane"].set(multi_plane_schema); + + i["param_schema"].set(param_schema); } - //----------------------------------------------------------------------------- void VTKHThreshold::execute() @@ -1971,160 +1797,81 @@ VTKHClip::declare_interface(Node &i) i["type_name"] = "vtkh_clip"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHClip::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - - bool type_present = false; - - if(params.has_child("sphere")) - { - type_present = true; - } - else if(params.has_child("cylinder")) - { - type_present = true; - } - else if(params.has_child("box")) - { - type_present = true; - } - else if(params.has_child("plane")) - { - type_present = true; - } - else if(params.has_child("multi_plane")) - { - type_present = true; - } - if(!type_present) - { - info["errors"].append() = "Missing required parameter. Clip must specify a 'sphere', 'cylinder', 'box', 'plane', or 'mulit_plane'"; - res = false; - } - else - { - - res &= check_string("topology",params, info, false); - if(params.has_child("sphere")) - { - res = check_numeric("sphere/center/x",params, info, true, true) && res; - res = check_numeric("sphere/center/y",params, info, true, true) && res; - res = check_numeric("sphere/center/z",params, info, true, true) && res; - res = check_numeric("sphere/radius",params, info, true, true) && res; - } - else if(params.has_child("cylinder")) - { - res = check_numeric("cylinder/center/x",params, info, true, true) && res; - res = check_numeric("cylinder/center/y",params, info, true, true) && res; - res = check_numeric("cylinder/center/z",params, info, true, true) && res; - res = check_numeric("cylinder/axis/x",params, info, true, true) && res; - res = check_numeric("cylinder/axis/y",params, info, true, true) && res; - res = check_numeric("cylinder/axis/z",params, info, true, true) && res; - res = check_numeric("cylinder/radius",params, info, true, true) && res; - } - else if(params.has_child("box")) - { - res = check_numeric("box/min/x",params, info, true, true) && res; - res = check_numeric("box/min/y",params, info, true, true) && res; - res = check_numeric("box/min/z",params, info, true, true) && res; - res = check_numeric("box/max/x",params, info, true, true) && res; - res = check_numeric("box/max/y",params, info, true, true) && res; - res = check_numeric("box/max/z",params, info, true, true) && res; - } - else if(params.has_child("plane")) - { - res = check_numeric("plane/point/x",params, info, true, true) && res; - res = check_numeric("plane/point/y",params, info, true, true) && res; - res = check_numeric("plane/point/z",params, info, true, true) && res; - res = check_numeric("plane/normal/x",params, info, true, true) && res; - res = check_numeric("plane/normal/y",params, info, true, true) && res; - res = check_numeric("plane/normal/z",params, info, true, true) && res; - } - else if(params.has_child("multi_plane")) - { - res = check_numeric("multi_plane/point1/x",params, info, true, true) && res; - res = check_numeric("multi_plane/point1/y",params, info, true, true) && res; - res = check_numeric("multi_plane/point1/z",params, info, true, true) && res; - res = check_numeric("multi_plane/normal1/x",params, info, true, true) && res; - res = check_numeric("multi_plane/normal1/y",params, info, true, true) && res; - res = check_numeric("multi_plane/normal1/z",params, info, true, true) && res; - - res = check_numeric("multi_plane/point2/x",params, info, true, true) && res; - res = check_numeric("multi_plane/point2/y",params, info, true, true) && res; - res = check_numeric("multi_plane/point2/z",params, info, true, true) && res; - res = check_numeric("multi_plane/normal2/x",params, info, true, true) && res; - res = check_numeric("multi_plane/normal2/y",params, info, true, true) && res; - res = check_numeric("multi_plane/normal2/z",params, info, true, true) && res; - } - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + param_schema["constraints/exclusiveChildren"].append() = "sphere"; + param_schema["constraints/exclusiveChildren"].append() = "cylinder"; + param_schema["constraints/exclusiveChildren"].append() = "box"; + param_schema["constraints/exclusiveChildren"].append() = "plane"; + param_schema["constraints/exclusiveChildren"].append() = "multi_plane"; + param_schema["constraints/allowNoneInExclusiveGroup"] = false; - res = check_string("invert",params, info, false) && res; - res = check_string("topology",params, info, false) && res; + // optional + param_schema["properties/topology"].set(string_schema()); + param_schema["properties/invert"].set(string_schema()); - std::vector valid_paths; - valid_paths.push_back("topology"); - valid_paths.push_back("invert"); + // --- sphere --- + conduit::Node sphere_schema; + sphere_schema["type"] = "object"; + sphere_schema["additionalProperties"] = false; + sphere_schema["properties/center"].set(vec3_schema()); + sphere_schema["properties/radius"].set(number_schema()); + sphere_schema["required"].append() = "center"; + sphere_schema["required"].append() = "radius"; + param_schema["properties/sphere"].set(sphere_schema); - valid_paths.push_back("sphere/center/x"); - valid_paths.push_back("sphere/center/y"); - valid_paths.push_back("sphere/center/z"); - valid_paths.push_back("sphere/radius"); - - valid_paths.push_back("cylinder/center/x"); - valid_paths.push_back("cylinder/center/y"); - valid_paths.push_back("cylinder/center/z"); - valid_paths.push_back("cylinder/axis/x"); - valid_paths.push_back("cylinder/axis/y"); - valid_paths.push_back("cylinder/axis/z"); - valid_paths.push_back("cylinder/radius"); - - valid_paths.push_back("box/min/x"); - valid_paths.push_back("box/min/y"); - valid_paths.push_back("box/min/z"); - valid_paths.push_back("box/max/x"); - valid_paths.push_back("box/max/y"); - valid_paths.push_back("box/max/z"); - - valid_paths.push_back("plane/point/x"); - valid_paths.push_back("plane/point/y"); - valid_paths.push_back("plane/point/z"); - valid_paths.push_back("plane/normal/x"); - valid_paths.push_back("plane/normal/y"); - valid_paths.push_back("plane/normal/z"); - - valid_paths.push_back("multi_plane/point1/x"); - valid_paths.push_back("multi_plane/point1/y"); - valid_paths.push_back("multi_plane/point1/z"); - valid_paths.push_back("multi_plane/normal1/x"); - valid_paths.push_back("multi_plane/normal1/y"); - valid_paths.push_back("multi_plane/normal1/z"); - - valid_paths.push_back("multi_plane/point2/x"); - valid_paths.push_back("multi_plane/point2/y"); - valid_paths.push_back("multi_plane/point2/z"); - valid_paths.push_back("multi_plane/normal2/x"); - valid_paths.push_back("multi_plane/normal2/y"); - valid_paths.push_back("multi_plane/normal2/z"); - std::string surprises = surprise_check(valid_paths, params); + // --- cylinder --- + conduit::Node cylinder_schema; + cylinder_schema["type"] = "object"; + cylinder_schema["additionalProperties"] = false; + cylinder_schema["properties/center"].set(vec3_schema()); + cylinder_schema["properties/axis"].set(vec3_schema()); + cylinder_schema["properties/radius"].set(number_schema()); + cylinder_schema["required"].append() = "center"; + cylinder_schema["required"].append() = "axis"; + cylinder_schema["required"].append() = "radius"; + param_schema["properties/cylinder"].set(cylinder_schema); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // --- box --- + conduit::Node box_schema; + box_schema["type"] = "object"; + box_schema["additionalProperties"] = false; + box_schema["properties/min"].set(vec3_schema()); + box_schema["properties/max"].set(vec3_schema()); + box_schema["required"].append() = "min"; + box_schema["required"].append() = "max"; + param_schema["properties/box"].set(box_schema); - return res; + // --- plane --- + conduit::Node plane_schema; + plane_schema["type"] = "object"; + plane_schema["additionalProperties"] = false; + plane_schema["properties/point"].set(vec3_schema()); + plane_schema["properties/normal"].set(vec3_schema()); + plane_schema["required"].append() = "point"; + plane_schema["required"].append() = "normal"; + param_schema["properties/plane"].set(plane_schema); + + // --- multi plane --- + conduit::Node multi_plane_schema; + multi_plane_schema["type"] = "object"; + multi_plane_schema["additionalProperties"] = false; + multi_plane_schema["properties/point1"].set(vec3_schema()); + multi_plane_schema["properties/point2"].set(vec3_schema()); + multi_plane_schema["properties/normal1"].set(vec3_schema()); + multi_plane_schema["properties/normal2"].set(vec3_schema()); + multi_plane_schema["required"].append() = "point1"; + multi_plane_schema["required"].append() = "point2"; + multi_plane_schema["required"].append() = "normal1"; + multi_plane_schema["required"].append() = "normal2"; + param_schema["properties/multi_plane"].set(multi_plane_schema); + + i["param_schema"].set(param_schema); } - //----------------------------------------------------------------------------- void VTKHClip::execute() diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp index 1c5386777..7cffa8a49 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp @@ -101,8 +101,6 @@ class ASCENT_API VTKHAutoSliceLevels : public ::flow::Filter virtual ~VTKHAutoSliceLevels(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; //----------------------------------------------------------------------------- @@ -126,8 +124,6 @@ class ASCENT_API VTKHThreshold : public ::flow::Filter virtual ~VTKHThreshold(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -139,8 +135,6 @@ class ASCENT_API VTKHGhostStripper: public ::flow::Filter virtual ~VTKHGhostStripper(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -152,8 +146,6 @@ class ASCENT_API VTKHAddRanks : public ::flow::Filter virtual ~VTKHAddRanks(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -166,8 +158,6 @@ class ASCENT_API VTKHAddDomains : public ::flow::Filter virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -181,8 +171,6 @@ class ASCENT_API VTKHClip: public ::flow::Filter virtual ~VTKHClip(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -456,8 +444,6 @@ class ASCENT_API VTKHCleanGrid : public ::flow::Filter virtual ~VTKHCleanGrid(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; From f6a94d20a8dee59864284a56e2ba823ebfcaaece Mon Sep 17 00:00:00 2001 From: Emily Howell Date: Tue, 24 Feb 2026 17:17:06 -0800 Subject: [PATCH 4/6] Adding a schema validator for flow filters --- src/libs/flow/CMakeLists.txt | 2 + src/libs/flow/flow_filter.cpp | 18 +- src/libs/flow/flow_schema_validator.cpp | 407 ++++++++++++++++++++++++ src/libs/flow/flow_schema_validator.hpp | 108 +++++++ 4 files changed, 525 insertions(+), 10 deletions(-) create mode 100644 src/libs/flow/flow_schema_validator.cpp create mode 100644 src/libs/flow/flow_schema_validator.hpp diff --git a/src/libs/flow/CMakeLists.txt b/src/libs/flow/CMakeLists.txt index c17075196..249af3b54 100644 --- a/src/libs/flow/CMakeLists.txt +++ b/src/libs/flow/CMakeLists.txt @@ -25,6 +25,7 @@ set(flow_sources flow_graph.cpp flow_workspace.cpp flow_timer.cpp + flow_schema_validator.cpp filters/flow_builtin_filters.cpp) set(flow_headers @@ -38,6 +39,7 @@ set(flow_headers flow_graph.hpp flow_workspace.hpp flow_timer.hpp + flow_schema_validator.hpp filters/flow_builtin_filters.hpp) set(flow_thirdparty_libs diff --git a/src/libs/flow/flow_filter.cpp b/src/libs/flow/flow_filter.cpp index 39691752b..9f502c767 100644 --- a/src/libs/flow/flow_filter.cpp +++ b/src/libs/flow/flow_filter.cpp @@ -26,6 +26,7 @@ #include #include #include +#include using namespace conduit; @@ -225,18 +226,15 @@ Filter::verify_params(const Node ¶ms, { info.reset(); - std::cout << "\nSlice Properties!!" << std::endl; - param_schema().print(); - - std::cout << "\nParams!!" << std::endl; - params.print(); + if (!param_schema().dtype().is_empty() && !(param_schema().dtype().is_object() && param_schema().number_of_children() == 0)) + { + // std::cout << "\nSlice Properties!!" << std::endl; + // param_schema().print(); - std::string surprises = "";// surprise_check(param_schema(), params); + // std::cout << "\nParams!!" << std::endl; + // params.print(); - if(surprises != "") - { - info["errors"].append() = surprises; - return false; + return flow::schema::validate(param_schema(), params, info); } return true; diff --git a/src/libs/flow/flow_schema_validator.cpp b/src/libs/flow/flow_schema_validator.cpp new file mode 100644 index 000000000..09ae400da --- /dev/null +++ b/src/libs/flow/flow_schema_validator.cpp @@ -0,0 +1,407 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Copyright (c) Lawrence Livermore National Security, LLC and other Ascent +// Project developers. See top-level LICENSE AND COPYRIGHT files for dates and +// other details. No copyright assignment is required to contribute to Ascent. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + + +//----------------------------------------------------------------------------- +/// +/// file: flow_schema_validator.cpp +/// +//----------------------------------------------------------------------------- + +#include "flow_schema_validator.hpp" + +// standard lib includes +#include +#include + +//----------------------------------------------------------------------------- +// -- begin flow -- +//----------------------------------------------------------------------------- +namespace flow +{ + +//----------------------------------------------------------------------------- +// -- begin flow::schema -- +//----------------------------------------------------------------------------- +namespace schema +{ + +// ---------- General Helpers ---------- +static void add_error(conduit::Node &info, const std::string &msg) +{ + if(!info.has_child("errors")) + { + info["errors"].reset(); + } + info["errors"].append() = msg; +} + +static std::string get_type_string(const conduit::Node &schema) +{ + if(schema.has_child("type") && schema["type"].dtype().is_string()) + { + return schema["type"].as_string(); + } + return ""; +} + +static bool check_type(const conduit::Node &input, + const conduit::Node &schema, + conduit::Node &info, + const std::string &path) +{ + const std::string schema_defined_type = get_type_string(schema); + if(schema_defined_type.empty()) return true; // schema didn't specify; treat as "accept anything" + + const auto data_type = input.dtype(); + bool ok = true; + + if(schema_defined_type == "object") ok = data_type.is_object(); + else if(schema_defined_type == "string") ok = data_type.is_string(); + else if(schema_defined_type == "number") ok = data_type.is_number(); + else + { + add_error(info, "At '" + (path.empty() ? std::string("") : path) + + "': unknown schema type '" + schema_defined_type + "'"); + return false; + } + + if(!ok) + { + add_error(info, "Type mismatch at '" + (path.empty() ? std::string("") : path) + + "': expected " + schema_defined_type + ", got " + input.dtype().name()); + } + + return ok; +} + +// ---------- Object-Specific Validation Helpers ---------- +static bool validate_required(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_child("required")) return true; + if(!input.dtype().is_object()) return true; // type error handled elsewhere + + bool ok = true; + const conduit::Node &req = schema["required"]; + for(conduit::index_t i = 0; i < req.number_of_children(); ++i) + { + const std::string k = req.child(i).as_string(); + if(!input.has_child(k)) + { + add_error(info, "Missing required field '" + conduit::utils::join_file_path(path, k) + "'"); + ok = false; + } + } + return ok; +} + +static bool validate_forbid(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_path("constraints/forbid")) return true; + if(!input.dtype().is_object()) return true; + + bool ok = true; + const conduit::Node &forbid = schema["constraints/forbid"]; + for(conduit::index_t i = 0; i < forbid.number_of_children(); ++i) + { + const std::string k = forbid.child(i).as_string(); + if(input.has_child(k)) + { + add_error(info, "Field '" + conduit::utils::join_file_path(path, k) + "' is forbidden by schema"); + ok = false; + } + } + return ok; +} + +static bool validate_properties(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_child("properties")) return true; + if(!input.dtype().is_object()) return true; + + bool ok = true; + const conduit::Node &props = schema["properties"]; + for(conduit::index_t i = 0; i < props.number_of_children(); ++i) + { + const std::string k = props[i].name(); + if(input.has_child(k)) + { + ok = validate_node(props[k], input[k], info, conduit::utils::join_file_path(path, k)) && ok; + } + } + return ok; +} + +static bool validate_additional_properties(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!input.dtype().is_object()) return true; + + bool allow_additional = true; + if(schema.has_child("additionalProperties")) + { + allow_additional = schema["additionalProperties"].to_int() != 0; + } + + if(allow_additional) return true; + + const bool has_props = schema.has_child("properties"); + const conduit::Node props_dummy; + const conduit::Node &props = has_props ? schema["properties"] : props_dummy; + + bool ok = true; + for(conduit::index_t i = 0; i < input.number_of_children(); ++i) + { + const std::string k = input[i].name(); + if(!has_props || !props.has_child(k)) + { + add_error(info, "Unexpected field '" + conduit::utils::join_file_path(path, k) + + "' (additionalProperties=false)"); + ok = false; + } + } + return ok; +} + +static bool validate_dependencies(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_path("constraints/dependencies")) return true; + if(!input.dtype().is_object()) return true; + + bool ok = true; + const conduit::Node &deps = schema["constraints/dependencies"]; + + for(conduit::index_t i = 0; i < deps.number_of_children(); ++i) + { + const std::string trigger = deps[i].name(); + if(!input.has_child(trigger)) continue; + + const conduit::Node &reqs = deps[trigger]; + for(conduit::index_t j = 0; j < reqs.number_of_children(); ++j) + { + const std::string needed = reqs.child(j).as_string(); + if(!input.has_child(needed)) + { + add_error(info, "Dependency violation at '" + + (path.empty() ? std::string("") : path) + + "': if '" + trigger + "' is provided, '" + + needed + "' must also be provided"); + ok = false; + } + } + } + return ok; +} + +static bool validate_exclusive_children(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_path("constraints/exclusiveChildren")) return true; + if(!input.dtype().is_object()) return true; + + const conduit::Node &keys = schema["constraints/exclusiveChildren"]; + const bool allow_none = schema.has_path("constraints/allowNoneInExclusiveGroup") + ? (schema["constraints/allowNoneInExclusiveGroup"].to_int() != 0) + : true; + + std::vector present; + present.reserve((size_t)keys.number_of_children()); + + for(conduit::index_t i = 0; i < keys.number_of_children(); ++i) + { + const std::string k = keys.child(i).as_string(); + if(input.has_child(k)) present.push_back(k); + } + + const int count = (int)present.size(); + const bool ok = allow_none ? (count <= 1) : (count == 1); + + if(ok) return true; + + std::ostringstream oss; + oss << "Exclusive-children violation at '" + << (path.empty() ? "" : path) << "': expected " + << (allow_none ? "zero or one" : "exactly one") + << " of {"; + + for(conduit::index_t i = 0; i < keys.number_of_children(); ++i) + { + if(i) oss << ", "; + oss << keys.child(i).as_string(); + } + oss << "}"; + + if(count > 0) + { + oss << ", but found: {"; + for(size_t i = 0; i < present.size(); ++i) + { + if(i) oss << ", "; + oss << present[i]; + } + oss << "}"; + } + else + { + oss << ", but found none"; + } + + add_error(info, oss.str()); + return false; +} + +static bool validate_one_of(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_child("oneOf")) return true; + + const conduit::Node &opts = schema["oneOf"]; + int matches = 0; + + // keep at most one representative failure per option for clarity + std::vector option_msgs; + + for(conduit::index_t i = 0; i < opts.number_of_children(); ++i) + { + const conduit::Node &opt = opts.child(i); + + conduit::Node tmp; + tmp.reset(); + + bool ok = true; + ok = check_type(input, opt, tmp, path) && ok; + ok = validate_required(opt, input, tmp, path) && ok; + ok = validate_forbid(opt, input, tmp, path) && ok; + ok = validate_dependencies(opt, input, tmp, path) && ok; + ok = validate_exclusive_children(opt, input, tmp, path) && ok; + + if(ok) + { + matches++; + } + else + { + // pick first error as representative + if(tmp.has_child("errors") && tmp["errors"].number_of_children() > 0) + { + option_msgs.push_back(tmp["errors"].child(0).as_string()); + } + else + { + option_msgs.push_back("Option " + std::to_string((int)i) + " failed"); + } + } + } + + if(matches == 1) return true; + + std::ostringstream oss; + oss << "oneOf violation at '" << (path.empty() ? "" : path) << "': "; + if(matches == 0) oss << "input did not match any supported schemas"; + else oss << "input matched " << matches << " options (ambiguous)"; + add_error(info, oss.str()); + + // give a couple of hints + for(size_t i = 0; i < option_msgs.size() && i < 2; ++i) + { + add_error(info, std::string(" hint: ") + option_msgs[i]); + } + + return false; +} + +static bool validate_object(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + bool ok = true; + + // Base checks first + ok = validate_required(schema, input, info, path) && ok; + ok = validate_forbid(schema, input, info, path) && ok; + ok = validate_dependencies(schema, input, info, path) && ok; + ok = validate_exclusive_children(schema, input, info, path) && ok; + + // Enforce unknown fields after we know properties + ok = validate_additional_properties(schema, input, info, path) && ok; + + // Recurse into declared properties that exist in input + ok = validate_properties(schema, input, info, path) && ok; + + // Finally, enforce oneOf (treating options as extra constraints on this same object) + ok = validate_one_of(schema, input, info, path) && ok; + + return ok; +} + +static bool validate_node(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + bool ok = true; + + ok = check_type(input, schema, info, path) && ok; + if(!ok) return false; // type mismatch stops recursion + + const std::string schema_defined_type = get_type_string(schema); + if(schema_defined_type == "object") + { + return validate_object(schema, input, info, path); + } + + ok = validate_one_of(schema, input, info, path) && ok; + + return ok; +} + +// ---------- Schema Validation Entry-Point ---------- +bool validate(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info) +{ + info.reset(); + bool ok = validate_node(schema, input, info, ""); + + if(!ok && !info.has_child("errors")) + { + info["errors"].append() = "Validation failed (no details)"; + } + + return ok; +} + + +}; +//----------------------------------------------------------------------------- +// -- end flow::schema -- +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +}; +//----------------------------------------------------------------------------- +// -- end flow -- +//----------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/libs/flow/flow_schema_validator.hpp b/src/libs/flow/flow_schema_validator.hpp new file mode 100644 index 000000000..11043ff70 --- /dev/null +++ b/src/libs/flow/flow_schema_validator.hpp @@ -0,0 +1,108 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// Copyright (c) Lawrence Livermore National Security, LLC and other Ascent +// Project developers. See top-level LICENSE AND COPYRIGHT files for dates and +// other details. No copyright assignment is required to contribute to Ascent. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// + + +//----------------------------------------------------------------------------- +/// +/// file: flow_schema_validator.hpp +/// +//----------------------------------------------------------------------------- + +#ifndef FLOW_SCHEMA_VALIDATOR_HPP +#define FLOW_SCHEMA_VALIDATOR_HPP + +#include + +#include +#include + +//----------------------------------------------------------------------------- +// -- begin flow -- +//----------------------------------------------------------------------------- +namespace flow +{ + +//----------------------------------------------------------------------------- +// -- begin flow::schema -- +//----------------------------------------------------------------------------- +namespace schema +{ + +bool FLOW_API validate(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info); + + +static bool validate_node(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +static bool validate_object(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +static bool validate_one_of(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +static bool validate_exclusive_children(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +static bool validate_dependencies(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +static bool validate_properties(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +static bool validate_additional_properties(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +static bool validate_required(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +static bool validate_forbid(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +static bool check_type(const conduit::Node &input, + const conduit::Node &schema, + conduit::Node &info, + const std::string &path); + +static std::string get_type_string(const conduit::Node &schema); + +static void add_error(conduit::Node &info, const std::string &msg); + +}; +//----------------------------------------------------------------------------- +// -- end flow::schema -- +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +}; +//----------------------------------------------------------------------------- +// -- end flow -- +//----------------------------------------------------------------------------- + +#endif +//----------------------------------------------------------------------------- +// -- end header ifdef guard +//----------------------------------------------------------------------------- \ No newline at end of file From 6d5d6e139be9c980997e168ccc18bda55e7eafb3 Mon Sep 17 00:00:00 2001 From: Emily Howell Date: Fri, 27 Feb 2026 15:59:50 -0800 Subject: [PATCH 5/6] Translating all filters in ascent_runtime_vtkh_filters to json schema format. Also adding additional validator constructs needed to complete this. --- .../ascent_runtime_param_check.cpp | 56 + .../ascent_runtime_param_check.hpp | 12 + .../ascent_runtime_vtkh_filters.cpp | 1577 +++++------------ .../ascent_runtime_vtkh_filters.hpp | 62 - src/libs/flow/flow_schema_validator.cpp | 186 +- 5 files changed, 722 insertions(+), 1171 deletions(-) diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp index 9291cb84e..0e75196c7 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp @@ -72,6 +72,39 @@ conduit::Node string_schema() return n; } +conduit::Node vec3_schema_anyOf(const std::string var1, const std::string var2, const std::string var3) +{ + conduit::Node n; + n["type"] = "object"; + n["additionalProperties"] = false; + + n["properties/" + var1].set(number_schema()); + n["properties/" + var2].set(number_schema()); + n["properties/" + var3].set(number_schema()); + + conduit::Node var1_required; + var1_required["type"] = "object"; + var1_required["required"] = var1; + n["anyOf"].append().set(var1_required); + + conduit::Node var2_required; + var2_required["type"] = "object"; + var2_required["required"] = var1; + n["anyOf"].append().set(var2_required); + + conduit::Node var3_required; + var3_required["type"] = "object"; + var3_required["required"] = var1; + n["anyOf"].append().set(var3_required); + + return n; +} + +conduit::Node vec3_schema_anyOf() +{ + return vec3_schema_anyOf("x", "y", "z"); +} + conduit::Node vec3_schema(const std::string var1, const std::string var2, const std::string var3) { conduit::Node n; @@ -94,6 +127,29 @@ conduit::Node vec3_schema() return vec3_schema("x", "y", "z"); } +conduit::Node array_schema(const conduit::Node &item_schema) +{ + conduit::Node n; + n["type"] = "array"; + n["items"].set(item_schema); + return n; +} + +conduit::Node array_schema() +{ + conduit::Node n; + n["type"] = "array"; + return n; +} + +conduit::Node ignore_schema() +{ + conduit::Node n; + n["type"] = "object"; + n["constraints/skip"] = true; + return n; +} + //----------------------------------------------------------------------------- bool check_numeric(const std::string path, diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp index 9c0c557f3..50413c9a0 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp @@ -51,6 +51,18 @@ conduit::Node ASCENT_API vec3_schema(const std::string var1, const std::string var2, const std::string var3); +conduit::Node ASCENT_API vec3_schema_anyOf(); + +conduit::Node ASCENT_API vec3_schema_anyOf(const std::string var1, + const std::string var2, + const std::string var3); + +conduit::Node ASCENT_API array_schema(); + +conduit::Node ASCENT_API array_schema(const conduit::Node &item_schema); + +conduit::Node ASCENT_API ignore_schema(); + bool ASCENT_API check_numeric(const std::string path, const conduit::Node ¶ms, conduit::Node &info, diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp index 8fcbee5f7..95445f6b0 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.cpp @@ -134,40 +134,22 @@ VTKHMarchingCubes::declare_interface(Node &i) i["type_name"] = "vtkh_marchingcubes"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHMarchingCubes::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_string("field",params, info, true); - bool has_values = check_numeric("iso_values",params, info, false); - bool has_levels = check_numeric("levels",params, info, false); - - if(!has_values && !has_levels) - { - info["errors"].append() = "Missing required numeric parameter. Contour must" - " specify 'iso_values' or 'levels'."; - res = false; - } - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("levels"); - valid_paths.push_back("iso_values"); - valid_paths.push_back("use_contour_tree"); - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/levels"].set(number_schema()); + param_schema["properties/iso_values"].set(number_schema()); + param_schema["properties/use_contour_tree"].set(string_schema()); - return res; + param_schema["required"].append() = "field"; + param_schema["anyOf"].append() = "levels"; + param_schema["anyOf"].append() = "iso_values"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -245,7 +227,6 @@ VTKHMarchingCubes::execute() set_output(res); } -//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- VTKHExternalSurfaces::VTKHExternalSurfaces() :Filter() @@ -266,31 +247,15 @@ VTKHExternalSurfaces::declare_interface(Node &i) i["type_name"] = "vtkh_external_surfaces"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHExternalSurfaces::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - - res = check_string("topology",params, info, false) && res; - - std::vector valid_paths; - valid_paths.push_back("topology"); - - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + param_schema["properties/topology"].set(string_schema()); + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -360,30 +325,18 @@ VTKHVectorMagnitude::declare_interface(Node &i) i["type_name"] = "vtkh_vector_magnitude"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHVectorMagnitude::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_string("field",params, info, true); - res = check_string("output_name",params, info, false) && res; - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("output_name"); - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -464,36 +417,18 @@ VTKH3Slice::declare_interface(Node &i) i["type_name"] = "vtkh_3slice"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKH3Slice::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - std::vector valid_paths; - res &= check_string("topology",params, info, false); - valid_paths.push_back("topology"); - res &= check_numeric("x_offset",params, info, false, true); - res &= check_numeric("y_offset",params, info, false, true); - res &= check_numeric("z_offset",params, info, false, true); - res = check_string("topology",params, info, false) && res; - - valid_paths.push_back("x_offset"); - valid_paths.push_back("y_offset"); - valid_paths.push_back("z_offset"); - - std::string surprises = surprise_check(valid_paths, params); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + param_schema["properties/topology"].set(string_schema()); + param_schema["properties/x_offset"].set(number_schema()); + param_schema["properties/y_offset"].set(number_schema()); + param_schema["properties/z_offset"].set(number_schema()); + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -613,32 +548,15 @@ VTKHTriangulate::declare_interface(Node &i) i["type_name"] = "vtkh_triangulate"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHTriangulate::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = true; - res = check_string("topology",params, info, false) && res; - - std::vector valid_paths; - valid_paths.push_back("topology"); - - - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + param_schema["properties/topology"].set(string_schema()); + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -2024,34 +1942,22 @@ VTKHClipWithField::declare_interface(Node &i) i["type_name"] = "vtkh_clip_with_field"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -VTKHClipWithField::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_numeric("clip_value",params, info, true, true); - res = check_string("field",params, info, true) && res; - res = check_string("invert",params, info, false) && res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - std::vector valid_paths; - valid_paths.push_back("clip_value"); - valid_paths.push_back("invert"); - valid_paths.push_back("field"); - std::string surprises = surprise_check(valid_paths, params); + param_schema["properties/clip_value"].set(number_schema()); + param_schema["properties/field"].set(string_schema()); + param_schema["properties/invert"].set(string_schema()); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["required"].append() = "clip_value"; + param_schema["required"].append() = "field"; - return res; + i["param_schema"].set(param_schema); } - //----------------------------------------------------------------------------- void VTKHClipWithField::execute() @@ -2136,35 +2042,23 @@ VTKHIsoVolume::declare_interface(Node &i) i["type_name"] = "vtkh_iso_volume"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHIsoVolume::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_numeric("min_value",params, info, true, true); - res = check_numeric("max_value",params, info, true, true) && res; - res = check_string("field",params, info, true) && res; - std::vector valid_paths; - valid_paths.push_back("min_value"); - valid_paths.push_back("max_value"); - valid_paths.push_back("field"); - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/min_value"].set(number_schema()); + param_schema["properties/max_value"].set(number_schema()); + param_schema["properties/field"].set(string_schema()); - return res; + param_schema["required"].append() = "min_value"; + param_schema["required"].append() = "max_value"; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } - //----------------------------------------------------------------------------- void VTKHIsoVolume::execute() @@ -2242,44 +2136,31 @@ VTKHLagrangian::declare_interface(Node &i) i["type_name"] = "vtkh_lagrangian"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -VTKHLagrangian::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_string("field",params, info, true); - res &= check_numeric("step_size", params, info, true); - res &= check_numeric("write_frequency", params, info, true); - res &= check_numeric("cust_res", params, info, true); - res &= check_numeric("x_res", params, info, true); - res &= check_numeric("y_res", params, info, true); - res &= check_numeric("z_res", params, info, true); - - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("step_size"); - valid_paths.push_back("write_frequency"); - valid_paths.push_back("cust_res"); - valid_paths.push_back("x_res"); - valid_paths.push_back("y_res"); - valid_paths.push_back("z_res"); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - std::string surprises = surprise_check(valid_paths, params); + param_schema["properties/field"].set(string_schema()); + param_schema["properties/step_size"].set(number_schema()); + param_schema["properties/write_frequency"].set(number_schema()); + param_schema["properties/cust_res"].set(number_schema()); + param_schema["properties/x_res"].set(number_schema()); + param_schema["properties/y_res"].set(number_schema()); + param_schema["properties/z_res"].set(number_schema()); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - return res; + param_schema["required"].append() = "field"; + param_schema["required"].append() = "step_size"; + param_schema["required"].append() = "write_frequency"; + param_schema["required"].append() = "cust_res"; + param_schema["required"].append() = "x_res"; + param_schema["required"].append() = "y_res"; + param_schema["required"].append() = "z_res"; + + i["param_schema"].set(param_schema); } - //----------------------------------------------------------------------------- void VTKHLagrangian::execute() @@ -2364,33 +2245,19 @@ VTKHLog::declare_interface(Node &i) i["type_name"] = "vtkh_log"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHLog::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - res &= check_string("output_name",params, info, false); - res &= check_numeric("clamp_min_value",params, info, false, true); - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("output_name"); - valid_paths.push_back("clamp_min_value"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); + param_schema["properties/clamp_min_value"].set(number_schema()); - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -2474,33 +2341,19 @@ VTKHLog10::declare_interface(Node &i) i["type_name"] = "vtkh_log10"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHLog10::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - res &= check_string("output_name",params, info, false); - res &= check_numeric("clamp_min_value",params, info, false, true); - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("output_name"); - valid_paths.push_back("clamp_min_value"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); + param_schema["properties/clamp_min_value"].set(number_schema()); - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -2584,33 +2437,19 @@ VTKHLog2::declare_interface(Node &i) i["type_name"] = "vtkh_log2"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHLog2::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - res &= check_string("output_name",params, info, false); - res &= check_numeric("clamp_min_value",params, info, false, true); - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("output_name"); - valid_paths.push_back("clamp_min_value"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); + param_schema["properties/clamp_min_value"].set(number_schema()); - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -2694,31 +2533,19 @@ VTKHRecenter::declare_interface(Node &i) i["type_name"] = "vtkh_recenter"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHRecenter::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - res &= check_string("association",params, info, true); - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("association"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/association"].set(string_schema()); - return res; + param_schema["required"].append() = "field"; + param_schema["required"].append() = "association"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -2808,33 +2635,19 @@ VTKHHistSampling::declare_interface(Node &i) i["type_name"] = "vtkh_hist_sampling"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHHistSampling::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - res &= check_numeric("bins",params, info, false, true); - res &= check_numeric("sample_rate",params, info, false, true); - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("bins"); - valid_paths.push_back("sample_rate"); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - std::string surprises = surprise_check(valid_paths, params); + param_schema["properties/field"].set(string_schema()); + param_schema["properties/bins"].set(number_schema()); + param_schema["properties/sample_rate"].set(number_schema()); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["required"].append() = "field"; - return res; + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -2961,32 +2774,19 @@ VTKHQCriterion::declare_interface(Node &i) i["type_name"] = "vtkh_qcriterion"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHQCriterion::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - res &= check_string("output_name",params, info, false); - res &= check_string("use_cell_gradient",params, info, false); - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("output_name"); - valid_paths.push_back("use_cell_gradient"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); + param_schema["properties/use_cell_gradient"].set(string_schema()); - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -3083,32 +2883,19 @@ VTKHDivergence::declare_interface(Node &i) i["type_name"] = "vtkh_divergence"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHDivergence::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - res &= check_string("output_name",params, info, false); - res &= check_string("use_cell_gradient",params, info, false); - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("output_name"); - valid_paths.push_back("use_cell_gradient"); - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); + param_schema["properties/use_cell_gradient"].set(string_schema()); - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -3204,33 +2991,20 @@ VTKHVorticity::declare_interface(Node &i) i["type_name"] = "vtkh_curl"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -VTKHVorticity::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - res &= check_string("output_name",params, info, false); - res &= check_string("use_cell_gradient",params, info, false); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("output_name"); - valid_paths.push_back("use_cell_gradient"); + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); + param_schema["properties/use_cell_gradient"].set(string_schema()); - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; -} + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); +} //----------------------------------------------------------------------------- void @@ -3325,33 +3099,19 @@ VTKHGradient::declare_interface(Node &i) i["type_name"] = "vtkh_gradient"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHGradient::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_string("field",params, info, true); - res &= check_string("output_name",params, info, false); - res &= check_string("use_cell_gradient",params, info, false); - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("output_name"); - valid_paths.push_back("use_cell_gradient"); - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); + param_schema["properties/use_cell_gradient"].set(string_schema()); - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -3439,70 +3199,23 @@ VTKHUniformGrid::declare_interface(Node &i) i["type_name"] = "vtkh_uniform_grid"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -VTKHUniformGrid::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = true; - res &= check_string("field",params, info, false); - res &= check_numeric("dims/i",params, info, false); - res &= check_numeric("dims/j",params, info, false); - res &= check_numeric("dims/k",params, info, false); - res &= check_numeric("origin/x",params, info, false); - res &= check_numeric("origin/y",params, info, false); - res &= check_numeric("origin/z",params, info, false); - res &= check_numeric("spacing/dx",params, info, false); - res &= check_numeric("spacing/dx",params, info, false); - res &= check_numeric("spacing/dy",params, info, false); - res &= check_numeric("spacing/dz",params, info, false); - res &= check_numeric("invalid_value",params, info, false); - - if(!params.has_child("field") && !params.has_child("fields")) - { - res = false; - info["errors"].append() = "Uniform Grid Sampling requires 'field' or 'fields'"; - } - - if(params.has_child("fields") && !params["fields"].dtype().is_list()) - { - res = false; - info["errors"].append() = "'fields' is not a list"; - } - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("fields"); - valid_paths.push_back("dims/i"); - valid_paths.push_back("dims/j"); - valid_paths.push_back("dims/k"); - valid_paths.push_back("origin/x"); - valid_paths.push_back("origin/y"); - valid_paths.push_back("origin/z"); - valid_paths.push_back("spacing/dx"); - valid_paths.push_back("spacing/dy"); - valid_paths.push_back("spacing/dz"); - valid_paths.push_back("invalid_value"); - - std::string surprises = ""; - - std::vector ignore_paths; - ignore_paths.push_back("fields"); - - if(params.number_of_children() != 0) - std::string surprises = surprise_check(valid_paths, ignore_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + param_schema["properties/field"].set(string_schema()); + param_schema["properties/fields"].set(array_schema(ignore_schema())); + param_schema["properties/dims"].set(vec3_schema_anyOf("i", "j", "k")); + param_schema["properties/origin"].set(vec3_schema_anyOf()); + param_schema["properties/spacing"].set(vec3_schema_anyOf("dx", "dy", "dz")); + param_schema["properties/invalid_value"].set(number_schema()); + + param_schema["anyOf"].append() = "field"; + param_schema["anyOf"].append() = "fields"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -3663,78 +3376,32 @@ VTKHSample::declare_interface(Node &i) i["type_name"] = "vtkh_sample"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -VTKHSample::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - bool res = true; - res &= check_string("field",params, info, false); - res &= check_numeric("invalid_value",params, info, false); + param_schema["properties/field"].set(string_schema()); + param_schema["properties/fields"].set(array_schema(ignore_schema())); + param_schema["properties/invalid_value"].set(number_schema()); + + // --- Line --- + conduit::Node line_schema; + line_schema["type"] = "object"; + line_schema["additionalProperties"] = false; + line_schema["properties/num_samples"].set(number_schema()); + line_schema["properties/start"].set(vec3_schema_anyOf()); + line_schema["properties/end"].set(vec3_schema_anyOf()); + param_schema["properties/line"].set(line_schema); + + // --- Points --- + param_schema["properties/points"].set(vec3_schema_anyOf()); + + param_schema["anyOf"].append() = "field"; + param_schema["anyOf"].append() = "fields"; - res &= check_numeric("line/num_samples",params, info, false); - res &= check_numeric("line/start/x",params, info, false); - res &= check_numeric("line/start/y",params, info, false); - res &= check_numeric("line/start/z",params, info, false); - res &= check_numeric("line/end/x",params, info, false); - res &= check_numeric("line/end/y",params, info, false); - res &= check_numeric("line/end/z",params, info, false); - - res &= check_numeric("points/x",params, info, false); - res &= check_numeric("points/y",params, info, false); - res &= check_numeric("points/z",params, info, false); - - - if(!params.has_child("field") && !params.has_child("fields")) - { - res = false; - info["errors"].append() = "Sampling requires 'field' or 'fields'"; - } - - if(params.has_child("fields") && !params["fields"].dtype().is_list()) - { - res = false; - info["errors"].append() = "'fields' is not a list"; - } - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("fields"); - valid_paths.push_back("invalid_value"); - - valid_paths.push_back("line/num_samples"); - valid_paths.push_back("line/start/x"); - valid_paths.push_back("line/start/y"); - valid_paths.push_back("line/start/z"); - valid_paths.push_back("line/end/x"); - valid_paths.push_back("line/end/y"); - valid_paths.push_back("line/end/z"); - - valid_paths.push_back("points/x"); - valid_paths.push_back("points/y"); - valid_paths.push_back("points/z"); - - std::string surprises = ""; - - std::vector ignore_paths; - ignore_paths.push_back("fields"); - - if(params.number_of_children() != 0) - { - surprises = surprise_check(valid_paths, ignore_paths, params); - } - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -3902,29 +3569,16 @@ VTKHStats::declare_interface(Node &i) i["type_name"] = "vtkh_stats"; i["port_names"].append() = "in"; i["output_port"] = "false"; -} -//----------------------------------------------------------------------------- -bool -VTKHStats::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_string("field",params, info, true); - - std::vector valid_paths; - valid_paths.push_back("field"); - - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + param_schema["properties/field"].set(string_schema()); + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -3996,31 +3650,18 @@ VTKHHistogram::declare_interface(Node &i) i["type_name"] = "vtkh_histogram"; i["port_names"].append() = "in"; i["output_port"] = "false"; -} -//----------------------------------------------------------------------------- -bool -VTKHHistogram::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_string("field",params, info, true); - res &= check_numeric("bins",params, info, false, true); - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("bins"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/bins"].set(number_schema()); - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -4096,49 +3737,22 @@ VTKHProject2d::declare_interface(Node &i) i["type_name"] = "vtkh_project_2d"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHProject2d::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("topology",params, info, false); - res &= check_numeric("image_width",params, info, false); - res &= check_numeric("image_height",params, info, false); - - if(params.has_child("fields") && !params["fields"].dtype().is_list()) - { - res = false; - info["errors"].append() = "fields is not a list"; - } - - std::vector valid_paths; - std::vector ignore_paths; - valid_paths.push_back("topology"); - valid_paths.push_back("image_width"); - valid_paths.push_back("image_height"); - valid_paths.push_back("dataset_bounds"); - valid_paths.push_back("camera"); - valid_paths.push_back("fields"); - ignore_paths.push_back("camera"); - ignore_paths.push_back("fields"); - ignore_paths.push_back("dataset_bounds"); - - std::string surprises = surprise_check(valid_paths, ignore_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + param_schema["properties/topology"].set(string_schema()); + param_schema["properties/image_width"].set(number_schema()); + param_schema["properties/image_height"].set(number_schema()); + param_schema["properties/dataset_bounds"].set(ignore_schema()); + param_schema["properties/camera"].set(ignore_schema()); + param_schema["properties/fields"].set(array_schema(ignore_schema())); + + i["param_schema"].set(param_schema); } - //----------------------------------------------------------------------------- void VTKHProject2d::execute() @@ -4278,29 +3892,16 @@ VTKHNoOp::declare_interface(Node &i) i["type_name"] = "vtkh_no_op"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHNoOp::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - - std::vector valid_paths; - valid_paths.push_back("field"); - - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + param_schema["properties/field"].set(string_schema()); + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -4376,33 +3977,21 @@ VTKHVectorComponent::declare_interface(Node &i) i["type_name"] = "vtkh_vector_component"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHVectorComponent::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field",params, info, true); - res &= check_numeric("component",params, info, true); - res &= check_string("output_name",params, info, true); - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("component"); - valid_paths.push_back("output_name"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field"].set(string_schema()); + param_schema["properties/component"].set(number_schema()); + param_schema["properties/output_name"].set(string_schema()); - return res; + param_schema["required"].append() = "field"; + param_schema["required"].append() = "component"; + param_schema["required"].append() = "output_name"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -4482,35 +4071,22 @@ VTKHCompositeVector::declare_interface(Node &i) i["type_name"] = "vtkh_composite_vector"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHCompositeVector::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("field1",params, info, true); - res &= check_string("field2",params, info, true); - res &= check_string("field3",params, info, false); - res &= check_string("output_name",params, info, true); - - std::vector valid_paths; - valid_paths.push_back("field1"); - valid_paths.push_back("field2"); - valid_paths.push_back("field3"); - valid_paths.push_back("output_name"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/field1"].set(string_schema()); + param_schema["properties/field2"].set(string_schema()); + param_schema["properties/field3"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); - return res; + param_schema["required"].append() = "field1"; + param_schema["required"].append() = "field2"; + param_schema["required"].append() = "output_name"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -4620,33 +4196,9 @@ VTKHScale::declare_interface(Node &i) i["type_name"] = "vtkh_scale_transform"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHScale::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = check_numeric("x_scale",params, info, true, true); - res &= check_numeric("y_scale",params, info, true, true); - res &= check_numeric("z_scale",params, info, true, true); - - std::vector valid_paths; - valid_paths.push_back("x_scale"); - valid_paths.push_back("y_scale"); - valid_paths.push_back("z_scale"); - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema = vec3_schema("x_scale", "y_scale", "z_scale"); } //----------------------------------------------------------------------------- @@ -4720,168 +4272,39 @@ VTKHTransform::declare_interface(Node &i) i["type_name"] = "vtkh_transform"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHTransform::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); -/* - scale/x,y,z - translate/x,y,z - rotate/x,y,z - reflect/x,y,z - transform_matrix: float64 x 16 -*/ + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + param_schema["constraints/exclusiveChildren"].append() = "scale"; + param_schema["constraints/exclusiveChildren"].append() = "translate"; + param_schema["constraints/exclusiveChildren"].append() = "reflect"; + param_schema["constraints/exclusiveChildren"].append() = "rotate"; + param_schema["constraints/exclusiveChildren"].append() = "matrix"; + param_schema["constraints/allowNoneInExclusiveGroup"] = false; - bool res = true; + param_schema["properties/scale"].set(vec3_schema_anyOf()); + param_schema["properties/translate"].set(vec3_schema_anyOf()); + param_schema["properties/reflect"].set(vec3_schema_anyOf()); + + // --- rotate --- + conduit::Node rotate_schema; + rotate_schema["type"] = "object"; + rotate_schema["additionalProperties"] = false; + rotate_schema["properties/angle"].set(number_schema()); + rotate_schema["properties/axis"].set(vec3_schema_anyOf()); + rotate_schema["required"].append() = "angle"; + rotate_schema["required"].append() = "axis"; + param_schema["properties/rotate"].set(rotate_schema); + + // --- matrix --- + conduit::Node matrix_schema = array_schema(number_schema()); + matrix_schema["minItems"] = 16; + matrix_schema["miaxItems"] = 16; + param_schema["properties/matrix"].set(matrix_schema); - std::vector modes = {"scale", - "translate", - "rotate", - "reflect", - "matrix"}; - - index_t mode_count = 0; - for( auto mode : modes) - { - if(params.has_child(mode)) - { - mode_count++; - } - } - - if(mode_count > 1) - { - info["errors"].append() = "transform only supports one of: scale, translate, rotate, reflect, or matrix"; - res = false; - } - - if(mode_count == 0) - { - info["errors"].append() = "transform requires parameters for: scale, translate, rotate, reflect, or matrix"; - res = false; - } - - if(params.has_child("scale")) - { - const Node &p_vals = params["scale"]; - if( ! p_vals.has_child("x") && - ! p_vals.has_child("y") && - ! p_vals.has_child("z") ) - { - res = false; - info["errors"].append()="scale transform requires: scale/x, scale/y, and/or scale/z"; - } - res &= check_numeric("x", p_vals, info, false, true); - res &= check_numeric("y", p_vals, info, false, true); - res &= check_numeric("z", p_vals, info, false, true); - } - - if(params.has_child("translate")) - { - const Node &p_vals = params["translate"]; - if( ! p_vals.has_child("x") && - ! p_vals.has_child("y") && - ! p_vals.has_child("z") ) - { - res = false; - info["errors"].append() = "translate transform requires: translate/x, translate/y, and/or translate/z"; - } - res &= check_numeric("x", p_vals, info, false, true); - res &= check_numeric("y", p_vals, info, false, true); - res &= check_numeric("z", p_vals, info, false, true); - } - - if(params.has_child("rotate")) - { - const Node &p_vals = params["rotate"]; - bool rotate_ok = check_numeric("angle", p_vals, info, true, true); - - if(p_vals.has_child("axis")) - { - const Node &p_axis = p_vals["axis"]; - if( ! p_axis.has_child("x") && - ! p_axis.has_child("y") && - ! p_axis.has_child("z") ) - { - rotate_ok = false; - } - - res &= check_numeric("x", p_axis, info, false, true); - res &= check_numeric("y", p_axis, info, false, true); - res &= check_numeric("z", p_axis, info, false, true); - - } - else - { - rotate_ok = false; - } - - if(!rotate_ok) - { - res = false; - info["errors"].append()="rotate transform requires: rotate/angle and rotate/axis/x, rotate/axis/y, and/or rotate/axis/z"; - } - } - - if(params.has_child("reflect")) - { - const Node &p_vals = params["reflect"]; - if( ! p_vals.has_child("x") && - ! p_vals.has_child("y") && - ! p_vals.has_child("z") ) - { - res = false; - info["errors"].append() = "reflect transform requires: reflect/x, reflect/y, and/or reflect/z"; - } - res &= check_numeric("x", p_vals, info, false, true); - res &= check_numeric("y", p_vals, info, false, true); - res &= check_numeric("z", p_vals, info, false, true); - } - - if(params.has_child("matrix")) - { - res &= check_numeric("matrix",params, info, true, true); - if(res) - { - // make sure it is 16 long - index_t matrix_len = params["matrix"].dtype().number_of_elements(); - if(matrix_len != 16) - { - res = false; - info["errors"].append()="matrix must an array with 16 entries (representing a 4x4 transform matrix)"; - } - } - } - - std::vector valid_paths = { "scale/x", - "scale/y", - "scale/z", - "translate/x", - "translate/y", - "translate/z", - "rotate/angle", - "rotate/axis/x", - "rotate/axis/y", - "rotate/axis/z", - "reflect/x", - "reflect/y", - "reflect/z", - "matrix"}; - - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -5096,126 +4519,121 @@ VTKHParticleAdvection::declare_interface(Node &i) i["type_name"] = "vtkh_particle_advection"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHParticleAdvection::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - bool res = check_string("field", params, info, true); - res &= check_numeric("num_steps", params, info, true, true); - res &= check_numeric("step_size", params, info, true, true); - info.reset(); - - if(!params.has_child("seeds")) - { - info["errors"].append() = "Missing required parameter. Particle Advection must specify seeds"; - res = false; - } - else - { - conduit::Node seed_params = params["seeds"]; - if(!seed_params.has_child("type")) - { - info["errors"].append() = "Missing required parameter. Particle Advection must specify seed type"; - res = false; - } - else - { - - res &= check_string("type", seed_params, info, true); - std::string type = seed_params["type"].as_string(); - if(type == "point") - { - res &= check_numeric("location",seed_params,info,true); - } - else if(type == "point_list") - { - res &= check_numeric("location",seed_params,info,true); - } - else if(type == "line") - { - res &= check_numeric("start",seed_params,info,true); - res &= check_numeric("end",seed_params,info,true); - res &= check_numeric("num_seeds",seed_params,info,true); - res &= check_string("sampling_type", seed_params, info, true); - } - else if(type == "box") - { - res &= check_string("sampling_space", seed_params, info, true); - res &= check_string("sampling_type", seed_params, info, true); - string sampling_type = seed_params["sampling_type"].as_string(); - if(sampling_type == "uniform") - { - res &= check_numeric("num_seeds_x",seed_params,info,true); - res &= check_numeric("num_seeds_y",seed_params,info,true); - res &= check_numeric("num_seeds_z",seed_params,info,true); - } - else - { - res &= check_numeric("num_seeds",seed_params,info,true); - } - - if(seed_params.has_child("extents_x")) - { - res &= check_numeric("extents_x",seed_params,info,true); - res &= check_numeric("extents_y",seed_params,info,true); - res &= check_numeric("extents_z",seed_params,info,true); - } - } - else - { - info["errors"].append() = "Unrecognized parameter. Particle Advection supports seed types 'point', 'point_list', 'line', or 'box'."; - res = false; - } - } - } - - if(params.has_child("rendering")) - { - res &= check_string("rendering/enable_tubes", params, info, false); - res &= check_string("rendering/tube_capping", params, info, false); - res &= check_numeric("rendering/tube_size", params, info, false); - res &= check_numeric("rendering/tube_sides", params, info, false); - res &= check_numeric("rendering/tube_value", params, info, false); - res &= check_string("rendering/output_field", params, info, false); - } - - std::vector valid_paths; - valid_paths.push_back("field"); - valid_paths.push_back("num_steps"); - valid_paths.push_back("step_size"); - valid_paths.push_back("seeds/type"); - valid_paths.push_back("seeds/location"); - valid_paths.push_back("seeds/start"); - valid_paths.push_back("seeds/end"); - valid_paths.push_back("seeds/num_seeds"); - valid_paths.push_back("seeds/num_seeds_x"); - valid_paths.push_back("seeds/num_seeds_y"); - valid_paths.push_back("seeds/num_seeds_z"); - valid_paths.push_back("seeds/extents_x"); - valid_paths.push_back("seeds/extents_y"); - valid_paths.push_back("seeds/extents_z"); - valid_paths.push_back("seeds/sampling_type"); - valid_paths.push_back("seeds/sampling_space"); - valid_paths.push_back("rendering/enable_tubes"); - valid_paths.push_back("rendering/tube_capping"); - valid_paths.push_back("rendering/tube_size"); - valid_paths.push_back("rendering/tube_sides"); - valid_paths.push_back("rendering/tube_value"); - valid_paths.push_back("rendering/output_field"); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - std::string surprises = surprise_check(valid_paths, params); + param_schema["properties/field"].set(string_schema()); + param_schema["properties/num_steps"].set(number_schema()); + param_schema["properties/step_size"].set(number_schema()); + + // --- seed --- + conduit::Node seed_schema; + seed_schema["type"] = "object"; + seed_schema["additionalProperties"] = false; + seed_schema["properties/type"].set(string_schema()); + seed_schema["properties/location"].set(number_schema()); + seed_schema["properties/start"].set(number_schema()); + seed_schema["properties/end"].set(number_schema()); + seed_schema["properties/num_seeds"].set(number_schema()); + seed_schema["properties/num_seeds_x"].set(number_schema()); + seed_schema["properties/num_seeds_y"].set(number_schema()); + seed_schema["properties/num_seeds_z"].set(number_schema()); + seed_schema["properties/extents_x"].set(number_schema()); + seed_schema["properties/extents_y"].set(number_schema()); + seed_schema["properties/extents_z"].set(number_schema()); + seed_schema["properties/sampling_type"].set(string_schema()); + seed_schema["properties/sampling_space"].set(string_schema()); + seed_schema["required"].append() = "type"; + + seed_schema["constraints/dependencies/extents_x"].append() = "extents_y"; + seed_schema["constraints/dependencies/extents_x"].append() = "extents_z"; + seed_schema["constraints/dependencies/extents_y"].append() = "extents_x"; + seed_schema["constraints/dependencies/extents_y"].append() = "extents_z"; + seed_schema["constraints/dependencies/extents_z"].append() = "extents_x"; + seed_schema["constraints/dependencies/extents_z"].append() = "extents_y"; + + // type == point + conduit::Node point_option; + point_option["type"] = "object"; + point_option["properties/type/type"] = "string"; + point_option["properties/type/constraints/const"] = "point"; + point_option["required"].append() = "type"; + point_option["required"].append() = "location"; + seed_schema["oneOf"].append().set(point_option); + + // type == point_list + conduit::Node point_list_option; + point_list_option["type"] = "object"; + point_list_option["properties/type/type"] = "string"; + point_list_option["properties/type/constraints/const"] = "point_list"; + point_list_option["required"].append() = "type"; + point_list_option["required"].append() = "location"; + seed_schema["oneOf"].append().set(point_list_option); + + // type == line + conduit::Node line_option; + line_option["type"] = "object"; + line_option["properties/type/type"] = "string"; + line_option["properties/type/constraints/const"] = "line"; + line_option["required"].append() = "type"; + line_option["required"].append() = "start"; + line_option["required"].append() = "end"; + line_option["required"].append() = "num_seeds"; + line_option["required"].append() = "sampling_type"; + seed_schema["oneOf"].append().set(line_option); + + // type == box + conduit::Node box_option; + box_option["type"] = "object"; + box_option["properties/type/type"] = "string"; + box_option["properties/type/constraints/const"] = "box"; + box_option["required"].append() = "type"; + box_option["required"].append() = "sampling_space"; + box_option["required"].append() = "sampling_type"; + { + conduit::Node box_option_uniform; + box_option_uniform["type"] = "object"; + box_option_uniform["properties/sampling_type/type"] = "string"; + box_option_uniform["properties/sampling_type/constraints/const"] = "uniform"; + box_option_uniform["required"].append() = "sampling_type"; + box_option_uniform["required"].append() = "num_seeds_x"; + box_option_uniform["required"].append() = "num_seeds_y"; + box_option_uniform["required"].append() = "num_seeds_z"; + box_option["oneOf"].append().set(box_option_uniform); + } + { + conduit::Node box_option_non_uniform; + box_option_non_uniform["type"] = "object"; + box_option_non_uniform["required"].append() = "sampling_type"; + box_option_non_uniform["required"].append() = "num_seeds"; + box_option_non_uniform["constraints/not_const/sampling_type"] = "uniform"; + box_option["oneOf"].append().set(box_option_non_uniform); + } + seed_schema["oneOf"].append().set(box_option); + + param_schema["properties/seed"].set(seed_schema); + + // --- rendering --- + conduit::Node rendering_schema; + rendering_schema["type"] = "object"; + rendering_schema["additionalProperties"] = false; + rendering_schema["properties/enable_tubes"].set(string_schema()); + rendering_schema["properties/tube_capping"].set(string_schema()); + rendering_schema["properties/tube_size"].set(number_schema()); + rendering_schema["properties/tube_sides"].set(number_schema()); + rendering_schema["properties/tube_value"].set(number_schema()); + rendering_schema["properties/output_field"].set(string_schema()); + param_schema["properties/rendering"].set(rendering_schema); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["required"].append() = "field"; + param_schema["required"].append() = "num_steps"; + param_schema["required"].append() = "step_size"; + param_schema["required"].append() = "seed"; - return res; + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -5749,55 +5167,35 @@ VTKHWarpXStreamline::declare_interface(Node &i) i["type_name"] = "vtkh_warpx_streamline"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHWarpXStreamline::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("b_field", params, info, false); - res &= check_string("e_field", params, info, false); - res &= check_numeric("num_steps", params, info, true, true); - res &= check_numeric("step_size", params, info, true, true); - - if(params.has_child("rendering")) - { - res &= check_string("rendering/enable_tubes", params, info, false); - res &= check_string("rendering/tube_capping", params, info, false); - res &= check_numeric("rendering/tube_size", params, info, false); - res &= check_numeric("rendering/tube_sides", params, info, false); - res &= check_numeric("rendering/tube_value", params, info, false); - res &= check_string("rendering/output_field", params, info, false); - } - - std::vector valid_paths; - valid_paths.push_back("b_field"); - valid_paths.push_back("e_field"); - valid_paths.push_back("charge_field"); - valid_paths.push_back("mass_field"); - valid_paths.push_back("momentum_field"); - valid_paths.push_back("weighting_field"); - valid_paths.push_back("num_steps"); - valid_paths.push_back("step_size"); - valid_paths.push_back("rendering/enable_tubes"); - valid_paths.push_back("rendering/tube_capping"); - valid_paths.push_back("rendering/tube_size"); - valid_paths.push_back("rendering/tube_sides"); - valid_paths.push_back("rendering/tube_value"); - valid_paths.push_back("rendering/output_field"); - std::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - return res; + param_schema["properties/b_field"].set(string_schema()); + param_schema["properties/e_field"].set(string_schema()); + param_schema["properties/num_steps"].set(number_schema()); + param_schema["properties/step_size"].set(number_schema()); + + // --- rendering --- + conduit::Node rendering_schema; + rendering_schema["type"] = "object"; + rendering_schema["additionalProperties"] = false; + rendering_schema["properties/enable_tubes"].set(string_schema()); + rendering_schema["properties/tube_capping"].set(string_schema()); + rendering_schema["properties/tube_size"].set(number_schema()); + rendering_schema["properties/tube_sides"].set(number_schema()); + rendering_schema["properties/tube_value"].set(number_schema()); + rendering_schema["properties/output_field"].set(string_schema()); + param_schema["properties/rendering"].set(rendering_schema); + + param_schema["required"].append() = "num_steps"; + param_schema["required"].append() = "step_size"; + + i["param_schema"].set(param_schema); } + //----------------------------------------------------------------------------- void VTKHWarpXStreamline::execute() @@ -5959,38 +5357,18 @@ VTKHVTKFileExtract::declare_interface(Node &i) i["type_name"] = "vtkh_vtk_file_extract"; i["port_names"].append() = "in"; i["output_port"] = "false"; -} -//----------------------------------------------------------------------------- -bool -VTKHVTKFileExtract::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - - bool res = true; - - if( !params.has_child("path") ) - { - info["errors"].append() = "missing required entry 'path'"; - res = false; - } - - res = check_string("topology",params, info, false) && res; - - std::vector valid_paths; - valid_paths.push_back("path"); - valid_paths.push_back("topology"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/path"].set(string_schema()); + param_schema["properties/topology"].set(string_schema()); - return res; + param_schema["required"].append() = "path"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -6171,39 +5549,22 @@ VTKHMIR::declare_interface(Node &i) i["type_name"] = "vtkh_mir"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHMIR::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = check_string("matset",params, info, true); - res &= check_string("output_name", params, info, false); - res &= check_numeric("error_scaling", params, info, false); - res &= check_numeric("scaling_decay", params, info, false); - res &= check_numeric("iterations", params, info, false); - res &= check_numeric("max_error", params, info, false); - - std::vector valid_paths; - valid_paths.push_back("matset"); - valid_paths.push_back("output_name"); - valid_paths.push_back("error_scaling"); - valid_paths.push_back("scaling_decay"); - valid_paths.push_back("iterations"); - valid_paths.push_back("max_error"); - - std::string surprises = surprise_check(valid_paths, params); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } + param_schema["properties/matset"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); + param_schema["properties/error_scaling"].set(number_schema()); + param_schema["properties/scaling_decay"].set(number_schema()); + param_schema["properties/iterations"].set(number_schema()); + param_schema["properties/max_error"].set(number_schema()); - return res; + param_schema["required"].append() = "matset"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp index 7cffa8a49..96b3484ac 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_vtkh_filters.hpp @@ -51,8 +51,6 @@ class ASCENT_API VTKHMarchingCubes : public ::flow::Filter virtual ~VTKHMarchingCubes(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -64,8 +62,6 @@ class ASCENT_API VTKHExternalSurfaces : public ::flow::Filter virtual ~VTKHExternalSurfaces(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -77,8 +73,6 @@ class ASCENT_API VTKHVectorMagnitude : public ::flow::Filter virtual ~VTKHVectorMagnitude(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -111,8 +105,6 @@ class ASCENT_API VTKH3Slice : public ::flow::Filter virtual ~VTKH3Slice(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -182,8 +174,6 @@ class ASCENT_API VTKHClipWithField : public ::flow::Filter virtual ~VTKHClipWithField(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -195,8 +185,6 @@ class ASCENT_API VTKHIsoVolume : public ::flow::Filter virtual ~VTKHIsoVolume(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -208,8 +196,6 @@ class ASCENT_API VTKHLagrangian : public ::flow::Filter virtual ~VTKHLagrangian(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -221,8 +207,6 @@ class ASCENT_API VTKHLog: public ::flow::Filter virtual ~VTKHLog(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -234,8 +218,6 @@ class ASCENT_API VTKHLog10: public ::flow::Filter virtual ~VTKHLog10(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -247,8 +229,6 @@ class ASCENT_API VTKHLog2: public ::flow::Filter virtual ~VTKHLog2(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -260,8 +240,6 @@ class ASCENT_API VTKHRecenter: public ::flow::Filter virtual ~VTKHRecenter(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -273,8 +251,6 @@ class ASCENT_API VTKHHistSampling : public ::flow::Filter virtual ~VTKHHistSampling(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -286,8 +262,6 @@ class ASCENT_API VTKHQCriterion: public ::flow::Filter virtual ~VTKHQCriterion(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -299,8 +273,6 @@ class ASCENT_API VTKHDivergence: public ::flow::Filter virtual ~VTKHDivergence(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -312,8 +284,6 @@ class ASCENT_API VTKHVorticity: public ::flow::Filter virtual ~VTKHVorticity(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -325,8 +295,6 @@ class ASCENT_API VTKHGradient : public ::flow::Filter virtual ~VTKHGradient(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -338,8 +306,6 @@ class ASCENT_API VTKHNoOp : public ::flow::Filter virtual ~VTKHNoOp(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -351,8 +317,6 @@ class ASCENT_API VTKHVectorComponent : public ::flow::Filter virtual ~VTKHVectorComponent(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -364,8 +328,6 @@ class ASCENT_API VTKHCompositeVector : public ::flow::Filter virtual ~VTKHCompositeVector(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -377,8 +339,6 @@ class ASCENT_API VTKHStats : public ::flow::Filter virtual ~VTKHStats(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -390,8 +350,6 @@ class ASCENT_API VTKHUniformGrid : public ::flow::Filter virtual ~VTKHUniformGrid(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -403,8 +361,6 @@ class ASCENT_API VTKHSample : public ::flow::Filter virtual ~VTKHSample(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -416,8 +372,6 @@ class ASCENT_API VTKHHistogram : public ::flow::Filter virtual ~VTKHHistogram(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -430,8 +384,6 @@ class ASCENT_API VTKHProject2d : public ::flow::Filter virtual ~VTKHProject2d(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -455,8 +407,6 @@ class ASCENT_API VTKHScale : public ::flow::Filter virtual ~VTKHScale(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -468,8 +418,6 @@ class ASCENT_API VTKHTransform : public ::flow::Filter virtual ~VTKHTransform(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -481,8 +429,6 @@ class ASCENT_API VTKHTriangulate : public ::flow::Filter virtual ~VTKHTriangulate(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -494,8 +440,6 @@ class ASCENT_API VTKHParticleAdvection : public ::flow::Filter virtual ~VTKHParticleAdvection(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); protected: @@ -519,8 +463,6 @@ class ASCENT_API VTKHWarpXStreamline : public ::flow::Filter virtual ~VTKHWarpXStreamline(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); protected: @@ -535,8 +477,6 @@ class ASCENT_API VTKHVTKFileExtract : public ::flow::Filter virtual ~VTKHVTKFileExtract(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; @@ -550,8 +490,6 @@ class ASCENT_API VTKHMIR : public ::flow::Filter virtual ~VTKHMIR(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, - conduit::Node &info); virtual void execute(); }; diff --git a/src/libs/flow/flow_schema_validator.cpp b/src/libs/flow/flow_schema_validator.cpp index 09ae400da..e6c4232a3 100644 --- a/src/libs/flow/flow_schema_validator.cpp +++ b/src/libs/flow/flow_schema_validator.cpp @@ -62,6 +62,7 @@ static bool check_type(const conduit::Node &input, if(schema_defined_type == "object") ok = data_type.is_object(); else if(schema_defined_type == "string") ok = data_type.is_string(); else if(schema_defined_type == "number") ok = data_type.is_number(); + else if(schema_defined_type == "array") ok = (data_type.is_list() || (data_type.is_number() && data_type.number_of_elements() >= 1)); else { add_error(info, "At '" + (path.empty() ? std::string("") : path) + @@ -123,6 +124,59 @@ static bool validate_forbid(const conduit::Node &schema, return ok; } +static bool validate_const(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_path("constraints/const")) return true; + + const conduit::Node &c = schema["constraints/const"]; + // Only implement string const for now (that’s all we used above) + if(input.dtype().is_string() && c.dtype().is_string()) + { + const std::string got = input.as_string(); + const std::string expect = c.as_string(); + if(got != expect) + { + add_error(info, "Value mismatch at '" + (path.empty() ? std::string("") : path) + + "': expected '" + expect + "', got '" + got + "'"); + return false; + } + } + return true; +} + +static bool validate_not_const_fields(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_path("constraints/not_const")) return true; + if(!input.dtype().is_object()) return true; + + bool ok = true; + const conduit::Node &nc = schema["constraints/not_const"]; + for(conduit::index_t i = 0; i < nc.number_of_children(); ++i) + { + const std::string field = nc[i].name(); + const conduit::Node &forbidden_val = nc[field]; + + if(input.has_child(field) && input[field].dtype().is_string() && forbidden_val.dtype().is_string()) + { + const std::string got = input[field].as_string(); + const std::string bad = forbidden_val.as_string(); + if(got == bad) + { + add_error(info, "Value forbidden at '" + conduit::utils::join_file_path(path, field) + + "': must not be '" + bad + "'"); + ok = false; + } + } + } + return ok; +} + static bool validate_properties(const conduit::Node &schema, const conduit::Node &input, conduit::Node &info, @@ -331,6 +385,56 @@ static bool validate_one_of(const conduit::Node &schema, return false; } +static bool validate_any_of(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_child("anyOf")) return true; + + const conduit::Node &opts = schema["anyOf"]; + int matches = 0; + + // collect a couple representative failures for hints + std::vector option_msgs; + + for(conduit::index_t i = 0; i < opts.number_of_children(); ++i) + { + const conduit::Node &opt = opts.child(i); + + conduit::Node tmp; + tmp.reset(); + + bool ok = true; + ok = check_type(input, opt, tmp, path) && ok; + ok = validate_required(opt, input, tmp, path) && ok; + ok = validate_forbid(opt, input, tmp, path) && ok; + ok = validate_dependencies(opt, input, tmp, path) && ok; + ok = validate_exclusive_children(opt, input, tmp, path) && ok; + + if(ok) + { + matches++; + } + else if(tmp.has_child("errors") && tmp["errors"].number_of_children() > 0) + { + option_msgs.push_back(tmp["errors"].child(0).as_string()); + } + } + + if(matches >= 1) return true; + + add_error(info, "anyOf violation at '" + (path.empty() ? std::string("") : path) + + "': input did not match any option"); + + for(size_t i = 0; i < option_msgs.size() && i < 2; ++i) + { + add_error(info, std::string(" hint: ") + option_msgs[i]); + } + + return false; +} + static bool validate_object(const conduit::Node &schema, const conduit::Node &input, conduit::Node &info, @@ -341,6 +445,7 @@ static bool validate_object(const conduit::Node &schema, // Base checks first ok = validate_required(schema, input, info, path) && ok; ok = validate_forbid(schema, input, info, path) && ok; + ok = validate_not_const_fields(schema, input, info, path) && ok; ok = validate_dependencies(schema, input, info, path) && ok; ok = validate_exclusive_children(schema, input, info, path) && ok; @@ -352,7 +457,60 @@ static bool validate_object(const conduit::Node &schema, // Finally, enforce oneOf (treating options as extra constraints on this same object) ok = validate_one_of(schema, input, info, path) && ok; + ok = validate_any_of(schema, input, info, path) && ok; + + return ok; +} + +static bool validate_array(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + bool ok = true; + + const auto data_type = input.dtype(); + const conduit::index_t count = data_type.is_list() ? input.number_of_children() : data_type.number_of_elements(); + + // Json Schema uses min/max bounds for array length. + if(schema.has_child("minItems")) + { + const conduit::index_t min_items = (conduit::index_t)schema["minItems"].to_int(); + if(count < min_items) + { + add_error(info, + "Array at '" + (path.empty() ? std::string("") : path) + + "' has too few items: expected at least " + + std::to_string((long long)min_items) + ", got " + + std::to_string((long long)count)); + ok = false; + } + } + if(schema.has_child("maxItems")) + { + const conduit::index_t max_items = (conduit::index_t)schema["maxItems"].to_int(); + if(count > max_items) + { + add_error(info, + "Array at '" + (path.empty() ? std::string("") : path) + + "' has too many items: expected at most " + + std::to_string((long long)max_items) + ", got " + + std::to_string((long long)count)); + ok = false; + } + } + + if(!schema.has_child("items")) return true; // unconstrained items + + const conduit::Node &item_schema = schema["items"]; + if(data_type.is_list()) { + for(conduit::index_t i = 0; i < count; ++i) + { + ok = validate_node(item_schema, input.child(i), info, + path + "[" + std::to_string((int)i) + "]") && ok; + } + } return ok; } @@ -361,18 +519,44 @@ static bool validate_node(const conduit::Node &schema, conduit::Node &info, const std::string &path) { + if (schema.has_path("constraints/skip") && schema["constraints/skip"].to_int() != 0) + { + return true; + } + + const std::string schema_defined_type = get_type_string(schema); + if(schema_defined_type == "object" && input.dtype().is_empty()) + { + conduit::Node empty_obj; + empty_obj.set(conduit::DataType::object()); + return validate_object(schema, empty_obj, info, path); + } + if(schema_defined_type == "array" && input.dtype().is_empty()) + { + conduit::Node empty_list; + empty_list.set(conduit::DataType::list()); + return validate_array(schema, empty_list, info, path); + } + bool ok = true; ok = check_type(input, schema, info, path) && ok; + ok = validate_const(schema, input, info, path) && ok; if(!ok) return false; // type mismatch stops recursion - const std::string schema_defined_type = get_type_string(schema); + + if(schema_defined_type == "object") { return validate_object(schema, input, info, path); } + if (schema_defined_type == "array") + { + return validate_array(schema, input, info, path); + } ok = validate_one_of(schema, input, info, path) && ok; + ok = validate_any_of(schema, input, info, path) && ok; return ok; } From 96efc0e56ddee27df31d66ba0ebb276af3c262da Mon Sep 17 00:00:00 2001 From: Emily Howell Date: Fri, 27 Feb 2026 16:49:49 -0800 Subject: [PATCH 6/6] Removing temporary helpers and cleaning up files --- .../ascent_runtime_param_check.cpp | 82 +++++-------------- .../ascent_runtime_param_check.hpp | 2 - src/libs/flow/flow_schema_validator.cpp | 2 +- src/libs/flow/flow_schema_validator.hpp | 2 +- 4 files changed, 24 insertions(+), 64 deletions(-) diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp index 0e75196c7..a3288f702 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.cpp @@ -72,6 +72,28 @@ conduit::Node string_schema() return n; } +conduit::Node vec3_schema(const std::string var1, const std::string var2, const std::string var3) +{ + conduit::Node n; + n["type"] = "object"; + n["additionalProperties"] = false; + + n["properties/" + var1].set(number_schema()); + n["properties/" + var2].set(number_schema()); + n["properties/" + var3].set(number_schema()); + + n["required"].append() = var1; + n["required"].append() = var2; + n["required"].append() = var3; + + return n; +} + +conduit::Node vec3_schema() +{ + return vec3_schema("x", "y", "z"); +} + conduit::Node vec3_schema_anyOf(const std::string var1, const std::string var2, const std::string var3) { conduit::Node n; @@ -105,28 +127,6 @@ conduit::Node vec3_schema_anyOf() return vec3_schema_anyOf("x", "y", "z"); } -conduit::Node vec3_schema(const std::string var1, const std::string var2, const std::string var3) -{ - conduit::Node n; - n["type"] = "object"; - n["additionalProperties"] = false; - - n["properties/" + var1].set(number_schema()); - n["properties/" + var2].set(number_schema()); - n["properties/" + var3].set(number_schema()); - - n["required"].append() = var1; - n["required"].append() = var2; - n["required"].append() = var3; - - return n; -} - -conduit::Node vec3_schema() -{ - return vec3_schema("x", "y", "z"); -} - conduit::Node array_schema(const conduit::Node &item_schema) { conduit::Node n; @@ -414,44 +414,6 @@ surprise_check(const std::vector &valid_paths, return ss.str(); } -//----------------------------------------------------------------------------- -std::string -surprise_check(const conduit::Node &properties, - const conduit::Node ¶ms) -{ - // only children can surprise us - if(params.number_of_children() == 0) - { - return ""; - } - - std::stringstream ss; -// std::vector paths; -// path_helper(paths, params); -// const int num_paths = static_cast(paths.size()); -// // const int num_valid_paths = static_cast(properties.size()); -// std::string curr_path = params.path() == "" ? "" :params.path() + "/"; -// for(int i = 0; i < num_paths; ++i) -// { -// bool found = false; -// for(int f = 0; f < num_valid_paths; ++f) -// { -// if(curr_path + valid_paths[f] == paths[i]) -// { -// found = true; -// break; -// } -// } - -// if(!found) -// { -// ss<<"Surprise parameter '"< &paths, const conduit::Node &node) diff --git a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp index 50413c9a0..e137446dd 100644 --- a/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp +++ b/src/libs/ascent/runtimes/flow_filters/ascent_runtime_param_check.hpp @@ -100,8 +100,6 @@ void ASCENT_API path_helper(std::vector &paths, std::string ASCENT_API surprise_check(const std::vector &valid_paths, const conduit::Node &node); -std::string ASCENT_API surprise_check(const conduit::Node &properties, - const conduit::Node &node); // // Ignore paths only ignores top level paths, differing lower level // paths to another surprise check. diff --git a/src/libs/flow/flow_schema_validator.cpp b/src/libs/flow/flow_schema_validator.cpp index e6c4232a3..d9faef8be 100644 --- a/src/libs/flow/flow_schema_validator.cpp +++ b/src/libs/flow/flow_schema_validator.cpp @@ -588,4 +588,4 @@ bool validate(const conduit::Node &schema, }; //----------------------------------------------------------------------------- // -- end flow -- -//----------------------------------------------------------------------------- \ No newline at end of file +//----------------------------------------------------------------------------- diff --git a/src/libs/flow/flow_schema_validator.hpp b/src/libs/flow/flow_schema_validator.hpp index 11043ff70..835081c4e 100644 --- a/src/libs/flow/flow_schema_validator.hpp +++ b/src/libs/flow/flow_schema_validator.hpp @@ -105,4 +105,4 @@ static void add_error(conduit::Node &info, const std::string &msg); #endif //----------------------------------------------------------------------------- // -- end header ifdef guard -//----------------------------------------------------------------------------- \ No newline at end of file +//-----------------------------------------------------------------------------