Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
36 changes: 20 additions & 16 deletions src/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ use crate::process::{
ProcessInvestmentConstraintsMap, ProcessMap, ProcessParameter, ProcessParameterMap,
};
use crate::region::RegionID;
use crate::simulation::investment::appraisal::LCOXMetric;
use crate::simulation::investment::appraisal::{
AppraisalOutput, coefficients::ObjectiveCoefficients,
};
use crate::simulation::investment::appraisal::coefficients::ActivityCoefficients;
use crate::simulation::investment::appraisal::{AppraisalOptimisation, LCOXMetric, MetricTrait};
use crate::time_slice::{TimeSliceID, TimeSliceInfo, TimeSliceLevel};
use crate::units::{
Activity, ActivityPerCapacity, Capacity, Dimensionless, Flow, MoneyPerActivity,
Expand Down Expand Up @@ -398,21 +396,27 @@ pub fn time_slice_info2() -> TimeSliceInfo {
}

#[fixture]
pub fn appraisal_output(asset: Asset, time_slice: TimeSliceID) -> AppraisalOutput {
pub fn appraisal_output(
asset: Asset,
time_slice: TimeSliceID,
) -> (
AssetRef,
AppraisalOptimisation,
Box<dyn MetricTrait>,
Arc<ActivityCoefficients>,
) {
let activity_coefficients = indexmap! { time_slice.clone() => MoneyPerActivity(0.5) };
let market_costs = indexmap! { time_slice.clone() => MoneyPerActivity(0.4) };
let activity = indexmap! { time_slice.clone() => Activity(10.0) };
let unmet_demand = indexmap! { time_slice.clone() => Flow(5.0) };
AppraisalOutput {
asset: AssetRef::from(asset),
coefficients: Arc::new(ObjectiveCoefficients {
activity_coefficients,
market_costs,
}),
activity,
unmet_demand,
metric: Some(Box::new(LCOXMetric::new(MoneyPerActivity(4.14)))),
}
(
AssetRef::from(asset),
AppraisalOptimisation {
activity,
unmet_demand,
},
Box::new(LCOXMetric::new(MoneyPerActivity(4.14))),
Arc::new(activity_coefficients),
)
}

#[cfg(test)]
Expand Down
72 changes: 49 additions & 23 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::asset::{Asset, AssetID, AssetRef};
use crate::commodity::CommodityID;
use crate::process::ProcessID;
use crate::region::RegionID;
use crate::simulation::investment::appraisal::AppraisalOutput;
use crate::simulation::investment::appraisal::coefficients::ActivityCoefficients;
use crate::simulation::investment::appraisal::{AppraisalMetrics, AppraisalOptimisation};
use crate::simulation::optimisation::{FlowMap, Solution};
use crate::simulation::prices::PriceMap;
use crate::time_slice::TimeSliceID;
Expand All @@ -13,9 +14,11 @@ use anyhow::{Context, Result, ensure};
use csv;
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;
use std::fs::File;
use std::path::{Path, PathBuf};
use std::sync::Arc;

pub mod metadata;
use metadata::write_metadata;
Expand Down Expand Up @@ -476,17 +479,17 @@ impl DebugDataWriter {
&mut self,
milestone_year: u32,
run_description: &str,
appraisal_results: &[AppraisalOutput],
appraisal_results: &AppraisalMetrics,
) -> Result<()> {
for result in appraisal_results {
for (asset, metric) in appraisal_results {
let row = AppraisalResultsRow {
milestone_year,
run_description: self.with_context(run_description),
asset_id: result.asset.id(),
process_id: result.asset.process_id().clone(),
region_id: result.asset.region_id().clone(),
capacity: result.asset.total_capacity(),
metric: result.metric.as_ref().map(|m| m.value()),
asset_id: asset.id(),
process_id: asset.process_id().clone(),
region_id: asset.region_id().clone(),
capacity: asset.total_capacity(),
metric: Some(metric.value()),
};
self.appraisal_results_writer.serialize(row)?;
}
Expand All @@ -499,20 +502,21 @@ impl DebugDataWriter {
&mut self,
milestone_year: u32,
run_description: &str,
appraisal_results: &[AppraisalOutput],
optimisations: &HashMap<AssetRef, AppraisalOptimisation>,
activity_coefficients: &HashMap<AssetRef, Arc<ActivityCoefficients>>,
demand: &IndexMap<TimeSliceID, Flow>,
) -> Result<()> {
for result in appraisal_results {
for (time_slice, activity) in &result.activity {
let activity_coefficient = result.coefficients.activity_coefficients[time_slice];
for (asset, optimisation) in optimisations {
for (time_slice, activity) in &optimisation.activity {
let activity_coefficient = activity_coefficients[asset][time_slice];
let demand = demand[time_slice];
let unmet_demand = result.unmet_demand[time_slice];
let unmet_demand = optimisation.unmet_demand[time_slice];
let row = AppraisalResultsTimeSliceRow {
milestone_year,
run_description: self.with_context(run_description),
asset_id: result.asset.id(),
process_id: result.asset.process_id().clone(),
region_id: result.asset.region_id().clone(),
asset_id: asset.id(),
process_id: asset.process_id().clone(),
region_id: asset.region_id().clone(),
time_slice: time_slice.clone(),
activity: *activity,
activity_coefficient,
Expand Down Expand Up @@ -601,15 +605,18 @@ impl DataWriter {
&mut self,
milestone_year: u32,
run_description: &str,
appraisal_results: &[AppraisalOutput],
appraisal_results: &AppraisalMetrics,
optimisations: &HashMap<AssetRef, AppraisalOptimisation>,
activity_coefficients: &HashMap<AssetRef, Arc<ActivityCoefficients>>,
demand: &IndexMap<TimeSliceID, Flow>,
) -> Result<()> {
if let Some(wtr) = &mut self.debug {
wtr.write_appraisal_results(milestone_year, run_description, appraisal_results)?;
wtr.write_appraisal_time_slice_results(
milestone_year,
run_description,
appraisal_results,
optimisations,
activity_coefficients,
demand,
)?;
}
Expand Down Expand Up @@ -710,7 +717,7 @@ mod tests {
use super::*;
use crate::asset::AssetPool;
use crate::fixture::{appraisal_output, asset, assets, commodity_id, region_id, time_slice};
use crate::simulation::investment::appraisal::AppraisalOutput;
use crate::simulation::investment::appraisal::MetricTrait;
use crate::time_slice::TimeSliceID;
use indexmap::indexmap;
use itertools::{Itertools, assert_equal};
Expand Down Expand Up @@ -1039,16 +1046,26 @@ mod tests {
}

#[rstest]
fn write_appraisal_results(asset: Asset, appraisal_output: AppraisalOutput) {
fn write_appraisal_results(
asset: Asset,
appraisal_output: (
AssetRef,
AppraisalOptimisation,
Box<dyn MetricTrait>,
Arc<ActivityCoefficients>,
),
) {
let milestone_year = 2020;
let run_description = "test_run".to_string();
let dir = tempdir().unwrap();

// Write appraisal results
{
let mut writer = DebugDataWriter::create(dir.path()).unwrap();
let (asset_ref, _, metric, _) = appraisal_output;
let metrics = indexmap! { asset_ref => metric };
writer
.write_appraisal_results(milestone_year, &run_description, &[appraisal_output])
.write_appraisal_results(milestone_year, &run_description, &metrics)
.unwrap();
writer.flush().unwrap();
}
Expand All @@ -1075,7 +1092,12 @@ mod tests {
#[rstest]
fn write_appraisal_time_slice_results(
asset: Asset,
appraisal_output: AppraisalOutput,
appraisal_output: (
AssetRef,
AppraisalOptimisation,
Box<dyn MetricTrait>,
Arc<ActivityCoefficients>,
),
time_slice: TimeSliceID,
) {
let milestone_year = 2020;
Expand All @@ -1086,11 +1108,15 @@ mod tests {
// Write appraisal time slice results
{
let mut writer = DebugDataWriter::create(dir.path()).unwrap();
let (asset_ref, optimisation, _, coefficients) = appraisal_output;
let optimisations = HashMap::from([(asset_ref.clone(), optimisation)]);
let activity_coefficients = HashMap::from([(asset_ref, coefficients)]);
writer
.write_appraisal_time_slice_results(
milestone_year,
&run_description,
&[appraisal_output],
&optimisations,
&activity_coefficients,
&demand,
)
.unwrap();
Expand Down
Loading
Loading