Skip to content

Commit

Permalink
Merge pull request #180 from EnergySystemsModellingLab/more_validation
Browse files Browse the repository at this point in the history
More validation
  • Loading branch information
dalonsoa authored Nov 8, 2024
2 parents 460597b + 4cf2628 commit 4e88827
Showing 1 changed file with 94 additions and 9 deletions.
103 changes: 94 additions & 9 deletions src/process.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::input::*;
use crate::region::*;
use crate::time_slice::{TimeSliceInfo, TimeSliceSelection};
use ::log::warn;
use serde::{Deserialize, Deserializer};
use serde_string_enum::{DeserializeLabeledStringEnum, SerializeLabeledStringEnum};
use std::collections::{HashMap, HashSet};
Expand Down Expand Up @@ -117,6 +118,8 @@ impl ProcessParameterRaw {
))?;
}

self.validate()?;

Ok(ProcessParameter {
process_id: self.process_id,
years: start_year..=end_year,
Expand All @@ -130,6 +133,57 @@ impl ProcessParameterRaw {
}
}

impl ProcessParameterRaw {
/// Validates the `ProcessParameterRaw` instance.
///
/// # Errors
///
/// Returns an error if:
/// - `lifetime` is 0.
/// - `discount_rate` is present and less than 0.0.
/// - `cap2act` is present and less than 0.0.
///
/// # Warnings
///
/// Logs a warning if:
/// - `discount_rate` is present and greater than 1.0.
///
/// # Returns
///
/// Returns `Ok(())` if all validations pass.
fn validate(&self) -> Result<(), Box<dyn Error>> {
if self.lifetime == 0 {
Err(format!(
"Error in parameter for process {}: Lifetime must be greater than 0",
self.process_id
))?;
}
if let Some(dr) = self.discount_rate {
if dr < 0.0 {
Err(format!(
"Error in parameter for process {}: Discount rate must be positive",
self.process_id
))?;
}
if dr > 1.0 {
warn!(
"Warning in parameter for process {}: Discount rate is greater than 1",
self.process_id
);
}
}
if let Some(c2a) = self.cap2act {
if c2a < 0.0 {
Err(format!(
"Error in parameter for process {}: Cap2act must be positive",
self.process_id
))?;
}
}
Ok(())
}
}

#[derive(PartialEq, Debug, Deserialize)]
pub struct ProcessParameter {
pub process_id: String,
Expand Down Expand Up @@ -325,6 +379,7 @@ mod tests {
fn create_param_raw(
start_year: Option<u32>,
end_year: Option<u32>,
lifetime: u32,
discount_rate: Option<f64>,
cap2act: Option<f64>,
) -> ProcessParameterRaw {
Expand All @@ -335,7 +390,7 @@ mod tests {
capital_cost: 0.0,
fixed_operating_cost: 0.0,
variable_operating_cost: 0.0,
lifetime: 1,
lifetime,
discount_rate,
cap2act,
}
Expand Down Expand Up @@ -363,28 +418,28 @@ mod tests {
let year_range = 2000..=2100;

// No missing values
let raw = create_param_raw(Some(2010), Some(2020), Some(1.0), Some(0.0));
let raw = create_param_raw(Some(2010), Some(2020), 1, Some(1.0), Some(0.0));
assert_eq!(
raw.into_parameter(&year_range).unwrap(),
create_param(2010..=2020, 1.0, 0.0)
);

// Missing years
let raw = create_param_raw(None, None, Some(1.0), Some(0.0));
let raw = create_param_raw(None, None, 1, Some(1.0), Some(0.0));
assert_eq!(
raw.into_parameter(&year_range).unwrap(),
create_param(2000..=2100, 1.0, 0.0)
);

// Missing discount_rate
let raw = create_param_raw(Some(2010), Some(2020), None, Some(0.0));
let raw = create_param_raw(Some(2010), Some(2020), 1, None, Some(0.0));
assert_eq!(
raw.into_parameter(&year_range).unwrap(),
create_param(2010..=2020, 0.0, 0.0)
);

// Missing cap2act
let raw = create_param_raw(Some(2010), Some(2020), Some(1.0), None);
let raw = create_param_raw(Some(2010), Some(2020), 1, Some(1.0), None);
assert_eq!(
raw.into_parameter(&year_range).unwrap(),
create_param(2010..=2020, 1.0, 1.0)
Expand All @@ -397,21 +452,21 @@ mod tests {

// Normal case
assert!(
create_param_raw(Some(2000), Some(2100), Some(1.0), Some(0.0))
create_param_raw(Some(2000), Some(2100), 1, Some(1.0), Some(0.0))
.into_parameter(&year_range)
.is_ok()
);

// start_year out of range - this is permitted
assert!(
create_param_raw(Some(1999), Some(2100), Some(1.0), Some(0.0))
create_param_raw(Some(1999), Some(2100), 1, Some(1.0), Some(0.0))
.into_parameter(&year_range)
.is_ok()
);

// end_year out of range - this is permitted
assert!(
create_param_raw(Some(2000), Some(2101), Some(1.0), Some(0.0))
create_param_raw(Some(2000), Some(2101), 1, Some(1.0), Some(0.0))
.into_parameter(&year_range)
.is_ok()
);
Expand All @@ -424,12 +479,42 @@ mod tests {

// start_year after end_year
assert!(
create_param_raw(Some(2001), Some(2000), Some(1.0), Some(0.0))
create_param_raw(Some(2001), Some(2000), 1, Some(1.0), Some(0.0))
.into_parameter(&year_range)
.is_ok()
);
}

#[test]
fn test_param_raw_validate_bad_lifetime() {
// lifetime = 0
assert!(
create_param_raw(Some(2000), Some(2100), 0, Some(1.0), Some(0.0))
.validate()
.is_err()
);
}

#[test]
fn test_param_raw_validate_bad_discount_rate() {
// discount rate = -1
assert!(
create_param_raw(Some(2000), Some(2100), 0, Some(-1.0), Some(0.0))
.validate()
.is_err()
);
}

#[test]
fn test_param_raw_validate_bad_capt2act() {
// capt2act = -1
assert!(
create_param_raw(Some(2000), Some(2100), 0, Some(1.0), Some(-1.0))
.validate()
.is_err()
);
}

#[test]
fn test_read_process_parameters_from_iter_good() {
let year_range = 2000..=2100;
Expand Down

0 comments on commit 4e88827

Please sign in to comment.