use cobre_core::{Stage, scenario::SamplingScheme, temporal::StageLagTransition};
use cobre_solver::StageTemplate;
use cobre_stochastic::{ExternalScenarioLibrary, HistoricalScenarioLibrary, StochasticContext};
use crate::{
dcs::DcsParams, horizon_mode::HorizonMode, indexer::StageIndexer,
inflow_method::InflowNonNegativityMethod, noise_key_diag::NoiseKeyDiag,
};
pub struct StageContext<'a> {
pub templates: &'a [StageTemplate],
pub base_rows: &'a [usize],
pub noise_scale: &'a [f64],
pub n_hydros: usize,
pub n_load_buses: usize,
pub load_balance_row_starts: &'a [usize],
pub load_bus_indices: &'a [usize],
pub block_counts_per_stage: &'a [usize],
pub ncs_max_gen: &'a [f64],
pub ncs_allow_curtailment: &'a [bool],
pub discount_factors: &'a [f64],
pub cumulative_discount_factors: &'a [f64],
pub stage_lag_transitions: &'a [StageLagTransition],
pub noise_group_ids: &'a [u32],
pub downstream_par_order: usize,
}
impl StageContext<'_> {
#[inline]
#[must_use]
pub fn noise_group_id_at(&self, t: usize) -> u32 {
if self.noise_group_ids.is_empty() {
#[allow(clippy::cast_possible_truncation)]
return t as u32;
}
debug_assert!(
t < self.noise_group_ids.len(),
"stage index {t} out of bounds for noise_group_ids (len={})",
self.noise_group_ids.len()
);
self.noise_group_ids[t]
}
}
pub struct TrainingContext<'a> {
pub horizon: &'a HorizonMode,
pub indexer: &'a StageIndexer,
pub inflow_method: &'a InflowNonNegativityMethod,
pub stochastic: &'a StochasticContext,
pub initial_state: &'a [f64],
pub inflow_scheme: SamplingScheme,
pub load_scheme: SamplingScheme,
pub ncs_scheme: SamplingScheme,
pub stages: &'a [Stage],
pub historical_library: Option<&'a HistoricalScenarioLibrary>,
pub external_inflow_library: Option<&'a ExternalScenarioLibrary>,
pub external_load_library: Option<&'a ExternalScenarioLibrary>,
pub external_ncs_library: Option<&'a ExternalScenarioLibrary>,
pub recent_accum_seed: &'a [f64],
pub recent_weight_seed: f64,
pub dcs: Option<DcsParams>,
pub noise_key_diag: Option<&'a NoiseKeyDiag>,
}