Skip to content

Commit 4bcb385

Browse files
committed
Merge remote-tracking branch 'origin/main' into output-dual-values-csv
2 parents 3b29700 + 0ae972a commit 4bcb385

18 files changed

Lines changed: 492 additions & 400 deletions

examples/simple/agents.csv

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
id,description,regions,decision_rule,decision_lexico_tolerance
2-
A0_GEX,Gas extractors,GBR,single,
3-
A0_GPR,Gas processors,GBR,single,
4-
A0_ELC,Electricity generators,GBR,single,
5-
A0_RES,Residential consumer,GBR,single,
2+
A0_GEX,Gas extractors,all,single,
3+
A0_GPR,Gas processors,all,single,
4+
A0_ELC,Electricity generators,all,single,
5+
A0_RES,Residential consumer,all,single,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
commodity_id,regions,years,time_slice,balance_type,value
2-
CO2EMT,GBR,all,annual,net,0.04
2+
CO2EMT,all,all,annual,net,0.04
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
process_id,regions,years,capital_cost,fixed_operating_cost,variable_operating_cost,lifetime,discount_rate,capacity_to_activity
2-
GASDRV,GBR,all,10.0,0.3,2.0,25,0.1,1.0
3-
GASPRC,GBR,all,7.0,0.21,0.5,25,0.1,1.0
4-
WNDFRM,GBR,all,1000.0,30.0,0.4,25,0.1,31.54
5-
GASCGT,GBR,all,700.0,21.0,0.55,30,0.1,31.54
6-
RGASBR,GBR,all,55.56,1.6668,0.16,15,0.1,1.0
7-
RELCHP,GBR,all,138.9,4.167,0.17,15,0.1,1.0
2+
GASDRV,all,all,10.0,0.3,2.0,25,0.1,1.0
3+
GASPRC,all,all,7.0,0.21,0.5,25,0.1,1.0
4+
WNDFRM,all,all,1000.0,30.0,0.4,25,0.1,31.54
5+
GASCGT,all,all,700.0,21.0,0.55,30,0.1,31.54
6+
RGASBR,all,all,55.56,1.6668,0.16,15,0.1,1.0
7+
RELCHP,all,all,138.9,4.167,0.17,15,0.1,1.0

examples/simple/processes.csv

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
id,description,regions,start_year,end_year
2-
GASDRV,Dry gas extraction,GBR,2020,2030
3-
GASPRC,Gas processing,GBR,2020,2030
4-
WNDFRM,Wind farm,GBR,2020,2030
5-
GASCGT,Gas combined cycle turbine,GBR,2020,2030
6-
RGASBR,Gas boiler,GBR,2020,2030
7-
RELCHP,Heat pump,GBR,2020,2030
2+
GASDRV,Dry gas extraction,all,2020,2030
3+
GASPRC,Gas processing,all,2020,2030
4+
WNDFRM,Wind farm,all,2020,2030
5+
GASCGT,Gas combined cycle turbine,all,2020,2030
6+
RGASBR,Gas boiler,all,2020,2030
7+
RELCHP,Heat pump,all,2020,2030

src/fixture.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::process::{
1111
ProcessParameterMap,
1212
};
1313
use crate::region::RegionID;
14-
use crate::time_slice::TimeSliceID;
14+
use crate::time_slice::{TimeSliceID, TimeSliceInfo};
1515
use indexmap::indexmap;
1616
use itertools::Itertools;
1717
use rstest::fixture;
@@ -35,6 +35,11 @@ pub fn region_id() -> RegionID {
3535
"GBR".into()
3636
}
3737

38+
#[fixture]
39+
pub fn commodity_ids() -> HashSet<CommodityID> {
40+
iter::once("commodity1".into()).collect()
41+
}
42+
3843
#[fixture]
3944
pub fn region_ids() -> HashSet<RegionID> {
4045
["GBR".into(), "USA".into()].into_iter().collect()
@@ -130,3 +135,20 @@ pub fn time_slice() -> TimeSliceID {
130135
time_of_day: "day".into(),
131136
}
132137
}
138+
139+
#[fixture]
140+
pub fn time_slice_info() -> TimeSliceInfo {
141+
TimeSliceInfo {
142+
seasons: iter::once("winter".into()).collect(),
143+
times_of_day: iter::once("day".into()).collect(),
144+
fractions: [(
145+
TimeSliceID {
146+
season: "winter".into(),
147+
time_of_day: "day".into(),
148+
},
149+
1.0,
150+
)]
151+
.into_iter()
152+
.collect(),
153+
}
154+
}

