Skip to content

Commit b771079

Browse files
committed
Add comments and rename function to clarify appraisal output filtering behaviour
1 parent e174be8 commit b771079

2 files changed

Lines changed: 24 additions & 26 deletions

File tree

src/simulation/investment.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub mod appraisal;
2020
use appraisal::coefficients::calculate_coefficients_for_assets;
2121
use appraisal::{
2222
AppraisalOutput, appraise_investment, count_equal_and_best_appraisal_outputs,
23-
sort_appraisal_outputs_by_investment_priority,
23+
sort_and_filter_appraisal_outputs,
2424
};
2525

2626
/// A map of demand across time slices for a specific market
@@ -796,13 +796,11 @@ fn select_best_assets(
796796
&demand,
797797
)?;
798798

799-
sort_appraisal_outputs_by_investment_priority(&mut outputs_for_opts);
799+
// Sort by investment priority and discord non-feasible options
800+
sort_and_filter_appraisal_outputs(&mut outputs_for_opts);
800801

801-
// Check if all options have zero capacity. If so, we cannot meet demand, so have to bail
802+
// Check if there are any remaining options. If not, we cannot meet demand, so have to bail
802803
// out.
803-
//
804-
// This may happen if the asset has zero activity limits for all time slices with
805-
// demand.
806804
if outputs_for_opts.is_empty() {
807805
let remaining_demands: Vec<_> = demand
808806
.iter()

src/simulation/investment/appraisal.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -358,18 +358,18 @@ fn compare_asset_fallback(asset1: &Asset, asset2: &Asset) -> Ordering {
358358
.cmp(&(asset1.is_commissioned(), asset1.commission_year()))
359359
}
360360

361-
/// Sort appraisal outputs by their investment priority.
361+
/// Sort appraisal outputs by their investment priority and exclude non-feasible options.
362362
///
363-
/// Primarily this is decided by their appraisal metric.
364-
/// When appraisal metrics are equal, a tie-breaker fallback is used. Commissioned assets
365-
/// are preferred over uncommissioned assets, and newer assets are preferred over older
366-
/// ones. The function does not guarantee that all ties will be resolved.
363+
/// Investment priority is primarily decided by appraisal metric. When appraisal metrics are equal,
364+
/// a tie-breaker fallback is used. Commissioned assets are preferred over uncommissioned assets,
365+
/// and newer assets are preferred over older ones. The function does not guarantee that all ties
366+
/// will be resolved.
367367
///
368-
/// Before sorting, outputs are filtered using [`AppraisalOutput::is_valid`], which
369-
/// excludes entries with invalid metrics (e.g. `None`) as well as zero capacity. This
370-
/// avoids meaningless or `NaN` appraisal metrics that could cause the program to panic,
371-
/// so the length of the returned vector may be less than the input.
372-
pub fn sort_appraisal_outputs_by_investment_priority(outputs_for_opts: &mut Vec<AppraisalOutput>) {
368+
/// Before sorting, outputs are filtered using [`AppraisalOutput::is_valid`], which excludes entries
369+
/// with invalid metrics (e.g. `None`) as well as zero capacity. This avoids meaningless or `NaN`
370+
/// appraisal metrics that could cause the program to panic, so the length of the returned vector
371+
/// may be less than the input.
372+
pub fn sort_and_filter_appraisal_outputs(outputs_for_opts: &mut Vec<AppraisalOutput>) {
373373
outputs_for_opts.retain(AppraisalOutput::is_valid);
374374
outputs_for_opts.sort_by(|output1, output2| match output1.compare_metric(output2) {
375375
// If equal, we fall back on comparing asset properties
@@ -626,7 +626,7 @@ mod tests {
626626

627627
let mut outputs =
628628
appraisal_outputs_with_investment_priority_invariant_to_assets(metrics, &asset);
629-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
629+
sort_and_filter_appraisal_outputs(&mut outputs);
630630

631631
assert_approx_eq!(f64, outputs[0].metric.as_ref().unwrap().value(), 3.0); // Best (lowest)
632632
assert_approx_eq!(f64, outputs[1].metric.as_ref().unwrap().value(), 5.0);
@@ -653,7 +653,7 @@ mod tests {
653653

654654
let mut outputs =
655655
appraisal_outputs_with_investment_priority_invariant_to_assets(metrics, &asset);
656-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
656+
sort_and_filter_appraisal_outputs(&mut outputs);
657657

658658
// Higher profitability index is better, so should be sorted: 3.0, 2.0, 1.5
659659
assert_approx_eq!(f64, outputs[0].metric.as_ref().unwrap().value(), 3.0); // Best (highest PI)
@@ -685,7 +685,7 @@ mod tests {
685685

686686
let mut outputs =
687687
appraisal_outputs_with_investment_priority_invariant_to_assets(metrics, &asset);
688-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
688+
sort_and_filter_appraisal_outputs(&mut outputs);
689689

690690
// Zero AFC should be first despite lower absolute surplus value
691691
assert_approx_eq!(f64, outputs[0].metric.as_ref().unwrap().value(), 50.0); // Zero AFC (uses surplus)
@@ -709,7 +709,7 @@ mod tests {
709709
let mut outputs =
710710
appraisal_outputs_with_investment_priority_invariant_to_assets(metrics, &asset);
711711
// This should panic when trying to compare different metric types
712-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
712+
sort_and_filter_appraisal_outputs(&mut outputs);
713713
}
714714

715715
/// Test that when metrics are equal, commissioned assets are sorted by commission year (newer first)
@@ -745,7 +745,7 @@ mod tests {
745745
];
746746

747747
let mut outputs = appraisal_outputs(assets, metrics);
748-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
748+
sort_and_filter_appraisal_outputs(&mut outputs);
749749

750750
// Should be sorted by commission year, newest first: 2020, 2015, 2010
751751
assert_eq!(outputs[0].asset.commission_year(), 2020);
@@ -782,7 +782,7 @@ mod tests {
782782
];
783783

784784
let mut outputs = appraisal_outputs(assets.clone(), metrics);
785-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
785+
sort_and_filter_appraisal_outputs(&mut outputs);
786786

787787
// Verify order is preserved - should match the original agent_ids array
788788
for (&expected_id, output) in agent_ids.iter().zip(outputs) {
@@ -838,7 +838,7 @@ mod tests {
838838
];
839839

840840
let mut outputs = appraisal_outputs(assets, metrics);
841-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
841+
sort_and_filter_appraisal_outputs(&mut outputs);
842842

843843
// Commissioned assets should be prioritised first
844844
assert!(outputs[0].asset.is_commissioned());
@@ -901,7 +901,7 @@ mod tests {
901901
];
902902

903903
let mut outputs = appraisal_outputs(assets, metrics);
904-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
904+
sort_and_filter_appraisal_outputs(&mut outputs);
905905

906906
// non-commissioned asset prioritised because it has a slightly better metric
907907
assert_approx_eq!(
@@ -934,7 +934,7 @@ mod tests {
934934
})
935935
.collect();
936936

937-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
937+
sort_and_filter_appraisal_outputs(&mut outputs);
938938

939939
// All zero capacity outputs should be filtered out
940940
assert_eq!(outputs.len(), 0);
@@ -953,7 +953,7 @@ mod tests {
953953
};
954954
let mut outputs = vec![output];
955955

956-
sort_appraisal_outputs_by_investment_priority(&mut outputs);
956+
sort_and_filter_appraisal_outputs(&mut outputs);
957957

958958
// The invalid output should have been filtered out
959959
assert_eq!(outputs.len(), 0);

0 commit comments

Comments
 (0)