///|
fn parameter_record(
name : String,
value : Double,
unit : String,
lower_bound : Double,
upper_bound : Double,
source : String,
) -> ParameterRecord {
ParameterRecord::new(
name~,
value~,
unit~,
lower_bound~,
upper_bound~,
source~,
)
}
///|
fn antoine_records(component : Component) -> Array[ParameterRecord] {
[
parameter_record(
component.name + ".antoine.a",
component.antoine.a,
"log10(mmHg)",
-100.0,
100.0,
component.antoine.note,
),
parameter_record(
component.name + ".antoine.b",
component.antoine.b,
"K",
0.0,
10000.0,
component.antoine.note,
),
parameter_record(
component.name + ".antoine.c",
component.antoine.c,
"C",
-500.0,
500.0,
component.antoine.note,
),
parameter_record(
component.name + ".antoine.t_min_k",
component.antoine.t_min_k,
"K",
0.0,
2000.0,
component.antoine.note,
),
parameter_record(
component.name + ".antoine.t_max_k",
component.antoine.t_max_k,
"K",
0.0,
2000.0,
component.antoine.note,
),
]
}
///|
pub fn public_parameter_catalog() -> Array[ParameterRecord] {
let records : Array[ParameterRecord] = []
for component in pressure_catalog_components() {
for record in antoine_records(component) {
records.push(record)
}
}
records
}
///|
pub fn validate_parameter_records(
records : Array[ParameterRecord],
) -> ParameterValidationReport {
let messages : Array[String] = []
let issue_count = for i = 0, count = 0; i < records.length(); {
let record = records[i]
let invalid_bounds = record.lower_bound >= record.upper_bound
let outside = record.value < record.lower_bound ||
record.value > record.upper_bound
let invalid_unit = record.unit.length() == 0
let invalid_source = record.source.length() == 0
let issues = (if invalid_bounds { 1 } else { 0 }) +
(if outside { 1 } else { 0 }) +
(if invalid_unit { 1 } else { 0 }) +
(if invalid_source { 1 } else { 0 })
if invalid_bounds {
messages.push(record.name + ": invalid bounds")
}
if outside {
messages.push(record.name + ": value outside bounds")
}
if invalid_unit {
messages.push(record.name + ": missing unit")
}
if invalid_source {
messages.push(record.name + ": missing source")
}
continue i + 1, count + issues
} nobreak {
count
}
ParameterValidationReport::{
valid: issue_count == 0,
issue_count,
checked_count: records.length(),
messages,
}
}
///|
pub fn parameter_catalog_is_valid(records : Array[ParameterRecord]) -> Bool {
validate_parameter_records(records).valid
}
///|
pub fn parameter_records_for_component(
component : Component,
) -> Array[ParameterRecord] {
antoine_records(component)
}
///|
pub fn parameter_record_value(
records : Array[ParameterRecord],
name : String,
) -> Double raise VleError {
for record in records {
if record.name == name {
return record.value
}
}
raise VleError::InvalidParameter("parameter name was not found")
}
///|
pub fn parameter_records_in_unit(
records : Array[ParameterRecord],
unit : String,
) -> Array[ParameterRecord] {
[
for record in records if record.unit == unit => record
]
}
///|
pub fn parameter_records_with_source(
records : Array[ParameterRecord],
source_fragment : String,
) -> Array[ParameterRecord] {
[
for record in records if record.source.contains(source_fragment) => record
]
}
///|
pub fn parameter_catalog_units(
records : Array[ParameterRecord],
) -> Array[String] {
let result : Array[String] = []
for record in records {
if !result.contains(record.unit) {
result.push(record.unit)
}
}
result
}
///|
pub fn parameter_catalog_sources(
records : Array[ParameterRecord],
) -> Array[String] {
let result : Array[String] = []
for record in records {
if !result.contains(record.source) {
result.push(record.source)
}
}
result
}
///|
pub fn parameter_range_width(record : ParameterRecord) -> Double {
record.upper_bound - record.lower_bound
}
///|
pub fn parameter_relative_position(
record : ParameterRecord,
) -> Double raise VleError {
if record.upper_bound <= record.lower_bound {
raise VleError::InvalidRange(
low=record.lower_bound,
high=record.upper_bound,
)
}
(record.value - record.lower_bound) / parameter_range_width(record)
}
///|
pub fn parameter_is_near_lower_bound(
record : ParameterRecord,
fraction : Double,
) -> Bool raise VleError {
if fraction < 0.0 || fraction > 1.0 {
raise VleError::InvalidParameter(
"bound fraction must be between zero and one",
)
}
parameter_relative_position(record) <= fraction
}
///|
pub fn parameter_is_near_upper_bound(
record : ParameterRecord,
fraction : Double,
) -> Bool raise VleError {
if fraction < 0.0 || fraction > 1.0 {
raise VleError::InvalidParameter(
"bound fraction must be between zero and one",
)
}
parameter_relative_position(record) >= 1.0 - fraction
}