src/id.rs

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
//! Code for handling IDs
22
use anyhow::{Context, Result};
3-
use indexmap::IndexSet;
3+
use indexmap::{IndexMap, IndexSet};
4+
use std::borrow::Borrow;
45
use std::collections::HashSet;
6+
use std::fmt::Display;
7+
use std::hash::Hash;
58

69
/// A trait alias for ID types
7-
pub trait IDLike:
8-
Eq + std::hash::Hash + std::borrow::Borrow<str> + Clone + std::fmt::Display + From<String>
9-
{
10-
}
11-
impl<T> IDLike for T where
12-
T: Eq + std::hash::Hash + std::borrow::Borrow<str> + Clone + std::fmt::Display + From<String>
13-
{
14-
}
10+
pub trait IDLike: Eq + Hash + Borrow<str> + Clone + Display + From<String> {}
11+
impl<T> IDLike for T where T: Eq + Hash + Borrow<str> + Clone + Display + From<String> {}
1512

1613
macro_rules! define_id_type {
1714
($name:ident) => {
@@ -78,43 +75,25 @@ pub(crate) use define_id_getter;
7875

7976
/// A data structure containing a set of IDs
8077
pub trait IDCollection<ID: IDLike> {
81-
/// Get the ID from the collection by its string representation.
82-
///
83-
/// # Arguments
84-
///
85-
/// * `id` - The string representation of the ID
86-
///
87-
/// # Returns
88-
///
89-
/// A copy of the ID in `self`, or an error if not found.
90-
fn get_id_by_str(&self, id: &str) -> Result<ID>;
91-
9278
/// Check if the ID is in the collection, returning a copy of it if found.
9379
///
9480
/// # Arguments
9581
///
96-
/// * `id` - The ID to check
82+
/// * `id` - The ID to check (can be string or ID type)
9783
///
9884
/// # Returns
9985
///
10086
/// A copy of the ID in `self`, or an error if not found.
101-
fn get_id(&self, id: &ID) -> Result<ID>;
87+
fn get_id<T: Borrow<str> + Display + ?Sized>(&self, id: &T) -> Result<&ID>;
10288
}
10389

10490
macro_rules! define_id_methods {
10591
() => {
106-
fn get_id_by_str(&self, id: &str) -> Result<ID> {
107-
let found = self
108-
.get(id)
109-
.with_context(|| format!("Unknown ID {id} found"))?;
110-
Ok(found.clone())
111-
}
112-
113-
fn get_id(&self, id: &ID) -> Result<ID> {
92+
fn get_id<T: Borrow<str> + Display + ?Sized>(&self, id: &T) -> Result<&ID> {
11493
let found = self
11594
.get(id.borrow())
11695
.with_context(|| format!("Unknown ID {id} found"))?;
117-
Ok(found.clone())
96+
Ok(found)
11897
}
11998
};
12099
}
@@ -126,3 +105,12 @@ impl<ID: IDLike> IDCollection<ID> for HashSet<ID> {
126105
impl<ID: IDLike> IDCollection<ID> for IndexSet<ID> {
127106
define_id_methods!();
128107
}
108+
109+
impl<ID: IDLike, V> IDCollection<ID> for IndexMap<ID, V> {
110+
fn get_id<T: Borrow<str> + Display + ?Sized>(&self, id: &T) -> Result<&ID> {
111+
let (found, _) = self
112+
.get_key_value(id.borrow())
113+
.with_context(|| format!("Unknown ID {id} found"))?;
114+
Ok(found)
115+
}
116+
}

src/input/agent/commodity_portion.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use super::super::*;
33
use crate::agent::{AgentCommodityPortionsMap, AgentID, AgentMap};
44
use crate::commodity::{CommodityID, CommodityMap, CommodityType};
5+
use crate::id::IDCollection;
56
use crate::region::RegionID;
67
use crate::year::parse_year_str;
78
use anyhow::{ensure, Context, Result};
@@ -66,9 +67,7 @@ where
6667
for agent_commodity_portion_raw in iter {
6768
// Get agent ID
6869
let agent_id_raw = agent_commodity_portion_raw.agent_id.as_str();
69-
let (id, _agent) = agents
70-
.get_key_value(agent_id_raw)
71-
.with_context(|| format!("Invalid agent ID {agent_id_raw}"))?;
70+
let id = agents.get_id(agent_id_raw)?;
7271

7372
// Get/create entry for agent
7473
let entry = agent_commodity_portions
@@ -77,9 +76,7 @@ where
7776

7877
// Insert portion for the commodity/year(s)
7978
let commodity_id_raw = agent_commodity_portion_raw.commodity_id.as_str();
80-
let (commodity_id, _commodity) = commodities
81-
.get_key_value(commodity_id_raw)
82-
.with_context(|| format!("Invalid commodity ID {commodity_id_raw}"))?;
79+
let commodity_id = commodities.get_id(commodity_id_raw)?;
8380
let years = parse_year_str(&agent_commodity_portion_raw.years, milestone_years)?;
8481
for year in years {
8582
try_insert(

src/input/agent/cost_limit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ where
6161
let years = parse_year_str(&agent_cost_limits_raw.years, milestone_years)?;
6262

6363
// Get agent ID
64-
let agent_id = agent_ids.get_id_by_str(&agent_cost_limits_raw.agent_id)?;
64+
let agent_id = agent_ids.get_id(&agent_cost_limits_raw.agent_id)?;
6565

6666
// Get or create entry in the map
6767
let entry = map.entry(agent_id.clone()).or_default();

src/input/agent/search_space.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,16 @@ impl AgentSearchSpaceRaw {
5252
let search_space = Rc::new(parse_search_space_str(&self.search_space, process_ids)?);
5353

5454
// Get commodity
55-
let commodity_id = commodity_ids.get_id_by_str(&self.commodity_id)?;
55+
let commodity_id = commodity_ids.get_id(&self.commodity_id)?;
5656

5757
// Check that the year is a valid milestone year
5858
let year = parse_year_str(&self.years, milestone_years)?;
5959

60-
let (agent_id, _) = agents
61-
.get_key_value(self.agent_id.as_str())
62-
.context("Invalid agent ID")?;
60+
let agent_id = agents.get_id(&self.agent_id)?;
6361

6462
Ok(AgentSearchSpace {
6563
agent_id: agent_id.clone(),
66-
commodity_id,
64+
commodity_id: commodity_id.clone(),
6765
years: year,
6866
search_space,
6967
})
@@ -86,7 +84,7 @@ fn parse_search_space_str(
8684
} else {
8785
search_space
8886
.split(';')
89-
.map(|id| process_ids.get_id_by_str(id.trim()))
87+
.map(|id| Ok(process_ids.get_id(id.trim())?.clone()))
9088
.try_collect()
9189
}
9290
}

src/input/asset.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,16 @@ where
6969
I: Iterator<Item = AssetRaw>,
7070
{
7171
iter.map(|asset| -> Result<_> {
72-
let agent_id = agent_ids.get_id_by_str(&asset.agent_id)?;
72+
let agent_id = agent_ids.get_id(&asset.agent_id)?;
7373
let process = processes
7474
.get(asset.process_id.as_str())
7575
.with_context(|| format!("Invalid process ID: {}", &asset.process_id))?;
76-
let region_id = region_ids.get_id_by_str(&asset.region_id)?;
76+
let region_id = region_ids.get_id(&asset.region_id)?;
7777

7878
Asset::new(
79-
agent_id,
79+
agent_id.clone(),
8080
Rc::clone(process),
81-
region_id,
81+
region_id.clone(),
8282
asset.capacity,
8383
asset.commission_year,
8484
)

0 commit comments

Comments
 (0)