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

feat: add timeseries section to model schema #99

Merged
merged 19 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
32b5e5e
WIP: feat: add timeseries section to model schema
Batch21 Feb 7, 2024
2b308ec
add a align_and_resample timeseries mod
Batch21 Feb 10, 2024
e5c6822
Merge branch 'main' into schema-timeseries
Batch21 Feb 29, 2024
1b5c5b1
fix: check if param exists before creating param from timeseries input
Batch21 Mar 3, 2024
72fe90e
create seperate timeseries error enum
Batch21 Mar 3, 2024
5320983
wip: conversion of v1 dataframe parameters to timeseries inputs
Batch21 Mar 7, 2024
1300e77
update timeseries url in test model + remove dbg statement
Batch21 Mar 7, 2024
6b29780
feat: Implement Parameter<usize> for PyParameter.
jetuk Mar 11, 2024
da16f71
Merge branch 'main' into schema-timeseries
Batch21 Mar 11, 2024
d7d011c
Merge branch 'py-index-param' into schema-timeseries
Batch21 Mar 11, 2024
483b17e
fix: Fix and upgrade highs_sys to v1.6.2
jetuk Mar 12, 2024
413a6be
Merge branch 'main' into schema-timeseries
Batch21 Mar 12, 2024
e9805f4
Merge remote-tracking branch 'origin/fix-highs' into schema-timeseries
Batch21 Mar 12, 2024
4040da2
fix: conversion of inline dataframe parameter to timeseries
Batch21 Mar 21, 2024
bbe8187
Merge branch 'main' into schema-timeseries
Batch21 Mar 21, 2024
38f16d4
response to review comments
Batch21 Mar 23, 2024
a021b2b
fix: use index_col for time_col when converting v1 df param to timese…
Batch21 Mar 24, 2024
7de6996
Merge branch 'main' into schema-timeseries
Batch21 Mar 24, 2024
4150d54
remove dataframe parameter from schema and update test models
Batch21 Mar 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pywr-schema/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ categories = ["science", "simulation"]

[dependencies]
svgbobdoc = { version = "0.3.0", features = ["enable"] }
polars = { workspace = true }
polars = { workspace = true, features = ["csv"] }
pyo3 = { workspace = true }
pyo3-polars = { workspace = true }
strum = "0.26"
Expand Down
11 changes: 11 additions & 0 deletions pywr-schema/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::data_tables::TableError;
use crate::nodes::NodeAttribute;
use polars::error::PolarsError;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import

