Skip to content

Commit

Permalink
NOAA-OWP#554: initial external model_params parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
program-- committed Jul 26, 2023
1 parent c4165cd commit 788318f
Showing 1 changed file with 70 additions and 7 deletions.
77 changes: 70 additions & 7 deletions include/realizations/catchment/Formulation_Manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <FeatureBuilder.hpp>
#include "JSONProperty.hpp"
#include "features/Features.hpp"
#include <FeatureCollection.hpp>
#include "Formulation_Constructors.hpp"
Expand Down Expand Up @@ -158,20 +159,29 @@ namespace realization {

if (possible_catchment_configs) {
for (std::pair<std::string, boost::property_tree::ptree> catchment_config : *possible_catchment_configs) {
if( fabric->find(catchment_config.first) == -1 )
int catchment_index = fabric->find(catchment_config.first);
if( catchment_index == -1 )
{
#ifndef NGEN_QUIET
std::cerr<<"WARNING Formulation_Manager::read: Cannot create formulation for catchment "
<<catchment_config.first
<<" that isn't identified in the hydrofabric or requested subset"<<std::endl;
#endif
continue;
#ifndef NGEN_QUIET
std::cerr<<"WARNING Formulation_Manager::read: Cannot create formulation for catchment "
<<catchment_config.first
<<" that isn't identified in the hydrofabric or requested subset"<<std::endl;
#endif
continue;
}

auto catchment_feature = fabric->get_feature(catchment_index);
auto formulations = catchment_config.second.get_child_optional("formulations");
if( !formulations ) {
throw std::runtime_error("ERROR: No formulations defined for "+catchment_config.first+".");
}

// Parse catchment-specific model_params
auto model_params = formulations->get_child_optional("params.model_params");
if (model_params) {
parse_external_model_params(*model_params, catchment_feature);
}

for (const auto &formulation: *formulations) {
this->add_formulation(
this->construct_formulation_from_tree(
Expand Down Expand Up @@ -461,6 +471,59 @@ namespace realization {
throw std::runtime_error("Forcing data could not be found for '" + identifier + "'");
}

/**
* @brief Parse a `model_params` property tree and replace external parameters
* with values from a catchment's properties
*
* @param model_params Property tree with root key "model_params"
* @param catchment_feature Associated catchment feature
*/
void parse_external_model_params(boost::property_tree::ptree& model_params, const geojson::Feature catchment_feature) {
for (auto& param : model_params) {
auto param_source = param.second.get_child_optional("source");
if (!param_source) {
continue;
}

auto param_source_name = param_source->get_value<std::string>();
if (param_source_name != "hydrofabric") {
// temporary until the logic for alternative sources is designed
throw std::logic_error("ERROR: 'model_params' source `" + param_source_name + "` not currently supported. Only `hydrofabric` is supported.");
}

auto param_name = param.second.get_child_optional("from")
? param.second.get_child("from").get_value<std::string>()
: param.first;

model_params.erase(param.first);

if (catchment_feature->has_property(param_name)) {
auto catchment_attribute = catchment_feature->get_property(param_name);
switch (catchment_attribute.get_type()) {
case geojson::PropertyType::Natural:
model_params.put(param_name, catchment_attribute.as_natural_number());
break;
case geojson::PropertyType::Boolean:
model_params.put(param_name, catchment_attribute.as_boolean());
break;
case geojson::PropertyType::Real:
model_params.put(param_name, catchment_attribute.as_real_number());
break;
case geojson::PropertyType::String:
model_params.put(param_name, catchment_attribute.as_string());
break;

case geojson::PropertyType::List:
case geojson::PropertyType::Object:
default:
std::cerr << "WARNING: property type " << static_cast<int>(catchment_attribute.get_type()) << " not allowed as model parameter. "
<< "Must be one of: Natural (int), Real (double), Boolean, or String" << std::endl;
break;
}
}
}
}

boost::property_tree::ptree tree;

boost::property_tree::ptree global_formulation_tree;
Expand Down

0 comments on commit 788318f

Please sign in to comment.