MedASR-Bench / src /components /model /TopicBreakdown.tsx
ngoan
MedASR Bench: full platform + Hugging Face Docker Space packaging
d70f132
Raw
History Blame Contribute Delete
2.95 kB
import type { ModelRow, Provenance, SplitMetrics } from "@/lib/types";
import SectionLabel from "./SectionLabel";
import TopicChart, { type TopicWer } from "./TopicChart";
export interface TopicBreakdownProps {
model: ModelRow;
}
/** The five ViMedCSS topic domains (ghost state when no breakdown exists). */
const TOPICS = [
"Medical Sciences",
"Pathology & Pathogens",
"Treatments",
"Nutrition",
"Diagnostics",
];
/**
* Per-topic data is an optional forward-compatible extension of
* SplitMetrics (`topics: [{ topic, wer }]`) written by platform runs;
* paper imports never carry it, so we runtime-guard the shape.
*/
function readTopics(metrics?: ModelRow["metrics"]): TopicWer[] | null {
for (const split of ["test", "hard"] as const) {
const m = metrics?.[split] as
| (SplitMetrics & { topics?: unknown })
| undefined;
const t = m?.topics;
if (
Array.isArray(t) &&
t.length > 0 &&
t.every(
(x): x is TopicWer =>
typeof x === "object" &&
x !== null &&
typeof (x as { topic?: unknown }).topic === "string" &&
typeof (x as { wer?: unknown }).wer === "number",
)
) {
return t;
}
}
return null;
}
function gapReason(provenance: Provenance): string {
if (provenance === "running")
return "the pilot run executing now records it per domain";
if (provenance === "planned") return "no run exists yet";
if (provenance === "paper-imported")
return "paper imports report corpus-level scores only";
return "this submission did not include a per-domain breakdown";
}
/**
* Per-topic WER section: recharts horizontal bars when a run recorded the
* breakdown, otherwise an evidence-gap mini-note listing the five domains.
*/
export default function TopicBreakdown({ model }: TopicBreakdownProps) {
const topics = readTopics(model.metrics);
return (
<section className="flex flex-col gap-4">
<SectionLabel
index="04"
title="Per-topic WER"
hint="five ViMedCSS domains"
/>
{topics ? (
<div className="hairline depth-1 rounded-sm bg-surface p-5">
<TopicChart data={topics} />
</div>
) : (
<div className="rounded-sm border border-dashed border-line px-5 py-4">
<p className="max-w-xl text-[13px] leading-relaxed text-muted">
Per-topic WER is unavailable for this row —{" "}
{gapReason(model.provenance)}. Platform-verified runs break WER
down across the five ViMedCSS domains:
</p>
<ul className="mt-3 flex flex-wrap gap-1.5">
{TOPICS.map((t) => (
<li
key={t}
className="num rounded-sm border border-line/70 px-1.5 py-0.5 text-[11px] tracking-wide text-muted"
>
{t}
</li>
))}
</ul>
</div>
)}
</section>
);
}