use pyo3::exceptions::PyRuntimeError;
use pyo3::PyErr;
use thiserror::Error;
Expand Down Expand Up @@ -28,6 +29,16 @@ pub enum SchemaError {
PywrCore(#[from] pywr_core::PywrError),
#[error("data table error: {0}")]
DataTable(#[from] TableError),
#[error("Timeseries '{0} not found")]
TimeseriesNotFound(String),
#[error("Column '{col}' not found in timeseries input '{name}'")]
ColumnNotFound { col: String, name: String },
#[error("Timeseries provider '{provider}' does not support '{fmt}' file types")]
TimeseriesUnsupportedFileFormat { provider: String, fmt: String },
#[error("Timeseries provider '{provider}' cannot parse file: '{path}'")]
TimeseriesUnparsableFileFormat { provider: String, path: String },
#[error("Polars error: {0}")]
PolarsError(#[from] PolarsError),
#[error("Circular node reference(s) found.")]
CircularNodeReference,
#[error("Circular parameters reference(s) found.")]
Expand Down
1 change: 1 addition & 0 deletions pywr-schema/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod model;
pub mod nodes;
pub mod outputs;
pub mod parameters;
pub mod timeseries;

pub use error::{ConversionError, SchemaError};
pub use model::PywrModel;
10 changes: 10 additions & 0 deletions pywr-schema/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::error::{ConversionError, SchemaError};
use crate::metric_sets::MetricSet;
use crate::outputs::Output;
use crate::parameters::{MetricFloatReference, TryIntoV2Parameter};
use crate::timeseries::{LoadedTimeseriesCollection, Timeseries};
use pywr_core::models::ModelDomain;
use pywr_core::PywrError;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -91,6 +92,7 @@ pub struct PywrNetwork {
pub edges: Vec<Edge>,
pub parameters: Option<Vec<Parameter>>,
pub tables: Option<Vec<DataTable>>,
pub timeseries: Option<Vec<Timeseries>>,
pub metric_sets: Option<Vec<MetricSet>>,
pub outputs: Option<Vec<Output>>,
}
Expand Down Expand Up @@ -139,6 +141,9 @@ impl PywrNetwork {
// Load all the data tables
let tables = LoadedTableCollection::from_schema(self.tables.as_deref(), data_path)?;

// Load all timeseries data
let timeseries = LoadedTimeseriesCollection::from_schema(self.timeseries.as_deref(), domain, data_path)?;

// Create all the nodes
let mut remaining_nodes = self.nodes.clone();

Expand All @@ -153,6 +158,7 @@ impl PywrNetwork {
&tables,
data_path,
inter_network_transfers,
&timeseries,
) {
// Adding the node failed!
match e {
Expand Down Expand Up @@ -211,6 +217,7 @@ impl PywrNetwork {
&tables,
data_path,
inter_network_transfers,
&timeseries,
) {
// Adding the parameter failed!
match e {
Expand Down Expand Up @@ -244,6 +251,7 @@ impl PywrNetwork {
&tables,
data_path,
inter_network_transfers,
&timeseries,
)?;
}

Expand Down Expand Up @@ -382,13 +390,15 @@ impl TryFrom<pywr_v1_schema::PywrModel> for PywrModel {

// TODO convert v1 tables!
let tables = None;
let timeseries = None;
let outputs = None;
let metric_sets = None;
let network = PywrNetwork {
nodes,
edges,
parameters,
tables,
timeseries,
metric_sets,
outputs,
};
Expand Down
32 changes: 29 additions & 3 deletions pywr-schema/src/nodes/annual_virtual_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::model::PywrMultiNetworkTransfer;
use crate::nodes::core::StorageInitialVolume;
use crate::nodes::{NodeAttribute, NodeMeta};
use crate::parameters::{DynamicFloatValue, TryIntoV2Parameter};
use crate::timeseries::LoadedTimeseriesCollection;
use pywr_core::derived_metric::DerivedMetric;
use pywr_core::metric::Metric;
use pywr_core::models::ModelDomain;
Expand Down Expand Up @@ -53,24 +54,49 @@ impl AnnualVirtualStorageNode {
tables: &LoadedTableCollection,
data_path: Option<&Path>,
inter_network_transfers: &[PywrMultiNetworkTransfer],
timeseries: &LoadedTimeseriesCollection,
) -> Result<(), SchemaError> {
let cost = match &self.cost {
Some(v) => v
.load(network, schema, domain, tables, data_path, inter_network_transfers)?
.load(
Batch21 marked this conversation as resolved.
Show resolved Hide resolved
network,
schema,
domain,
tables,
data_path,
inter_network_transfers,
timeseries,
)?
.into(),
None => ConstraintValue::Scalar(0.0),
};

let min_volume = match &self.min_volume {
Some(v) => v
.load(network, schema, domain, tables, data_path, inter_network_transfers)?
.load(
network,
schema,
domain,
tables,
data_path,
inter_network_transfers,
timeseries,
)?
.into(),
None => ConstraintValue::Scalar(0.0),
};

let max_volume = match &self.max_volume {
Some(v) => v
.load(network, schema, domain, tables, data_path, inter_network_transfers)?
.load(
network,
schema,
domain,
tables,
data_path,
inter_network_transfers,
timeseries,
)?
.into(),
None => ConstraintValue::None,
};
Expand Down
Loading
Loading