/** * Transition fidelity labels, binned from structural similarity * (see the pipeline's step 10b): * sim ≥ 0.95 identical · 0.70–0.95 low · 0.50–0.70 medium · ≤ 0.50 high * "Fidelity" grows with the size of the conformational change. */ export const FIDELITY_ORDER = ['identical', 'low', 'medium', 'high'] as const; export const FIDELITY_INFO: Record = { identical: { label: 'Identical', range: 'similarity ≥ 0.95', blurb: 'Same conformation' }, low: { label: 'Low', range: '0.70 – 0.95', blurb: 'Subtle rearrangement' }, medium: { label: 'Medium', range: '0.50 – 0.70', blurb: 'Clear conformational change' }, high: { label: 'High', range: 'similarity ≤ 0.50', blurb: 'Large-scale transition' }, NA: { label: 'N/A', range: 'not computable', blurb: 'Similarity unavailable' }, }; export function fidelityKey(f: string | null | undefined): string { if (!f || f === '' || f === 'NA') return 'NA'; return f in FIDELITY_INFO ? f : 'NA'; } export function fidelityColor(f: string | null | undefined): string { return `var(--fid-${fidelityKey(f) === 'NA' ? 'na' : fidelityKey(f)})`; } export function fidelityRank(f: string | null | undefined): number { const i = (FIDELITY_ORDER as readonly string[]).indexOf(fidelityKey(f)); return i === -1 ? -1 : i; } /** Heatmap color for a similarity in [0, 1] (darker = more similar). */ export function similarityColor(sim: number | null | undefined): string { if (sim == null || !Number.isFinite(sim)) return 'var(--surface-3)'; const steps = [0.5, 0.7, 0.85, 0.95, 0.98]; const idx = steps.findIndex((s) => sim < s); return `var(--seq-${idx === -1 ? 5 : idx})`; }