diff --git a/src/libs/ascent/ascent.cpp b/src/libs/ascent/ascent.cpp index 3194006e5..156a00d14 100644 --- a/src/libs/ascent/ascent.cpp +++ b/src/libs/ascent/ascent.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include @@ -649,6 +651,9 @@ Ascent::open(const conduit::Node &options) m_runtime->Initialize(m_options); + // Set the flow filter expression checker: + flow::schema::set_expression_checker(&runtime::filters::is_valid_expression); + // don't print info messages unless we are using verbose // Runtimes may set their own handlers in initialize, so // make sure to do this after. diff --git a/src/libs/ascent/runtimes/expressions/ascent_expression_filters.cpp b/src/libs/ascent/runtimes/expressions/ascent_expression_filters.cpp index 6bdd9cd12..04cccf516 100644 --- a/src/libs/ascent/runtimes/expressions/ascent_expression_filters.cpp +++ b/src/libs/ascent/runtimes/expressions/ascent_expression_filters.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -944,20 +945,16 @@ ExprBoolean::declare_interface(Node &i) i["type_name"] = "expr_bool"; i["port_names"] = DataType::empty(); i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -ExprBoolean::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - if(!params.has_path("value")) - { - info["errors"].append() = "Missing required numeric parameter 'value'"; - res = false; - } - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + param_schema["properties/value"].set(filters::number_schema()); + param_schema["required"].append() = "value"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -993,20 +990,16 @@ ExprInteger::declare_interface(Node &i) i["type_name"] = "expr_integer"; i["port_names"] = DataType::empty(); i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -ExprInteger::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - if(!params.has_path("value")) - { - info["errors"].append() = "Missing required numeric parameter 'value'"; - res = false; - } - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + param_schema["properties/value"].set(filters::number_schema()); + param_schema["required"].append() = "value"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1043,20 +1036,16 @@ ExprDouble::declare_interface(Node &i) i["type_name"] = "expr_double"; i["port_names"] = DataType::empty(); i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -ExprDouble::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - if(!params.has_path("value")) - { - info["errors"].append() = "Missing required numeric parameter 'value'"; - res = false; - } - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + param_schema["properties/value"].set(filters::number_schema()); + param_schema["required"].append() = "value"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1094,20 +1083,16 @@ ExprString::declare_interface(Node &i) i["type_name"] = "expr_string"; i["port_names"] = DataType::empty(); i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -ExprString::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - if(!params.has_path("value")) - { - info["errors"].append() = "Missing required string parameter 'value'"; - res = false; - } - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + param_schema["properties/value"].set(filters::string_schema()); + param_schema["required"].append() = "value"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1146,15 +1131,6 @@ ExprNan::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprNan::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprNan::execute() @@ -1192,15 +1168,6 @@ ExprNull::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprNull::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprNull::execute() @@ -1233,20 +1200,16 @@ ExprIdentifier::declare_interface(Node &i) i["type_name"] = "expr_identifier"; i["port_names"] = DataType::empty(); i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -ExprIdentifier::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - if(!params.has_path("value")) - { - info["errors"].append() = "Missing required string parameter 'value'"; - res = false; - } - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + param_schema["properties/value"].set(filters::string_schema()); + param_schema["required"].append() = "value"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1301,20 +1264,16 @@ ExprObjectDotAccess::declare_interface(Node &i) i["type_name"] = "expr_dot"; i["port_names"].append() = "obj"; i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -ExprObjectDotAccess::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - if(!params.has_path("name")) - { - info["errors"].append() = "DotAccess: Missing required parameter 'name'"; - res = false; - } - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + param_schema["properties/name"].set(filters::string_schema()); + param_schema["required"].append() = "name"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1390,15 +1349,6 @@ ExprIf::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprIf::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprIf::execute() @@ -1447,20 +1397,16 @@ ExprBinaryOp::declare_interface(Node &i) i["port_names"].append() = "lhs"; i["port_names"].append() = "rhs"; i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -ExprBinaryOp::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - if(!params.has_path("op_string")) - { - info["errors"].append() = "Missing required string parameter 'op_string'"; - res = false; - } - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + param_schema["properties/op_string"].set(filters::string_schema()); + param_schema["required"].append() = "op_string"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1575,15 +1521,6 @@ ExprScalarMin::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprScalarMin::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprScalarMin::execute() @@ -1639,15 +1576,6 @@ ExprScalarMax::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprScalarMax::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprScalarMax::execute() @@ -1704,15 +1632,6 @@ ExprScalarAbs::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprScalarAbs::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprScalarAbs::execute() @@ -1770,15 +1689,6 @@ ExprScalarExp::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprScalarExp::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprScalarExp::execute() @@ -1821,15 +1731,6 @@ ExprScalarLog::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprScalarLog::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprScalarLog::execute() @@ -1872,15 +1773,6 @@ ExprScalarPow::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprScalarPow::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprScalarPow::execute() @@ -1937,15 +1829,6 @@ ExprVector::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprVector::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprVector::execute() @@ -1993,16 +1876,6 @@ ExprVectorMagnitude::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprVectorMagnitude::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprVectorMagnitude::execute() @@ -2056,15 +1929,6 @@ ExprArrayAccess::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprArrayAccess::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprArrayAccess::execute() @@ -2118,15 +1982,6 @@ ExprArrayReplace::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprArrayReplace::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprArrayReplace::execute() @@ -2218,15 +2073,6 @@ ExprArrayReductionMin::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprArrayReductionMin::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprArrayReductionMin::execute() @@ -2266,15 +2112,6 @@ ExprArrayReductionMax::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprArrayReductionMax::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprArrayReductionMax::execute() @@ -2314,15 +2151,6 @@ ExprArrayReductionAvg::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprArrayReductionAvg::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprArrayReductionAvg::execute() @@ -2362,15 +2190,6 @@ ExprArrayReductionSum::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprArrayReductionSum::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprArrayReductionSum::execute() @@ -2421,15 +2240,6 @@ ExprHistory::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistory::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprHistory::execute() @@ -2538,16 +2348,6 @@ ExprHistoryRange::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistoryRange::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - - //----------------------------------------------------------------------------- void ExprHistoryRange::execute() @@ -2615,15 +2415,6 @@ ExprHistoryGradient::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistoryGradient::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprHistoryGradient::execute() @@ -2823,16 +2614,6 @@ ExprHistoryGradientRange::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistoryGradientRange::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - - //----------------------------------------------------------------------------- void ExprHistoryGradientRange::execute() @@ -2930,15 +2711,6 @@ ExprHistogram::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistogram::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprHistogram::execute() @@ -3041,15 +2813,6 @@ ExprHistogramEntropy::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistogramEntropy::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprHistogramEntropy::execute() @@ -3094,15 +2857,6 @@ ExprHistogramPDF::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistogramPDF::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprHistogramPDF::execute() @@ -3146,15 +2900,6 @@ ExprHistogramCDF::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistogramCDF::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprHistogramCDF::execute() @@ -3201,15 +2946,6 @@ ExprHistogramCDFQuantile::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistogramCDFQuantile::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprHistogramCDFQuantile::execute() @@ -3276,15 +3012,6 @@ ExprHistogramBinByIndex::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistogramBinByIndex::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprHistogramBinByIndex::execute() @@ -3337,16 +3064,6 @@ ExprHistogramBinByValue::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprHistogramBinByValue::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprHistogramBinByValue::execute() @@ -3413,15 +3130,6 @@ ExprMeshCycle::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshCycle::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshCycle::execute() @@ -3471,15 +3179,6 @@ ExprMeshTime::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshTime::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshTime::execute() @@ -3531,15 +3230,6 @@ ExprMeshField::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshField::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshField::execute() @@ -3653,15 +3343,6 @@ ExprMeshTopology::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshTopology::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshTopology::execute() @@ -3726,15 +3407,6 @@ ExprMeshBounds::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshBounds::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshBounds::execute() @@ -3824,15 +3496,6 @@ ExprMeshLineout::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshLineout::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshLineout::execute() @@ -3994,15 +3657,6 @@ ExprMeshFieldReductionMin::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshFieldReductionMin::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshFieldReductionMin::execute() @@ -4067,15 +3721,6 @@ ExprMeshFieldReductionMax::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshFieldReductionMax::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshFieldReductionMax::execute() @@ -4138,15 +3783,6 @@ ExprMeshFieldReductionAvg::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshFieldReductionAvg::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshFieldReductionAvg::execute() @@ -4200,15 +3836,6 @@ ExprMeshFieldReductionSum::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshFieldReductionSum::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshFieldReductionSum::execute() @@ -4252,15 +3879,6 @@ ExprMeshFieldReductionNanCount::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshFieldReductionNanCount::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshFieldReductionNanCount::execute() @@ -4305,15 +3923,6 @@ ExprMeshFieldReductionInfCount::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshFieldReductionInfCount::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshFieldReductionInfCount::execute() @@ -4372,15 +3981,6 @@ ExprMeshBinning::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshBinning::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshBinning::execute() @@ -4461,16 +4061,6 @@ ExprMeshBinningAxis::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshBinningAxis::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshBinningAxis::execute() @@ -4641,16 +4231,6 @@ ExprMeshBinningBinByIndex::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshBinningBinByIndex::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshBinningBinByIndex::execute() @@ -4735,16 +4315,6 @@ ExprMeshBinningPointAndAxis::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshBinningPointAndAxis::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshBinningPointAndAxis::execute() @@ -4872,16 +4442,6 @@ ExprMeshBinningMaxFromPoint::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprMeshBinningMaxFromPoint::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprMeshBinningMaxFromPoint::execute() diff --git a/src/libs/ascent/runtimes/expressions/ascent_expression_filters.hpp b/src/libs/ascent/runtimes/expressions/ascent_expression_filters.hpp index 861ffb7b6..e029a7839 100644 --- a/src/libs/ascent/runtimes/expressions/ascent_expression_filters.hpp +++ b/src/libs/ascent/runtimes/expressions/ascent_expression_filters.hpp @@ -77,7 +77,6 @@ class ExprBoolean : public ::flow::Filter ~ExprBoolean(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -89,7 +88,6 @@ class ExprInteger : public ::flow::Filter ~ExprInteger(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -101,7 +99,6 @@ class ExprDouble : public ::flow::Filter ~ExprDouble(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -113,7 +110,6 @@ class ExprString : public ::flow::Filter ~ExprString(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -125,7 +121,6 @@ class ExprNan : public ::flow::Filter ~ExprNan(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -137,7 +132,6 @@ class ExprNull : public ::flow::Filter ~ExprNull(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -149,7 +143,6 @@ class ExprIdentifier : public ::flow::Filter ~ExprIdentifier(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -161,7 +154,6 @@ class ExprObjectDotAccess : public ::flow::Filter ~ExprObjectDotAccess(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -173,7 +165,6 @@ class ExprIf : public ::flow::Filter ~ExprIf(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -185,7 +176,6 @@ class ExprBinaryOp : public ::flow::Filter ~ExprBinaryOp(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -206,7 +196,6 @@ class ExprScalarMin : public ::flow::Filter ~ExprScalarMin(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -218,7 +207,6 @@ class ExprScalarMax : public ::flow::Filter ~ExprScalarMax(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -230,7 +218,6 @@ class ExprScalarAbs : public ::flow::Filter ~ExprScalarAbs(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -242,7 +229,6 @@ class ExprScalarExp : public ::flow::Filter ~ExprScalarExp(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -254,7 +240,6 @@ class ExprScalarLog : public ::flow::Filter ~ExprScalarLog(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -266,7 +251,6 @@ class ExprScalarPow : public ::flow::Filter ~ExprScalarPow(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -287,7 +271,6 @@ class ExprVector : public ::flow::Filter ~ExprVector(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -299,7 +282,6 @@ class ExprVectorMagnitude : public ::flow::Filter ~ExprVectorMagnitude(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -320,7 +302,6 @@ class ExprArrayAccess : public ::flow::Filter ~ExprArrayAccess(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -332,7 +313,6 @@ class ExprArrayReplace : public ::flow::Filter ~ExprArrayReplace(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -344,7 +324,6 @@ class ExprArrayReductionMin : public ::flow::Filter ~ExprArrayReductionMin(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -356,7 +335,6 @@ class ExprArrayReductionMax : public ::flow::Filter ~ExprArrayReductionMax(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -368,7 +346,6 @@ class ExprArrayReductionAvg : public ::flow::Filter ~ExprArrayReductionAvg(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -380,7 +357,6 @@ class ExprArrayReductionSum : public ::flow::Filter ~ExprArrayReductionSum(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -401,7 +377,6 @@ class ExprHistory: public ::flow::Filter ~ExprHistory(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -413,7 +388,6 @@ class ExprHistoryRange : public ::flow::Filter ~ExprHistoryRange(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -425,7 +399,6 @@ class ExprHistoryGradient : public ::flow::Filter ~ExprHistoryGradient(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -437,7 +410,6 @@ class ExprHistoryGradientRange : public ::flow::Filter ~ExprHistoryGradientRange(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -458,7 +430,6 @@ class ExprHistogram : public ::flow::Filter ~ExprHistogram(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -470,7 +441,6 @@ class ExprHistogramEntropy : public ::flow::Filter ~ExprHistogramEntropy(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -482,7 +452,6 @@ class ExprHistogramPDF : public ::flow::Filter ~ExprHistogramPDF(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -494,7 +463,6 @@ class ExprHistogramCDF : public ::flow::Filter ~ExprHistogramCDF(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -506,7 +474,6 @@ class ExprHistogramCDFQuantile : public ::flow::Filter ~ExprHistogramCDFQuantile(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -519,7 +486,6 @@ class ExprHistogramBinByIndex : public ::flow::Filter ~ExprHistogramBinByIndex(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -531,7 +497,6 @@ class ExprHistogramBinByValue : public ::flow::Filter ~ExprHistogramBinByValue(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -552,7 +517,6 @@ class ExprMeshCycle : public ::flow::Filter ~ExprMeshCycle(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -564,7 +528,6 @@ class ExprMeshTime : public ::flow::Filter ~ExprMeshTime(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -576,7 +539,6 @@ class ExprMeshField : public ::flow::Filter ~ExprMeshField(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -588,7 +550,6 @@ class ExprMeshTopology : public ::flow::Filter ~ExprMeshTopology(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -600,7 +561,6 @@ class ExprMeshBounds : public ::flow::Filter ~ExprMeshBounds(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -612,7 +572,6 @@ class ExprMeshLineout : public ::flow::Filter ~ExprMeshLineout(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -633,7 +592,6 @@ class ExprMeshFieldReductionMin : public ::flow::Filter ~ExprMeshFieldReductionMin(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -645,7 +603,6 @@ class ExprMeshFieldReductionMax : public ::flow::Filter ~ExprMeshFieldReductionMax(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -657,7 +614,6 @@ class ExprMeshFieldReductionAvg : public ::flow::Filter ~ExprMeshFieldReductionAvg(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -669,7 +625,6 @@ class ExprMeshFieldReductionSum : public ::flow::Filter ~ExprMeshFieldReductionSum(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -681,7 +636,6 @@ class ExprMeshFieldReductionNanCount : public ::flow::Filter ~ExprMeshFieldReductionNanCount(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -693,7 +647,6 @@ class ExprMeshFieldReductionInfCount : public ::flow::Filter ~ExprMeshFieldReductionInfCount(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -715,7 +668,6 @@ class ExprMeshBinning : public ::flow::Filter ~ExprMeshBinning(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -727,7 +679,6 @@ class ExprMeshBinningAxis : public ::flow::Filter ~ExprMeshBinningAxis(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -739,7 +690,6 @@ class ExprMeshBinningBinByIndex: public ::flow::Filter ~ExprMeshBinningBinByIndex(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -751,7 +701,6 @@ class ExprMeshBinningPointAndAxis : public ::flow::Filter ~ExprMeshBinningPointAndAxis(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); }; @@ -763,7 +712,6 @@ class ExprMeshBinningMaxFromPoint : public ::flow::Filter ~ExprMeshBinningMaxFromPoint(); 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/ascent/runtimes/expressions/ascent_expression_jit_filters.cpp b/src/libs/ascent/runtimes/expressions/ascent_expression_jit_filters.cpp index b435f7321..a0b93cf60 100644 --- a/src/libs/ascent/runtimes/expressions/ascent_expression_jit_filters.cpp +++ b/src/libs/ascent/runtimes/expressions/ascent_expression_jit_filters.cpp @@ -140,31 +140,25 @@ ExprJitFilter::declare_interface(Node &i) i["port_names"].append() = ss.str(); } i["output_port"] = "true"; -} -//----------------------------------------------------------------------------- -bool -ExprJitFilter::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - info.reset(); - bool res = filters::check_string("func", params, info, true); - res &= filters::check_string("filter_name", params, info, true); - if(!params.has_path("inputs")) - { - info["errors"].append() = "Missing required parameter 'inputs'"; - res = false; - } - else if(params["inputs"].number_of_children() != num_inputs) - { - stringstream ss; - ss << "Expected parameter 'inputs' to have " << num_inputs - << " inputs but it has " << params["inputs"].number_of_children() - << " inputs."; - info["errors"].append() = ss.str(); - res = false; - } - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = true; + + param_schema["properties/func"].set(filters::string_schema()); + param_schema["properties/filter_name"].set(filters::string_schema()); + + conduit::Node inputs_schema = filters::array_schema(filters::ignore_schema()); + inputs_schema["minItems"] = num_inputs; + inputs_schema["miaxItems"] = num_inputs; + param_schema["properties/inputs"].set(inputs_schema); + + param_schema["required"].append() = "func"; + param_schema["required"].append() = "filter_name"; + param_schema["required"].append() = "inputs"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -784,15 +778,6 @@ ExprExpressionList::declare_interface(Node &i) i["output_port"] = "true"; } -//----------------------------------------------------------------------------- -bool -ExprExpressionList::verify_params(const conduit::Node ¶ms, conduit::Node &info) -{ - info.reset(); - bool res = true; - return res; -} - //----------------------------------------------------------------------------- void ExprExpressionList::execute() diff --git a/src/libs/ascent/runtimes/expressions/ascent_expression_jit_filters.hpp b/src/libs/ascent/runtimes/expressions/ascent_expression_jit_filters.hpp index 4b9c9a38f..cc8b80850 100644 --- a/src/libs/ascent/runtimes/expressions/ascent_expression_jit_filters.hpp +++ b/src/libs/ascent/runtimes/expressions/ascent_expression_jit_filters.hpp @@ -39,7 +39,6 @@ class ExprJitFilter : public ::flow::Filter ~ExprJitFilter(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); private: @@ -58,7 +57,6 @@ class ExprExpressionList : public ::flow::Filter ~ExprExpressionList(); virtual void declare_interface(conduit::Node &i); - virtual bool verify_params(const conduit::Node ¶ms, conduit::Node &info); virtual void execute(); protected: 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..bec88d983 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 @@ -17,6 +17,7 @@ #include "expressions/ascent_expressions_tokens.hpp" #include "expressions/ascent_expressions_parser.hpp" #include +#include #include @@ -43,7 +44,7 @@ namespace filters //----------------------------------------------------------------------------- // this detects if the syntax is valid, not // whether the expression will actually work -bool is_valid_expression(const std::string expr, std::string &err_msg) +bool is_valid_expression(const std::string &expr, std::string &err_msg) { bool res = true; try @@ -58,6 +59,124 @@ bool is_valid_expression(const std::string expr, std::string &err_msg) return res; } +void ascent_register_flow_schema_hooks() +{ + flow::schema::set_expression_checker(&is_valid_expression); +} + +conduit::Node string_schema() +{ + conduit::Node n; + n["type"] = "string"; + return n; +} + +conduit::Node expression_schema() +{ + conduit::Node n = string_schema(); + n["format"] = "expression"; + return n; +} + +conduit::Node number_schema(bool supports_expressions) +{ + conduit::Node n; + if (supports_expressions) + { + n["oneOf"].append().set(number_schema()); + n["oneOf"].append().set(expression_schema()); + } + else + { + n["type"] = "number"; + } + return n; +} + +conduit::Node vec3_schema(const std::string var1, + const std::string var2, + const std::string var3, + bool supports_expressions) +{ + conduit::Node n; + n["type"] = "object"; + n["additionalProperties"] = false; + + n["properties/" + var1].set(number_schema(supports_expressions)); + n["properties/" + var2].set(number_schema(supports_expressions)); + n["properties/" + var3].set(number_schema(supports_expressions)); + + n["required"].append() = var1; + n["required"].append() = var2; + n["required"].append() = var3; + + return n; +} + +conduit::Node vec3_schema(bool supports_expressions) +{ + return vec3_schema("x", "y", "z", supports_expressions); +} + +conduit::Node vec3_schema_anyOf(const std::string var1, + const std::string var2, + const std::string var3, + bool supports_expressions) +{ + conduit::Node n; + n["type"] = "object"; + n["additionalProperties"] = false; + + n["properties/" + var1].set(number_schema(supports_expressions)); + n["properties/" + var2].set(number_schema(supports_expressions)); + n["properties/" + var3].set(number_schema(supports_expressions)); + + 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(bool supports_expressions) +{ + return vec3_schema_anyOf("x", "y", "z", supports_expressions); +} + +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 c2874fe43..f5ff163ce 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,32 @@ namespace runtime namespace filters { +bool ASCENT_API is_valid_expression(const std::string &expr, std::string &err_msg); + +conduit::Node ASCENT_API string_schema(); + +conduit::Node ASCENT_API number_schema(bool supports_expressions = false); + +conduit::Node ASCENT_API vec3_schema(bool supports_expressions = false); + +conduit::Node ASCENT_API vec3_schema(const std::string var1, + const std::string var2, + const std::string var3, + bool supports_expressions = false); + +conduit::Node ASCENT_API vec3_schema_anyOf(bool supports_expressions = false); + +conduit::Node ASCENT_API vec3_schema_anyOf(const std::string var1, + const std::string var2, + const std::string var3, + bool supports_expressions = false); + +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, @@ -77,6 +103,7 @@ void ASCENT_API path_helper(std::vector &paths, std::string ASCENT_API surprise_check(const std::vector &valid_paths, 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 8079edfc9..99fa9387a 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); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(!has_values && !has_levels) - { - info["errors"].append() = "Missing required numeric parameter. Contour must" - " specify 'iso_values' or 'levels'."; - res = false; - } + 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()); - 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); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - 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; + // ----------- 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"); - std::string surprises = surprise_check(valid_paths, params); + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - 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(true)); + param_schema["properties/y_offset"].set(number_schema(true)); + param_schema["properties/z_offset"].set(number_schema(true)); + + 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); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; + param_schema["properties/topology"].set(string_schema()); + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -708,32 +626,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); } //----------------------------------------------------------------------------- @@ -806,138 +708,102 @@ VTKHSlice::declare_interface(Node &i) i["type_name"] = "vtkh_slice"; i["port_names"].append() = "in"; i["output_port"] = "true"; -} - -//----------------------------------------------------------------------------- -bool -VTKHSlice::verify_params(const conduit::Node ¶ms, - conduit::Node &info) -{ - 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::string surprises = surprise_check(valid_paths, params); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return 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() = "point"; + param_schema["constraints/allowNoneInExclusiveGroup"] = false; + + // optional + param_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(true)); + sphere_schema["properties/radius"].set(number_schema(true)); + sphere_schema["required"].append() = "center"; + sphere_schema["required"].append() = "radius"; + param_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(true)); + cylinder_schema["properties/axis"].set(vec3_schema(true)); + cylinder_schema["properties/radius"].set(number_schema(true)); + cylinder_schema["required"].append() = "center"; + cylinder_schema["required"].append() = "axis"; + cylinder_schema["required"].append() = "radius"; + param_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(true)); + box_schema["properties/max"].set(vec3_schema(true)); + box_schema["required"].append() = "min"; + box_schema["required"].append() = "max"; + param_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(true)); + plane_schema["properties/normal"].set(vec3_schema(true)); + plane_schema["required"].append() = "point"; + plane_schema["required"].append() = "normal"; + param_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(true)); + point_schema["properties/y"].set(number_schema(true)); + point_schema["properties/z"].set(number_schema(true)); + point_schema["properties/x_offset"].set(number_schema(true)); + point_schema["properties/y_offset"].set(number_schema(true)); + point_schema["properties/z_offset"].set(number_schema(true)); + + // 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); + + param_schema["properties/point"].set(point_schema); + param_schema["properties/normal"].set(vec3_schema(true)); + param_schema["constraints/dependencies/normal"].append() = "point"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1118,48 +984,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; + param_schema["properties/field"].set(string_schema()); + param_schema["properties/normal"].set(vec3_schema(true)); + param_schema["properties/levels"].set(number_schema(true)); - 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"); - - - 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); } //----------------------------------------------------------------------------- @@ -1319,33 +1158,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); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - res = check_numeric("min_value",params, info, true, true) && res; - res = check_numeric("max_value",params, info, true, true) && res; + param_schema["properties/field"].set(string_schema()); + param_schema["properties/min_value"].set(number_schema(true)); + param_schema["properties/max_value"].set(number_schema(true)); - 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); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - 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); } //----------------------------------------------------------------------------- @@ -1432,31 +1259,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(); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - 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; - } - - return res; + // optional + param_schema["properties/topology"].set(string_schema()); + param_schema["properties/output"].set(string_schema()); + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -1541,31 +1354,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); } //----------------------------------------------------------------------------- @@ -1645,177 +1444,89 @@ 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; - - res = check_string("invert",params, info, false) && res; - - 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"); - - 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); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return 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; + + // optional + param_schema["properties/field"].set(string_schema()); + param_schema["properties/topology"].set(string_schema()); + param_schema["properties/min_value"].set(number_schema(true)); + param_schema["properties/max_value"].set(number_schema(true)); + param_schema["properties/invert"].set(string_schema()); + param_schema["properties/extract"].set(string_schema()); + + // param_schema["oneOf"].append("field"); + // param_schema["oneOf"].append("topology") + + // --- sphere --- + conduit::Node sphere_schema; + sphere_schema["type"] = "object"; + sphere_schema["additionalProperties"] = false; + sphere_schema["properties/center"].set(vec3_schema(true)); + sphere_schema["properties/radius"].set(number_schema(true)); + sphere_schema["required"].append() = "center"; + sphere_schema["required"].append() = "radius"; + param_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(true)); + cylinder_schema["properties/axis"].set(vec3_schema(true)); + cylinder_schema["properties/radius"].set(number_schema(true)); + cylinder_schema["required"].append() = "center"; + cylinder_schema["required"].append() = "axis"; + cylinder_schema["required"].append() = "radius"; + param_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(true)); + box_schema["properties/max"].set(vec3_schema(true)); + box_schema["required"].append() = "min"; + box_schema["required"].append() = "max"; + param_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(true)); + plane_schema["properties/normal"].set(vec3_schema(true)); + 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(true)); + multi_plane_schema["properties/point2"].set(vec3_schema(true)); + multi_plane_schema["properties/normal1"].set(vec3_schema(true)); + multi_plane_schema["properties/normal2"].set(vec3_schema(true)); + 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() @@ -2007,160 +1718,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; - } - } - - res = check_string("invert",params, info, false) && res; - res = check_string("topology",params, info, false) && res; - - std::vector valid_paths; - valid_paths.push_back("topology"); - valid_paths.push_back("invert"); - 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); - - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return 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; + + // optional + param_schema["properties/topology"].set(string_schema()); + param_schema["properties/invert"].set(string_schema()); + + // --- sphere --- + conduit::Node sphere_schema; + sphere_schema["type"] = "object"; + sphere_schema["additionalProperties"] = false; + sphere_schema["properties/center"].set(vec3_schema(true)); + sphere_schema["properties/radius"].set(number_schema(true)); + sphere_schema["required"].append() = "center"; + sphere_schema["required"].append() = "radius"; + param_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(true)); + cylinder_schema["properties/axis"].set(vec3_schema(true)); + cylinder_schema["properties/radius"].set(number_schema(true)); + cylinder_schema["required"].append() = "center"; + cylinder_schema["required"].append() = "axis"; + cylinder_schema["required"].append() = "radius"; + param_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(true)); + box_schema["properties/max"].set(vec3_schema(true)); + box_schema["required"].append() = "min"; + box_schema["required"].append() = "max"; + param_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(true)); + plane_schema["properties/normal"].set(vec3_schema(true)); + 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(true)); + multi_plane_schema["properties/point2"].set(vec3_schema(true)); + multi_plane_schema["properties/normal1"].set(vec3_schema(true)); + multi_plane_schema["properties/normal2"].set(vec3_schema(true)); + 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() @@ -2313,34 +1945,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(true)); + 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() @@ -2425,35 +2045,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; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - 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); + param_schema["properties/min_value"].set(number_schema(true)); + param_schema["properties/max_value"].set(number_schema(true)); + param_schema["properties/field"].set(string_schema()); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - 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() @@ -2531,44 +2139,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"); - - 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; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + 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()); + + 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() @@ -2653,33 +2248,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); + // ----------- 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("clamp_min_value"); + param_schema["properties/field"].set(string_schema()); + param_schema["properties/output_name"].set(string_schema()); + param_schema["properties/clamp_min_value"].set(number_schema(true)); - 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); } //----------------------------------------------------------------------------- @@ -2763,33 +2344,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"); + // ----------- 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/output_name"].set(string_schema()); + param_schema["properties/clamp_min_value"].set(number_schema(true)); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -2873,33 +2440,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"); + // ----------- 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/output_name"].set(string_schema()); + param_schema["properties/clamp_min_value"].set(number_schema(true)); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -2983,31 +2536,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); } //----------------------------------------------------------------------------- @@ -3097,33 +2638,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); + // ----------- 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("bins"); - valid_paths.push_back("sample_rate"); + param_schema["properties/field"].set(string_schema()); + param_schema["properties/bins"].set(number_schema(true)); + param_schema["properties/sample_rate"].set(number_schema(true)); - std::string surprises = surprise_check(valid_paths, params); + param_schema["required"].append() = "field"; - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -3250,32 +2777,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); + // ----------- 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); } //----------------------------------------------------------------------------- @@ -3372,32 +2886,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); + // ----------- 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); } //----------------------------------------------------------------------------- @@ -3493,32 +2994,19 @@ 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); - - 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); } //----------------------------------------------------------------------------- @@ -3614,33 +3102,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); - - 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/output_name"].set(string_schema()); + param_schema["properties/use_cell_gradient"].set(string_schema()); + + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -3728,69 +3202,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/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); + // ----------- 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/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()); - return res; + param_schema["anyOf"].append() = "field"; + param_schema["anyOf"].append() = "fields"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -3959,104 +3387,41 @@ 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(); - - bool res = true; - res &= check_string("field",params, info, false); - res &= check_numeric("invalid_value",params, info, false); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = 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()); + + // --- Box --- + conduit::Node box_schema; + box_schema["type"] = "object"; + box_schema["additionalProperties"] = false; + box_schema["properties/dims"].set(vec3_schema_anyOf()); + box_schema["properties/min"].set(vec3_schema_anyOf()); + box_schema["properties/max"].set(vec3_schema_anyOf()); + param_schema["properties/box"].set(box_schema); + + 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); - - res &= check_numeric("box/dims/x",params, info, false); - res &= check_numeric("box/dims/y",params, info, false); - res &= check_numeric("box/dims/z",params, info, false); - res &= (check_numeric("box/min/x",params, info, false) - || check_string("box/min/x",params, info, false)); - res &= (check_numeric("box/min/y",params, info, false) - || check_string("box/min/y",params, info, false)); - res &= (check_numeric("box/min/z",params, info, false) - || check_string("box/min/z",params, info, false)); - res &= (check_numeric("box/max/x",params, info, false) - || check_string("box/max/x",params, info, false)); - res &= (check_numeric("box/max/y",params, info, false) - || check_string("box/max/y",params, info, false)); - res &= (check_numeric("box/max/z",params, info, false) - || check_string("box/max/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"); - - valid_paths.push_back("box/dims/i"); - valid_paths.push_back("box/dims/j"); - valid_paths.push_back("box/dims/k"); - 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"); - - 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); } //----------------------------------------------------------------------------- @@ -4369,29 +3734,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); } //----------------------------------------------------------------------------- @@ -4463,31 +3815,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"); + // ----------- 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(true)); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - return res; + param_schema["required"].append() = "field"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -4563,49 +3902,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; - } - - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + 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() @@ -4745,29 +4057,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); } //----------------------------------------------------------------------------- @@ -4843,33 +4142,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"); + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; - std::string surprises = surprise_check(valid_paths, params); - - 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); } //----------------------------------------------------------------------------- @@ -4949,35 +4236,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); } //----------------------------------------------------------------------------- @@ -5087,33 +4361,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", true); } //----------------------------------------------------------------------------- @@ -5187,168 +4437,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 -*/ - bool res = true; + // ----------- 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; + + param_schema["properties/scale"].set(vec3_schema_anyOf(true)); + param_schema["properties/translate"].set(vec3_schema_anyOf(true)); + param_schema["properties/reflect"].set(vec3_schema_anyOf(true)); + + // --- rotate --- + conduit::Node rotate_schema; + rotate_schema["type"] = "object"; + rotate_schema["additionalProperties"] = false; + rotate_schema["properties/angle"].set(number_schema(true)); + rotate_schema["properties/axis"].set(vec3_schema_anyOf(true)); + 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(true)); + 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); } //----------------------------------------------------------------------------- @@ -5563,126 +4684,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"); - 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; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + param_schema["properties/field"].set(string_schema()); + param_schema["properties/num_steps"].set(number_schema(true)); + param_schema["properties/step_size"].set(number_schema(true)); + + // --- seed --- + conduit::Node seeds_schema; + seeds_schema["type"] = "object"; + seeds_schema["additionalProperties"] = false; + seeds_schema["properties/type"].set(string_schema()); + seeds_schema["properties/location"].set(number_schema()); + seeds_schema["properties/start"].set(number_schema()); + seeds_schema["properties/end"].set(number_schema()); + seeds_schema["properties/num_seeds"].set(number_schema()); + seeds_schema["properties/num_seeds_x"].set(number_schema()); + seeds_schema["properties/num_seeds_y"].set(number_schema()); + seeds_schema["properties/num_seeds_z"].set(number_schema()); + seeds_schema["properties/extents_x"].set(number_schema()); + seeds_schema["properties/extents_y"].set(number_schema()); + seeds_schema["properties/extents_z"].set(number_schema()); + seeds_schema["properties/sampling_type"].set(string_schema()); + seeds_schema["properties/sampling_space"].set(string_schema()); + seeds_schema["required"].append() = "type"; + + seeds_schema["constraints/dependencies/extents_x"].append() = "extents_y"; + seeds_schema["constraints/dependencies/extents_x"].append() = "extents_z"; + seeds_schema["constraints/dependencies/extents_y"].append() = "extents_x"; + seeds_schema["constraints/dependencies/extents_y"].append() = "extents_z"; + seeds_schema["constraints/dependencies/extents_z"].append() = "extents_x"; + seeds_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"; + seeds_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"; + seeds_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"; + seeds_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); + } + seeds_schema["oneOf"].append().set(box_option); + + param_schema["properties/seeds"].set(seeds_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() = "field"; + param_schema["required"].append() = "num_steps"; + param_schema["required"].append() = "step_size"; + param_schema["required"].append() = "seeds"; + + i["param_schema"].set(param_schema); } //----------------------------------------------------------------------------- @@ -6216,55 +5332,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; - } - - return res; + // ----------- Define Param Schema ----------- + conduit::Node param_schema; + param_schema["type"] = "object"; + param_schema["additionalProperties"] = false; + + param_schema["properties/b_field"].set(string_schema()); + param_schema["properties/e_field"].set(string_schema()); + param_schema["properties/num_steps"].set(number_schema(true)); + param_schema["properties/step_size"].set(number_schema(true)); + + // --- 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() @@ -6426,38 +5522,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); } //----------------------------------------------------------------------------- @@ -6638,39 +5714,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"); + // ----------- 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/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()); - if(surprises != "") - { - res = false; - info["errors"].append() = surprises; - } - - 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 b52f95815..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(); }; @@ -90,8 +84,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(); }; @@ -103,8 +95,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(); }; //----------------------------------------------------------------------------- @@ -115,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(); }; @@ -128,8 +116,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(); }; @@ -141,8 +127,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(); }; @@ -154,8 +138,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(); }; @@ -168,8 +150,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(); }; @@ -183,8 +163,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(); }; @@ -196,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(); }; @@ -209,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(); }; @@ -222,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(); }; @@ -235,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(); }; @@ -248,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(); }; @@ -261,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(); }; @@ -274,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(); }; @@ -287,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(); }; @@ -300,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(); }; @@ -313,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(); }; @@ -326,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(); }; @@ -339,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(); }; @@ -352,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(); }; @@ -365,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(); }; @@ -378,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(); }; @@ -391,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(); }; @@ -404,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(); }; @@ -417,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(); }; @@ -430,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(); }; @@ -444,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(); }; @@ -458,8 +396,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(); }; @@ -471,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(); }; @@ -484,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(); }; @@ -497,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(); }; @@ -510,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: @@ -535,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: @@ -551,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(); }; @@ -566,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/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 4bce67aa1..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; @@ -111,6 +112,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 +142,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 +221,22 @@ Filter::params() //----------------------------------------------------------------------------- bool -Filter::verify_params(const Node &, // unused: params, +Filter::verify_params(const Node ¶ms, Node &info) { info.reset(); + + 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::cout << "\nParams!!" << std::endl; + // params.print(); + + return flow::schema::validate(param_schema(), params, info); + } + 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; diff --git a/src/libs/flow/flow_schema_validator.cpp b/src/libs/flow/flow_schema_validator.cpp new file mode 100644 index 000000000..e4e8befa0 --- /dev/null +++ b/src/libs/flow/flow_schema_validator.cpp @@ -0,0 +1,629 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// 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 +{ + +//----------------------------------------------------------------------------- +// -- begin flow::schema::detail -- +//----------------------------------------------------------------------------- +namespace detail +{ + +// ---------- General Helpers ---------- +ExpressionCheckFn &expr_checker() +{ + static ExpressionCheckFn fn = nullptr; + return fn; +} + +void add_error(conduit::Node &info, const std::string &msg) +{ + if(!info.has_child("errors")) + { + info["errors"].reset(); + } + info["errors"].append() = msg; +} + +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 ""; +} + +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 if(schema_defined_type == "array") ok = (data_type.is_list() || (data_type.is_number() && data_type.number_of_elements() >= 1) || data_type.is_object()); + 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 ---------- + +// Earlier declaration so validate node can be refrenced by helpers. +bool validate_node(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path); + +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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +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) + { + conduit::Node tmp; + tmp.reset(); + + bool ok = validate_node(opts.child(i), input, tmp, path); + + 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; +} + +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) + { + conduit::Node tmp; + tmp.reset(); + + bool ok = validate_node(opts.child(i), input, tmp, path); + + 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; +} + +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_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; + + // 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; + ok = validate_any_of(schema, input, info, path) && ok; + + return ok; +} + +bool validate_format(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info, + const std::string &path) +{ + if(!schema.has_child("format")) return true; + if(!schema["format"].dtype().is_string()) return true; + + const std::string fmt = schema["format"].as_string(); + if(fmt != "expression") return true; + if(!input.dtype().is_string()) return true; + + auto expr_fn = expr_checker(); + if(expr_fn == nullptr) return true; + + std::string err; + bool ok = expr_fn(input.as_string(), err); + if(!ok) + { + add_error(info, "Invalid expression at '" + (path.empty() ? std::string("") : path) + "': " + err); + } + return ok; +} + +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() || data_type.is_object()) ? 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; +} + +bool validate_node(const conduit::Node &schema, + const conduit::Node &input, + 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 + + 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; + ok = validate_format(schema, input, info, path) && ok; + + return ok; +} + +}; +//----------------------------------------------------------------------------- +// -- end flow::schema::detail -- +//----------------------------------------------------------------------------- + +void set_expression_checker(ExpressionCheckFn fn) +{ + detail::expr_checker() = fn; +} + +// ---------- Schema Validation Entry-Point ---------- +bool validate(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info) +{ + info.reset(); + bool ok = detail::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 -- +//----------------------------------------------------------------------------- diff --git a/src/libs/flow/flow_schema_validator.hpp b/src/libs/flow/flow_schema_validator.hpp new file mode 100644 index 000000000..26587ff81 --- /dev/null +++ b/src/libs/flow/flow_schema_validator.hpp @@ -0,0 +1,57 @@ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// +// 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 +{ + +using ExpressionCheckFn = bool (*)(const std::string &expr, std::string &err_msg); + +void FLOW_API set_expression_checker(ExpressionCheckFn fn); + +bool FLOW_API validate(const conduit::Node &schema, + const conduit::Node &input, + conduit::Node &info); + +}; +//----------------------------------------------------------------------------- +// -- end flow::schema -- +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +}; +//----------------------------------------------------------------------------- +// -- end flow -- +//----------------------------------------------------------------------------- + +#endif +//----------------------------------------------------------------------------- +// -- end header ifdef guard +//-----------------------------------------------------------------------------