hydropd / website /src /components /ConditionMatcher.tsx
rikardsaqe's picture
Upload folder using huggingface_hub
47bb217 verified
Raw
History Blame Contribute Delete
4.62 kB
import { useMemo } from 'react'
import { MODELS, displayAuroc } from '../data/models'
import {
rankModels,
distinctEnzymes,
distinctProtocols,
distinctSpecies,
type Conditions,
} from '../lib/rankModels'
interface ConditionMatcherProps {
conditions: Conditions
onChange: (c: Conditions) => void
onPick: (code: string) => void // set the active model
selected: string // active model code (to highlight)
}
// Let the user describe how their peptides were generated (species / enzyme / MS
// protocol) and rank the models by condition similarity, species first, then
// enzyme, then protocol. The top matches are offered as one-click model choices.
export default function ConditionMatcher({
conditions,
onChange,
onPick,
selected,
}: ConditionMatcherProps) {
const enzymes = useMemo(() => distinctEnzymes(MODELS), [])
const protocols = useMemo(() => distinctProtocols(MODELS), [])
const species = useMemo(() => distinctSpecies(MODELS), [])
const anySet = !!(conditions.species || conditions.enzyme || conditions.protocol)
const ranked = useMemo(
() => (anySet ? rankModels(MODELS, conditions) : []),
[conditions, anySet],
)
const top = ranked.slice(0, 3)
return (
<div className="field">
<div className="field-label">
Match my conditions{' '}
<span className="field-hint">
How were your peptides made? We rank models by species, then enzyme, then protocol.
</span>
</div>
<div className="cond-selects">
<label className="cond-select">
<span>Species</span>
<select
value={conditions.species ?? ''}
onChange={(e) => onChange({ ...conditions, species: e.target.value || undefined })}
>
<option value="">Any</option>
{species.map((s) => (
<option key={s.key} value={s.key}>
{s.label}
</option>
))}
<option value="other">Other</option>
</select>
</label>
<label className="cond-select">
<span>Enzyme</span>
<select
value={conditions.enzyme ?? ''}
onChange={(e) => onChange({ ...conditions, enzyme: e.target.value || undefined })}
>
<option value="">Any</option>
{enzymes.map((x) => (
<option key={x} value={x}>
{x}
</option>
))}
<option value="other">Other</option>
</select>
</label>
<label className="cond-select">
<span>MS protocol</span>
<select
value={conditions.protocol ?? ''}
onChange={(e) => onChange({ ...conditions, protocol: e.target.value || undefined })}
>
<option value="">Any</option>
{protocols.map((x) => (
<option key={x} value={x}>
{x}
</option>
))}
<option value="other">Other</option>
</select>
</label>
</div>
{anySet && (
<div className="cond-ranked">
<div className="muted" style={{ fontSize: 'var(--text-xs)', fontWeight: 600, margin: '4px 0' }}>
Best-matched models
</div>
{top.map((m, i) => {
const on = selected === m.code
return (
<button
key={m.code}
type="button"
className={'cond-rank-row' + (on ? ' selected' : '')}
onClick={() => onPick(m.code)}
title="Use this model"
>
<span className="cond-rank-pos">#{i + 1}</span>
<span className="cond-rank-body">
<span className="cond-rank-title">
<span className="mono">{m.code}</span> · {m.species} · {m.enzyme}
</span>
<span className="cond-rank-tags">
<span className={'tag' + (m.speciesMatch ? ' tag-on' : '')}>species</span>
<span className={'tag' + (m.enzymeMatch ? ' tag-on' : '')}>enzyme</span>
<span className={'tag' + (m.protocolMatch ? ' tag-on' : '')}>protocol</span>
<span className="muted" style={{ fontSize: 'var(--text-xs)' }}>
AUROC {displayAuroc(m)}
</span>
</span>
</span>
{on && <span className="badge badge-good">Selected</span>}
</button>
)
})}
</div>
)}
</div>
)
}