NGen
Loading...
Searching...
No Matches
formulation.hpp
1#ifndef NGEN_REALIZATION_CONFIG_FORMULATION_H
2#define NGEN_REALIZATION_CONFIG_FORMULATION_H
3
4#include <NGenConfig.h>
5#include <boost/property_tree/ptree.hpp>
6#include <string>
7
8#include "JSONProperty.hpp"
9
10namespace realization{
11 namespace config{
12
14 std::string type;
15 //Formulation parameters, object as a PropertyMap
17 //List of nested formulations (used for multi bmi representations)
18 std::vector<Formulation> nested;
19
25 Formulation() = default;
26
33 Formulation(std::string type, geojson::PropertyMap params):type(std::move(type)), parameters(params){}
34
43 Formulation(const boost::property_tree::ptree& tree){
44 type = tree.get<std::string>("name");
45 for (std::pair<std::string, boost::property_tree::ptree> setting : tree.get_child("params")) {
46 //Construct the geoJSON PropertyMap from each key, value pair in "params"
47 parameters.emplace(
48 setting.first,
49 geojson::JSONProperty(setting.first, setting.second)
50 );
51 }
52 if(type=="bmi_multi"){
53 for(auto& module : tree.get_child("params.modules")){
54 //Create the nested formulations in order of definition
55 nested.push_back(Formulation(module.second));
56 }
57 }
58 }
59
67
68 if(type == "bmi_multi"){
69 std::vector<geojson::JSONProperty> tmp;
70 for(auto& n : nested){
71 //Iterate and link any nested modules with this feature
72 if(n.parameters.count("model_params")){
73 n.link_external(feature);
74 }
75 //Need a temporary map to hold the updated formulation properties in
76 geojson::PropertyMap map = {};
77 map.emplace("name", geojson::JSONProperty("name", n.type));
78 map.emplace("params", geojson::JSONProperty("", n.parameters));
79 tmp.push_back(geojson::JSONProperty("", map));
80 }
81 //Reset the bmi_multi modules with the now linked module definitions
82 parameters.at("modules") = geojson::JSONProperty("modules", tmp);
83 return;
84 }
85 //Short circut
86 if(parameters.count("model_params") < 1 ) return;
87 //Have some model params, check to see if any should be linked to the hyrdofabric feature
88 geojson::PropertyMap attr = parameters.at("model_params").get_values();
89 for (decltype(auto) param : attr) {
90 // Check for type to short-circuit. If param.second is not an object, `.has_key()` will throw
91 if (param.second.get_type() != geojson::PropertyType::Object || !param.second.has_key("source")) {
92 attr.emplace(param.first, param.second);
93 continue;
94 }
95
96 decltype(auto) param_source = param.second.at("source");
97 decltype(auto) param_source_name = param_source.as_string();
98 if (param_source_name != "hydrofabric") {
99 // TODO: temporary until the logic for alternative sources is designed
100 throw std::logic_error("ERROR: 'model_params' source `" + param_source_name + "` not currently supported. Only `hydrofabric` is supported.");
101 }
102
103 // Property name in the feature properties is either
104 // the value of key "from", or has the same name as
105 // the expected model parameter key
106 decltype(auto) param_name = param.second.has_key("from")
107 ? param.second.at("from").as_string()
108 : param.first;
109
110 if (feature->has_property(param_name)) {
111 auto catchment_attribute = feature->get_property(param_name);
112
113 // Use param.first in the `.emplace` calls instead of param_name since
114 // the expected name is given by the key of the model_params values.
115 switch (catchment_attribute.get_type()) {
118 // TODO: Should list/object values be passed to model parameters?
119 // Typically, feature properties *should* be scalars.
120 std::cerr << "WARNING: property type " << static_cast<int>(catchment_attribute.get_type()) << " not allowed as model parameter. "
121 << "Must be one of: Natural (int), Real (double), Boolean, or String" << '\n';
122 break;
123 default:
124 attr.at(param.first) = geojson::JSONProperty(param.first, catchment_attribute);
125 }
126 }
127 }
128 parameters.at("model_params") = geojson::JSONProperty("model_params", attr);
129 }
130 };
131
132 }//end namespace config
133}//end namespace realization
134#endif //NGEN_REALIZATION_CONFIG_FORMULATION_H
@TODO: Convert JSONProperty into a variant of the supported types
Definition JSONProperty.hpp:165
std::map< std::string, JSONProperty > PropertyMap
Shorthand for a mapping between strings and properties.
Definition JSONProperty.hpp:21
std::shared_ptr< FeatureBase > Feature
An easy name for a smart pointer for FeatureBase and its children.
Definition FeatureBase.hpp:34
Definition HY_Features.hpp:12
STL namespace.
Definition formulation.hpp:13
geojson::PropertyMap parameters
Definition formulation.hpp:16
std::string type
Definition formulation.hpp:14
Formulation()=default
Construct a new default Formulation object.
Formulation(std::string type, geojson::PropertyMap params)
Construct a new Formulation object.
Definition formulation.hpp:33
Formulation(const boost::property_tree::ptree &tree)
Construct a new Formulation object from a boost property tree.
Definition formulation.hpp:43
std::vector< Formulation > nested
Definition formulation.hpp:18
void link_external(geojson::Feature feature)
Link formulation parameters to hydrofabric data held in feature.
Definition formulation.hpp:66