///|
/// Privacy-friendly cohort comparison primitives.
/// The module accepts already de-identified observations and returns ranges,
/// ranks, and quality-aware flags without retaining personal identifiers.
pub(all) struct CohortObservation {
reference : String
rmssd_ms : Double
mean_rr_ms : Double
resting_hr_bpm : Double
readiness_score : Double
training_load : Double
signal_quality : Double
age_band : String
activity_band : String
} derive(FromJson, ToJson, Debug, Eq)
///|
pub(all) struct CohortMetricRange {
metric : String
sample_count : Int
minimum : Double
lower_quartile : Double
median : Double
upper_quartile : Double
maximum : Double
mean : Double
standard_deviation : Double
} derive(FromJson, ToJson, Debug, Eq)
///|
pub(all) struct CohortRank {
reference : String
metric : String
value : Double
percentile : Double
z_score : Double
quality_adjusted : Bool
label : String
} derive(FromJson, ToJson, Debug, Eq)
///|
pub(all) struct CohortComparison {
reference : String
quality_ok : Bool
ranks : Array[CohortRank]
flags : Array[String]
similarity_score : Double
} derive(FromJson, ToJson, Debug, Eq)
///|
pub(all) struct CohortComparisonSummary {
observations : Int
quality_eligible : Int
quality_ratio : Double
ranges : Array[CohortMetricRange]
comparisons : Array[CohortComparison]
feature_vector : Array[Double]
} derive(FromJson, ToJson, Debug, Eq)
///|
fn cohort_bound(value : Double, low : Double, high : Double) -> Double {
if value.is_nan() || value.is_inf() {
low
} else {
value.clamp(min=low, max=high)
}
}
///|
pub fn make_cohort_observation(
reference : String,
rmssd_ms : Double,
mean_rr_ms : Double,
resting_hr_bpm : Double,
readiness_score : Double,
training_load : Double,
signal_quality : Double,
age_band : String,
activity_band : String,
) -> CohortObservation {
{
reference,
rmssd_ms: cohort_bound(rmssd_ms, 0.0, 1000.0),
mean_rr_ms: cohort_bound(mean_rr_ms, 0.0, 3000.0),
resting_hr_bpm: cohort_bound(resting_hr_bpm, 0.0, 240.0),
readiness_score: cohort_bound(readiness_score, 0.0, 100.0),
training_load: cohort_bound(training_load, 0.0, 100000.0),
signal_quality: cohort_bound(signal_quality, 0.0, 1.0),
age_band,
activity_band,
}
}
///|
pub fn cohort_observation_is_eligible(
observation : CohortObservation,
quality_floor : Double,
) -> Bool {
observation.reference.length() > 0 &&
observation.rmssd_ms > 0.0 &&
observation.mean_rr_ms > 0.0 &&
observation.resting_hr_bpm > 0.0 &&
observation.signal_quality >= quality_floor
}
///|
fn cohort_metric_values(
observations : Array[CohortObservation],
metric : String,
) -> Array[Double] {
match metric {
"rmssd" => observations.map(item => item.rmssd_ms)
"mean_rr" => observations.map(item => item.mean_rr_ms)
"resting_hr" => observations.map(item => item.resting_hr_bpm)
"readiness" => observations.map(item => item.readiness_score)
"training_load" => observations.map(item => item.training_load)
"quality" => observations.map(item => item.signal_quality)
_ => []
}
}
///|
fn cohort_min(values : Array[Double]) -> Double {
if values.length() == 0 {
0.0
} else {
let mut result = values[0]
for value in values {
if value < result {
result = value
}
}
result
}
}
///|
fn cohort_max(values : Array[Double]) -> Double {
if values.length() == 0 {
0.0
} else {
let mut result = values[0]
for value in values {
if value > result {
result = value
}
}
result
}
}
///|
pub fn cohort_metric_range(
observations : Array[CohortObservation],
metric : String,
) -> CohortMetricRange {
let values = cohort_metric_values(observations, metric)
{
metric,
sample_count: values.length(),
minimum: cohort_min(values),
lower_quartile: quantile_value(values, 0.25),
median: median_value(values),
upper_quartile: quantile_value(values, 0.75),
maximum: cohort_max(values),
mean: mean_value(values),
standard_deviation: standard_deviation(values),
}
}
///|
fn cohort_percentile(values : Array[Double], value : Double) -> Double {
if values.length() == 0 {
0.0
} else {
let lower = values.filter(item => item <= value).length()
lower.to_double() / values.length().to_double()
}
}
///|
fn cohort_z_score(values : Array[Double], value : Double) -> Double {
let sd = standard_deviation(values)
if sd <= 0.000001 {
0.0
} else {
(value - mean_value(values)) / sd
}
}
///|
fn cohort_label(percentile : Double, higher_is_better : Bool) -> String {
let score = if higher_is_better { percentile } else { 1.0 - percentile }
if score >= 0.85 {
"high"
} else if score >= 0.40 {
"typical"
} else {
"low"
}
}
///|
pub fn cohort_rank(
observation : CohortObservation,
observations : Array[CohortObservation],
metric : String,
higher_is_better : Bool,
quality_floor : Double,
) -> CohortRank {
let eligible = observations.filter(item => {
cohort_observation_is_eligible(item, quality_floor)
})
let values = cohort_metric_values(eligible, metric)
let value = match metric {
"rmssd" => observation.rmssd_ms
"mean_rr" => observation.mean_rr_ms
"resting_hr" => observation.resting_hr_bpm
"readiness" => observation.readiness_score
"training_load" => observation.training_load
"quality" => observation.signal_quality
_ => 0.0
}
let percentile = cohort_percentile(values, value)
{
reference: observation.reference,
metric,
value,
percentile,
z_score: cohort_z_score(values, value),
quality_adjusted: observation.signal_quality >= quality_floor,
label: cohort_label(percentile, higher_is_better),
}
}
///|
pub fn cohort_compare(
observation : CohortObservation,
observations : Array[CohortObservation],
quality_floor : Double,
) -> CohortComparison {
let quality_ok = cohort_observation_is_eligible(observation, quality_floor)
let metrics = [
("rmssd", true),
("mean_rr", true),
("resting_hr", false),
("readiness", true),
("training_load", false),
]
let ranks = []
for pair in metrics {
ranks.push(
cohort_rank(observation, observations, pair.0, pair.1, quality_floor),
)
}
let flags = []
for rank in ranks {
if rank.label == "low" {
flags.push("\{rank.metric} is below the comparison range")
} else if rank.label == "high" && rank.metric == "training_load" {
flags.push("training load is above the comparison range")
}
}
if !quality_ok {
flags.push("observation is below the quality floor")
}
let similarity = if ranks.length() == 0 {
0.0
} else {
mean_value(
ranks.map(rank => {
(1.0 - (rank.percentile - 0.5).abs() * 2.0).clamp(min=0.0, max=1.0)
}),
)
}
{
reference: observation.reference,
quality_ok,
ranks,
flags,
similarity_score: similarity,
}
}
///|
pub fn cohort_ranges(
observations : Array[CohortObservation],
quality_floor : Double,
) -> Array[CohortMetricRange] {
let eligible = observations.filter(item => {
cohort_observation_is_eligible(item, quality_floor)
})
[
cohort_metric_range(eligible, "rmssd"),
cohort_metric_range(eligible, "mean_rr"),
cohort_metric_range(eligible, "resting_hr"),
cohort_metric_range(eligible, "readiness"),
cohort_metric_range(eligible, "training_load"),
cohort_metric_range(eligible, "quality"),
]
}
///|
pub fn build_cohort_summary(
observations : Array[CohortObservation],
quality_floor : Double,
) -> CohortComparisonSummary {
let eligible = observations.filter(item => {
cohort_observation_is_eligible(item, quality_floor)
})
let comparisons = []
for observation in observations {
comparisons.push(cohort_compare(observation, observations, quality_floor))
}
let ranges = cohort_ranges(observations, quality_floor)
let feature_vector = [
observations.length().to_double(),
eligible.length().to_double(),
if observations.length() == 0 {
0.0
} else {
eligible.length().to_double() / observations.length().to_double()
},
]
for range in ranges {
feature_vector.push(range.median)
feature_vector.push(range.standard_deviation)
}
{
observations: observations.length(),
quality_eligible: eligible.length(),
quality_ratio: if observations.length() == 0 {
0.0
} else {
eligible.length().to_double() / observations.length().to_double()
},
ranges,
comparisons,
feature_vector,
}
}
///|
pub fn cohort_summary_is_usable(summary : CohortComparisonSummary) -> Bool {
summary.observations > 0 &&
summary.quality_eligible > 0 &&
summary.ranges.length() >= 3
}
///|
pub fn cohort_summary_csv(summary : CohortComparisonSummary) -> String {
let grid = [
[
"metric", "sample_count", "minimum", "lower_quartile", "median", "upper_quartile",
"maximum", "mean", "standard_deviation",
],
]
for range in summary.ranges {
grid.push([
range.metric,
range.sample_count.to_string(),
range.minimum.to_string(),
range.lower_quartile.to_string(),
range.median.to_string(),
range.upper_quartile.to_string(),
range.maximum.to_string(),
range.mean.to_string(),
range.standard_deviation.to_string(),
])
}
to_csv(grid)
}
///|
pub fn cohort_comparisons_csv(comparisons : Array[CohortComparison]) -> String {
let grid = [
[
"reference", "metric", "value", "percentile", "z_score", "label", "flagged",
],
]
for comparison in comparisons {
for rank in comparison.ranks {
grid.push([
comparison.reference,
rank.metric,
rank.value.to_string(),
rank.percentile.to_string(),
rank.z_score.to_string(),
rank.label,
comparison.flags.length().to_string(),
])
}
}
to_csv(grid)
}
///|
pub fn cohort_findings(comparison : CohortComparison) -> Array[String] {
comparison.flags
}
///|
pub fn cohort_percentile_for(
summary : CohortComparisonSummary,
reference : String,
metric : String,
) -> Double {
for comparison in summary.comparisons {
if comparison.reference == reference {
for rank in comparison.ranks {
if rank.metric == metric {
return rank.percentile
}
}
}
}
0.0
}
///|
pub fn cohort_similarity_for(
summary : CohortComparisonSummary,
reference : String,
) -> Double {
for comparison in summary.comparisons {
if comparison.reference == reference {
return comparison.similarity_score
}
}
0.0
}
///|
pub fn cohort_quality_adjusted_score(
observation : CohortObservation,
summary : CohortComparisonSummary,
) -> Double {
let similarity = cohort_similarity_for(summary, observation.reference)
similarity * observation.signal_quality
}
///|
pub fn cohort_training_load_flag(
observation : CohortObservation,
summary : CohortComparisonSummary,
) -> Bool {
cohort_percentile_for(summary, observation.reference, "training_load") >= 0.85
}
///|
pub fn cohort_recovery_flag(
observation : CohortObservation,
summary : CohortComparisonSummary,
) -> Bool {
cohort_percentile_for(summary, observation.reference, "readiness") <= 0.15
}
///|
pub fn cohort_range_row(range : CohortMetricRange) -> Array[String] {
[
range.metric,
range.sample_count.to_string(),
range.minimum.to_string(),
range.median.to_string(),
range.maximum.to_string(),
range.mean.to_string(),
range.standard_deviation.to_string(),
]
}
///|
pub fn cohort_summary_feature_vector(
summary : CohortComparisonSummary,
) -> Array[Double] {
let result = []
for value in summary.feature_vector {
result.push(value)
}
result.push(summary.comparisons.length().to_double())
result.push(
summary.comparisons
.filter(item => item.flags.length() > 0)
.length()
.to_double(),
)
result
}