import React, { useState } from 'react'; import { THEME, tempColor, pHColor, saltColor } from '../theme.js'; import { OxygenConfArc, IntervalBar, MediaConfBar, MonoTag, SourceBadge } from './Primitives.jsx'; const PRESETS = [ { id: 'ecoli', name: 'Escherichia coli K-12 MG1655', accession: 'GCF_000005845.2', published: { T_opt: 37, pH: 7.0, salt: 1, O2: 'facultative anaerobe', medium: 'LB (Luria-Bertani)' } }, { id: 'bsub', name: 'Bacillus subtilis 168', accession: 'GCF_000009045.1', published: { T_opt: 30, pH: 7.0, salt: 2, O2: 'facultative anaerobe', medium: 'LB or Nutrient Broth' } }, { id: 'tt', name: 'Thermus thermophilus HB8', accession: 'GCF_000091545.1', published: { T_opt: 70, pH: 7.5, salt: 0.5, O2: 'aerobe', medium: 'DSMZ 74 Castenholz TYE' } }, ]; export default function TestTab() { const [selected, setSelected] = useState(PRESETS[0]); const [result, setResult] = useState(null); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); async function predict(preset) { setSelected(preset); setBusy(true); setError(null); try { const r = await fetch('/api/predict', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ target: preset.accession, top_k: 5 }), }); if (!r.ok) throw new Error(await r.text()); setResult(await r.json()); } catch (e) { setError(String(e.message || e)); } finally { setBusy(false); } } return (
Sanity-check the model on a microbe with published growth conditions.
{PRESETS.map((p) => ( ))}
{busy &&
Predicting…
} {error &&
{error}
} {result && }
); } function CompareCard({ label, pred, lo, hi, pub, unit, color, scaleMin, scaleMax }) { const inInterval = pub >= lo && pub <= hi; const pubPct = ((pub - scaleMin) / (scaleMax - scaleMin)) * 100; return (
{label} {inInterval ? '✓ in 80% PI' : '△ outside PI'}
predicted
{pred.toFixed(1)}{unit}
{lo.toFixed(1)}{unit} – {hi.toFixed(1)}{unit}
published
{pub}{unit}
literature
↑ pub
); } function Comparison({ preset, result }) { const p = result.phenotypes; const pub = preset.published; const T = p.optimal_temperature_c; const pH = p.optimal_ph; const salt = p.salt_tolerance_pct; const O2 = p.oxygen_requirement; const top = result.media?.[0]; return (
Predicted vs published — {preset.name}
{T && } {pH && } {salt && } {O2 && (
Oxygen requirement
{O2.prediction === pub.O2 ? '✓ match' : '△ mismatch'}
predicted
{O2.prediction}
published
{pub.O2}
)}
Top media to try
{result.media?.slice(0, 5).map((m, i) => (
{m.medium_id} {m.name}
{m.recipe && (
{m.recipe}
)}
))}
); }