hydropd / website /src /lib /rankModels.ts
rikardsaqe's picture
Upload folder using huggingface_hub
47bb217 verified
Raw
History Blame Contribute Delete
2.61 kB
// Condition-aware model ranking (client-side mirror of backend/ranking.py).
//
// Given the conditions a user's peptides were generated under, species, enzyme,
// MS protocol, rank the models by how similar their training conditions were.
// Concise, generalizable rule: species dominates, then enzyme, then protocol, each
// only when supplied and matched. Weighted score (species 100 > enzyme 10 > protocol
// 1) so the order is exactly "same species first; among those same enzyme; among
// those same protocol"; ties broken by the model's own AUROC.
import { displayAurocValue, type RealModel } from '../data/models'
export interface RankedModel extends RealModel {
rankScore: number
speciesMatch: boolean
enzymeMatch: boolean
protocolMatch: boolean
}
const norm = (x: string | null | undefined): string => (x ?? '').trim().toLowerCase()
// Loose equality: exact, or one contains the other (handles "trypsin" vs "trypsin
// then flavourzyme", "nano-LC-MS/MS" vs "LC-MS/MS").
function match(a: string, b: string): boolean {
return !!a && !!b && (a === b || a.includes(b) || b.includes(a))
}
export interface Conditions {
species?: string
enzyme?: string
protocol?: string
}
export function rankModels(models: RealModel[], c: Conditions): RankedModel[] {
const s = norm(c.species)
const e = norm(c.enzyme)
const p = norm(c.protocol)
return models
.map((m) => {
const sp = match(s, norm(m.speciesKey) || norm(m.species))
const en = match(e, norm(m.enzyme))
const pr = match(p, norm(m.msProtocol))
return {
...m,
rankScore: 100 * (sp ? 1 : 0) + 10 * (en ? 1 : 0) + 1 * (pr ? 1 : 0),
speciesMatch: sp,
enzymeMatch: en,
protocolMatch: pr,
}
})
.sort(
(a, b) =>
b.rankScore - a.rankScore ||
(displayAurocValue(b) ?? 0) - (displayAurocValue(a) ?? 0),
)
}
// Distinct, sorted option lists for the condition selectors (built from the models).
export function distinctEnzymes(models: RealModel[]): string[] {
return [...new Set(models.map((m) => m.enzyme).filter(Boolean))].sort()
}
export function distinctProtocols(models: RealModel[]): string[] {
return [...new Set(models.map((m) => m.msProtocol).filter(Boolean))].sort()
}
export function distinctSpecies(models: RealModel[]): { key: string; label: string }[] {
const seen = new Map<string, string>()
for (const m of models) if (!seen.has(m.speciesKey)) seen.set(m.speciesKey, m.species)
return [...seen.entries()]
.map(([key, label]) => ({ key, label }))
.sort((a, b) => a.label.localeCompare(b.label))
}