pub mod forcing;
pub mod metrics;
pub use forcing::{Forcing, BasinInfo, Outlet};
pub use metrics::{
MetricsReport, nse, kge, rmse, pbias, r2, dc_grade, compute_metrics,
GbtEventErrors, QualificationTolerance, QualificationReport,
event_errors, event_qualified, qualified_rate, qualification_grade, scheme_grade,
compute_metrics_gbt,
ProbabilisticReport, crps, brier, pod_far_csi, ensemble_exceedance, compute_probabilistic,
rank_histogram,
};
use serde::{Serialize, Deserialize};
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum ModelType {
Xinanjiang,
Topmodel,
Swat,
Apicont,
}
impl ModelType {
pub fn name(&self) -> &'static str {
match self {
ModelType::Xinanjiang => "新安江",
ModelType::Topmodel => "TOPMODEL",
ModelType::Swat => "SWAT",
ModelType::Apicont => "API-CONT",
}
}
}
pub trait HydroModel: Send {
type Params: Serialize + for<'de> Deserialize<'de> + Clone + Send;
fn new(params: Self::Params) -> Self;
fn step(&mut self, forcing: &Forcing, dt_h: f64);
fn discharge(&self) -> f64;
fn state(&self) -> serde_json::Value;
fn reset(&mut self);
fn name(&self) -> &'static str;
fn params(&self) -> &Self::Params;
fn params_mut(&mut self) -> &mut Self::Params;
}
pub trait DynHydroModel: Send {
fn step(&mut self, forcing: &Forcing, dt_h: f64);
fn discharge(&self) -> f64;
fn name(&self) -> &'static str;
fn params_json(&self) -> serde_json::Value;
fn set_params_json(&mut self, v: &serde_json::Value);
fn reset(&mut self);
}
impl<M: HydroModel> DynHydroModel for M {
fn step(&mut self, forcing: &Forcing, dt_h: f64) {
HydroModel::step(self, forcing, dt_h);
}
fn discharge(&self) -> f64 {
HydroModel::discharge(self)
}
fn name(&self) -> &'static str {
HydroModel::name(self)
}
fn params_json(&self) -> serde_json::Value {
serde_json::to_value(self.params()).unwrap_or(serde_json::Value::Null)
}
fn set_params_json(&mut self, v: &serde_json::Value) {
if let Ok(p) = serde_json::from_value::<M::Params>(v.clone()) {
*self.params_mut() = p;
}
}
fn reset(&mut self) {
HydroModel::reset(self);
}
}