Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add min parameter #39

Merged
merged 10 commits into from
Sep 18, 2023
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ highs-sys = { git = "https://github.com/jetuk/highs-sys", branch="fix-build-lib
# highs-sys = { path = "../../highs-sys" }
pyo3 = { version = "0.19.0" }
rayon = "1.6.1"
polars = { version = "0.30.0", features = ["lazy", "rows", "ndarray"] }
pyo3-polars = "0.4.0"
polars = { version = "0.32.0", features = ["lazy", "rows", "ndarray"] }
pyo3-polars = "0.6.0"
pywr-schema = { git = "https://github.com/pywr/pywr-schema/", tag="v0.6.0" }
rhai = { version="1.12.0", features=["sync"] }

Expand Down
45 changes: 45 additions & 0 deletions src/parameters/min.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::metric::Metric;
use crate::model::Model;
use crate::parameters::{Parameter, ParameterMeta};
use crate::scenario::ScenarioIndex;
use std::any::Any;

use crate::state::State;
use crate::timestep::Timestep;
use crate::PywrError;

pub struct MinParameter {
meta: ParameterMeta,
metric: Metric,
threshold: f64,
}

impl MinParameter {
pub fn new(name: &str, metric: Metric, threshold: f64) -> Self {
Self {
meta: ParameterMeta::new(name),
metric,
threshold,
}
}
}

impl Parameter for MinParameter {
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn meta(&self) -> &ParameterMeta {
&self.meta
}
fn compute(
&self,
_timestep: &Timestep,
_scenario_index: &ScenarioIndex,
model: &Model,
state: &State,
_internal_state: &mut Option<Box<dyn Any + Send>>,
) -> Result<f64, PywrError> {
let x = self.metric.get_value(model, state)?;
Ok(x.min(self.threshold))
}
}
2 changes: 2 additions & 0 deletions src/parameters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod control_curves;
mod delay;
mod indexed_array;
mod max;
mod min;
mod negative;
mod polynomial;
mod profiles;
Expand Down Expand Up @@ -33,6 +34,7 @@ pub use control_curves::{
pub use delay::DelayParameter;
pub use indexed_array::IndexedArrayParameter;
pub use max::MaxParameter;
pub use min::MinParameter;
pub use negative::NegativeParameter;
pub use polynomial::Polynomial1DParameter;
pub use profiles::{DailyProfileParameter, MonthlyInterpDay, MonthlyProfileParameter, UniformDrawdownProfileParameter};
Expand Down
27 changes: 27 additions & 0 deletions src/schema/parameters/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,33 @@ impl MaxParameter {
}
}

#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
pub struct MinParameter {
#[serde(flatten)]
pub meta: ParameterMeta,
pub parameter: DynamicFloatValue,
pub threshold: Option<f64>,
}

impl MinParameter {
pub fn node_references(&self) -> HashMap<&str, &str> {
HashMap::new()
}

pub fn add_to_model(
&self,
model: &mut crate::model::Model,
tables: &LoadedTableCollection,
data_path: Option<&Path>,
) -> Result<ParameterIndex, PywrError> {
let idx = self.parameter.load(model, tables, data_path)?;
let threshold = self.threshold.unwrap_or(0.0);

let p = crate::parameters::MinParameter::new(&self.meta.name, idx, threshold);
model.add_parameter(Box::new(p))
}
}

impl TryFromV1Parameter<MaxParameterV1> for MaxParameter {
type Error = ConversionError;

Expand Down
4 changes: 2 additions & 2 deletions src/schema/parameters/data_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::schema::parameters::{DynamicFloatValueType, ParameterMeta};
use crate::{ParameterIndex, PywrError};
use ndarray::Array2;
use polars::prelude::DataType::Float64;
use polars::prelude::{DataFrame, Float64Type};
use polars::prelude::{DataFrame, Float64Type, IndexOrder};
use pyo3::prelude::PyModule;
use pyo3::types::{PyDict, PyTuple};
use pyo3::{IntoPy, PyErr, PyObject, Python, ToPyObject};
Expand Down Expand Up @@ -124,7 +124,7 @@ impl DataFrameParameter {
match &self.columns {
DataFrameColumns::Scenario(scenario) => {
let scenario_group = model.get_scenario_group_index_by_name(scenario)?;
let array: Array2<f64> = df.to_ndarray::<Float64Type>().unwrap();
let array: Array2<f64> = df.to_ndarray::<Float64Type>(IndexOrder::default()).unwrap();
let p = Array2Parameter::new(&self.meta.name, array, scenario_group);
model.add_parameter(Box::new(p))
}
Expand Down
7 changes: 6 additions & 1 deletion src/schema/parameters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub use super::parameters::control_curves::{
ControlCurveIndexParameter, ControlCurveInterpolatedParameter, ControlCurveParameter,
ControlCurvePiecewiseInterpolatedParameter,
};
pub use super::parameters::core::{ConstantParameter, MaxParameter, NegativeParameter};
pub use super::parameters::core::{ConstantParameter, MaxParameter, MinParameter, NegativeParameter};
pub use super::parameters::delay::DelayParameter;
pub use super::parameters::indexed_array::IndexedArrayParameter;
pub use super::parameters::polynomial::Polynomial1DParameter;
Expand Down Expand Up @@ -135,6 +135,7 @@ pub enum Parameter {
MonthlyProfile(MonthlyProfileParameter),
UniformDrawdownProfile(UniformDrawdownProfileParameter),
Max(MaxParameter),
Min(MinParameter),
Negative(NegativeParameter),
Polynomial1D(Polynomial1DParameter),
ParameterThreshold(ParameterThresholdParameter),
Expand All @@ -160,6 +161,7 @@ impl Parameter {
Self::MonthlyProfile(p) => p.meta.name.as_str(),
Self::UniformDrawdownProfile(p) => p.meta.name.as_str(),
Self::Max(p) => p.meta.name.as_str(),
Self::Min(p) => p.meta.name.as_str(),
Self::Negative(p) => p.meta.name.as_str(),
Self::Polynomial1D(p) => p.meta.name.as_str(),
Self::ParameterThreshold(p) => p.meta.name.as_str(),
Expand Down Expand Up @@ -187,6 +189,7 @@ impl Parameter {
Self::MonthlyProfile(p) => p.node_references(),
Self::UniformDrawdownProfile(p) => p.node_references(),
Self::Max(p) => p.node_references(),
Self::Min(p) => p.node_references(),
Self::Negative(p) => p.node_references(),
Self::Polynomial1D(p) => p.node_references(),
Self::ParameterThreshold(p) => p.node_references(),
Expand Down Expand Up @@ -231,6 +234,7 @@ impl Parameter {
Self::MonthlyProfile(_) => "MonthlyProfile",
Self::UniformDrawdownProfile(_) => "UniformDrawdownProfile",
Self::Max(_) => "Max",
Self::Min(_) => "Min",
Self::Negative(_) => "Negative",
Self::Polynomial1D(_) => "Polynomial1D",
Self::ParameterThreshold(_) => "ParameterThreshold",
Expand Down Expand Up @@ -263,6 +267,7 @@ impl Parameter {
Self::MonthlyProfile(p) => ParameterType::Parameter(p.add_to_model(model, tables)?),
Self::UniformDrawdownProfile(p) => ParameterType::Parameter(p.add_to_model(model, tables)?),
Self::Max(p) => ParameterType::Parameter(p.add_to_model(model, tables, data_path)?),
Self::Min(p) => ParameterType::Parameter(p.add_to_model(model, tables, data_path)?),
Self::Negative(p) => ParameterType::Parameter(p.add_to_model(model, tables, data_path)?),
Self::Polynomial1D(p) => ParameterType::Parameter(p.add_to_model(model)?),
Self::ParameterThreshold(p) => ParameterType::Index(p.add_to_model(model, tables, data_path)?),
Expand Down