///|
pub(all) struct Observable {
name : String
unit : String
values : Array[Double]
} derive(Debug, ToJson)
///|
pub fn Observable::new(
name : String,
unit : String,
values : Array[Double],
) -> Observable {
{ name, unit, values }
}
///|
pub fn Observable::count(observable : Observable) -> Int {
observable.values.length()
}
///|
pub fn Observable::mean(observable : Observable) -> Double {
mean(observable.values)
}
///|
pub fn Observable::minimum(observable : Observable) -> Double {
min_value(observable.values, 0.0)
}
///|
pub fn Observable::maximum(observable : Observable) -> Double {
max_value(observable.values, 0.0)
}
///|
pub fn Observable::range(observable : Observable) -> Double {
observable.maximum() - observable.minimum()
}
///|
pub fn Observable::normalize(observable : Observable) -> Observable {
{ ..observable, values: normalize_series(observable.values) }
}
///|
pub fn Observable::scale(
observable : Observable,
factor : Double,
) -> Observable {
{ ..observable, values: observable.values.map(fn(value) { value * factor }) }
}
///|
pub fn Observable::shift(
observable : Observable,
amount : Double,
) -> Observable {
{ ..observable, values: observable.values.map(fn(value) { value + amount }) }
}
///|
pub fn Observable::summary(observable : Observable) -> SeriesSummary {
summarize_series(observable.name, observable.values)
}
///|
pub fn Observable::to_csv(observable : Observable) -> String {
serialize_scalar_series(observable.name, observable.values)
}
///|
pub fn observables_from_diagnostics(
values : ArrayView[PicDiagnostics],
) -> Array[Observable] {
[
Observable::new(
"total_charge",
"C",
values.map(fn(value) { value.total_charge }),
),
Observable::new(
"kinetic_energy",
"J",
values.map(fn(value) { value.kinetic_energy }),
),
Observable::new(
"field_energy",
"J",
values.map(fn(value) { value.field_energy }),
),
Observable::new(
"total_energy",
"J",
values.map(fn(value) { value.total_energy() }),
),
Observable::new(
"mean_velocity",
"m/s",
values.map(fn(value) { value.mean_velocity }),
),
]
}
///|
pub fn observable_summary_csv(values : ArrayView[Observable]) -> String {
let output = StringBuilder()
output.write_string("name,unit,count,minimum,maximum,mean\n")
for value in values {
let summary = value.summary()
output.write_string(
"\{value.name},\{value.unit},\{summary.count},\{summary.minimum},\{summary.maximum},\{summary.mean}\n",
)
}
output.to_string()
}
///|
pub fn merge_observables(first : Observable, second : Observable) -> Observable {
let values = first.values.copy()
for value in second.values {
values.push(value)
}
Observable::new(first.name, first.unit, values)
}
///|
pub fn observable_difference(
first : Observable,
second : Observable,
) -> Observable {
Observable::new(
first.name,
first.unit,
field_difference(first.values, second.values),
)
}
///|
pub fn observable_correlation(
first : Observable,
second : Observable,
) -> Double {
correlation(first.values, second.values)
}