///|
/// Validation result for trial metadata received from an acquisition system.
pub struct MetadataValidation {
is_valid : Bool
flags : Array[String]
} derive(Debug)
///|
pub fn sampling_rate_is_supported(
metadata : TrialMetadata,
minimum_hz : Double,
maximum_hz : Double,
) -> Bool {
let lower = if minimum_hz < maximum_hz { minimum_hz } else { maximum_hz }
let upper = if minimum_hz < maximum_hz { maximum_hz } else { minimum_hz }
!metadata.sampling_rate.is_nan() &&
!metadata.sampling_rate.is_inf() &&
metadata.sampling_rate >= lower &&
metadata.sampling_rate <= upper
}
///|
/// Validates identifiers, physical mass, rate, and supported bilateral side.
pub fn validate_trial_metadata(metadata : TrialMetadata) -> MetadataValidation {
let flags : Array[String] = []
if metadata.subject_id.length() == 0 {
flags.push("missing_subject_id")
}
if metadata.sampling_rate <= 0.0 ||
metadata.sampling_rate.is_nan() ||
metadata.sampling_rate.is_inf() {
flags.push("invalid_sampling_rate")
}
if metadata.nominal_body_mass <= 0.0 ||
metadata.nominal_body_mass.is_nan() ||
metadata.nominal_body_mass.is_inf() {
flags.push("invalid_body_mass")
}
if metadata.side != "left" &&
metadata.side != "right" &&
metadata.side != "both" {
flags.push("unsupported_side")
}
{ is_valid: flags.length() == 0, flags }
}
///|
/// Stable one-line metadata representation for logs and benchmark provenance.
pub fn format_metadata_summary(metadata : TrialMetadata) -> String {
"subject_id=" +
metadata.subject_id +
" sampling_rate_hz=" +
metadata.sampling_rate.to_string() +
" body_mass_kg=" +
metadata.nominal_body_mass.to_string() +
" side=" +
metadata.side
}
///|
/// Returns the nominal sample period in seconds, or zero for invalid rates.
pub fn metadata_sampling_period_s(metadata : TrialMetadata) -> Double {
if metadata.sampling_rate <= 0.0 ||
metadata.sampling_rate.is_nan() ||
metadata.sampling_rate.is_inf() {
0.0
} else {
1.0 / metadata.sampling_rate
}
}
///|
/// Compact CSV row for provenance logs.
pub fn format_metadata_csv(metadata : TrialMetadata) -> String {
metadata.subject_id +
"," +
metadata.sampling_rate.to_string() +
"," +
metadata.nominal_body_mass.to_string() +
"," +
metadata.side +
"\n"
}
///|
/// JSON-compatible metadata object for machine-readable provenance.
pub fn format_metadata_json(metadata : TrialMetadata) -> String {
let builder = StringBuilder()
builder.write_string("{\n")
builder.write_string(" \"subject_id\": \"")
builder.write_string(metadata.subject_id)
builder.write_string("\",\n")
builder.write_string(" \"sampling_rate_hz\": ")
builder.write_string(metadata.sampling_rate.to_string())
builder.write_string(",\n")
builder.write_string(" \"nominal_body_mass_kg\": ")
builder.write_string(metadata.nominal_body_mass.to_string())
builder.write_string(",\n")
builder.write_string(" \"side\": \"")
builder.write_string(metadata.side)
builder.write_string("\"\n")
builder.write_string("}")
builder.to_string()
}
///|
/// Joins validation flags into a stable diagnostic string.
pub fn metadata_flag_summary(validation : MetadataValidation) -> String {
if validation.is_valid {
return "valid"
}
let builder = StringBuilder()
for i = 0; i < validation.flags.length(); i = i + 1 {
if i > 0 {
builder.write_string("|")
}
builder.write_string(validation.flags[i])
}
builder.to_string()
}
///|
pub fn metadata_is_bilateral(metadata : TrialMetadata) -> Bool {
metadata.side == "both"
}
///|
pub fn metadata_side_code(metadata : TrialMetadata) -> Int {
if metadata.side == "left" {
-1
} else if metadata.side == "right" {
1
} else {
0
}
}
///|
pub fn metadata_side_name(metadata : TrialMetadata) -> String {
if metadata.side == "left" {
"left"
} else if metadata.side == "right" {
"right"
} else if metadata.side == "both" {
"both"
} else {
"unknown"
}
}
///|
pub fn metadata_is_unilateral(metadata : TrialMetadata) -> Bool {
metadata.side == "left" || metadata.side == "right"
}
///|
pub fn metadata_has_subject_id(metadata : TrialMetadata) -> Bool {
metadata.subject_id.length() > 0
}
///|
pub fn metadata_is_complete(metadata : TrialMetadata) -> Bool {
validate_trial_metadata(metadata).is_valid
}
///|
pub fn metadata_is_physical(metadata : TrialMetadata) -> Bool {
metadata.nominal_body_mass > 0.0 && !metadata.nominal_body_mass.is_nan()
}