Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions client/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export interface SiteSummary {
site_num: number;
n_events: number;
n_hits: number;
n_no_hit: number;
n_ambiguous: number;
}
// Raw (unbinned) distribution values backing the dashboard's native charts —
// a live modernisation of PanDDA1's pandda_analyse.html graphs. The client
Expand Down
48 changes: 45 additions & 3 deletions client/src/components/InspectDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import ViewInArIcon from "@mui/icons-material/ViewInAr";
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import CancelIcon from "@mui/icons-material/Cancel";
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
import BuildCircleIcon from "@mui/icons-material/BuildCircle";
import NavigateBeforeIcon from "@mui/icons-material/NavigateBefore";
import NavigateNextIcon from "@mui/icons-material/NavigateNext";
Expand Down Expand Up @@ -1436,6 +1438,14 @@ export function InspectDrawer({
const nHits = g.events.filter(
(e) => e.decision === "hit"
).length;
// How many events here have a human decision (any of
// hit/no_hit/ambiguous) vs are still unreviewed — so while
// scanning sites you can see which still need analysing.
// A "built"/"hit" badge alone made a partly-done site look
// fully analysed (Erin's feedback); this corrects it.
const nReviewed = g.events.filter(
(e) => e.decision !== "unreviewed"
).length;
const built = isAutobuilt(g.events);
const candidate = !built && hasCandidatePose(g.events);
const topQ = bestQuality(g.events);
Expand All @@ -1450,6 +1460,27 @@ export function InspectDrawer({
}`}
/>
</Tooltip>
{nEvents > 0 && (
<Tooltip
title={
nReviewed < nEvents
? `${nEvents - nReviewed} event${
nEvents - nReviewed === 1 ? "" : "s"
} still to analyse`
: "All events analysed"
}
arrow
>
<Chip
size="small"
variant="outlined"
color={
nReviewed < nEvents ? "warning" : "success"
}
label={`${nReviewed}/${nEvents} analysed`}
/>
</Tooltip>
)}
{built && (
<Tooltip
title={
Expand Down Expand Up @@ -1664,14 +1695,25 @@ export function InspectDrawer({
isLive ? "warning" : decisionColour(ev.decision)
}
icon={
// Icon = DECISION status first, so no_hit and
// ambiguous are legible (they previously shared the
// generic view icon → looked unreviewed). Build
// status is still conveyed by the chip border (sx
// below), so we don't need the build icon once a
// decision exists. Order: loading > decision >
// build (undecided) > unreviewed.
loadingId === ev.id ? (
<CircularProgress size={14} />
) : ev.decision === "hit" ? (
<CheckCircleIcon />
) : ev.decision === "no_hit" ? (
<CancelIcon />
) : ev.decision === "ambiguous" ? (
<HelpOutlineIcon />
) : poseState !== "none" ? (
// A built/candidate ligand backs this event —
// flag it with the build icon (solid for
// merged, outlined-tint for candidate via sx).
// Undecided but a built/candidate ligand backs
// it — flag with the build icon (solid=merged,
// dashed-tint=candidate via sx).
<BuildCircleIcon />
) : (
<ViewInArIcon />
Expand Down
42 changes: 35 additions & 7 deletions client/src/components/SummaryCharts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,41 @@ export function SummaryCharts({
distributions: Distributions;
sites: SiteSummary[];
}) {
// Events-per-site bar (replaces PanDDA1's analyse_events_site_N pies); hits
// overlaid as a second series so curation progress reads off the same axis.
// Events-per-site, STACKED by decision (replaces PanDDA1's
// analyse_events_site_N pies). One bar per site whose total height is the
// event count, segmented into hit / no-hit / ambiguous / unreviewed — so
// curation progress AND the decision mix read off the same axis, and no-hit /
// ambiguous are visible (they weren't on the old Events+Hits overlay). Colours
// mirror the event-chip decision semantics. Unreviewed = events minus decided.
const siteData = useMemo(
() => ({
labels: sites.map((s) => `Site ${s.site_num}`),
datasets: [
{
label: "Events",
data: sites.map((s) => s.n_events),
backgroundColor: "#90caf9",
},
{
label: "Hits",
data: sites.map((s) => s.n_hits),
backgroundColor: "#66bb6a",
stack: "decisions",
},
{
label: "No-hit",
data: sites.map((s) => s.n_no_hit),
backgroundColor: "#ef5350",
stack: "decisions",
},
{
label: "Ambiguous",
data: sites.map((s) => s.n_ambiguous),
backgroundColor: "#ffb74d",
stack: "decisions",
},
{
label: "Unreviewed",
data: sites.map((s) =>
Math.max(0, s.n_events - s.n_hits - s.n_no_hit - s.n_ambiguous)
),
backgroundColor: "#e0e0e0",
stack: "decisions",
},
],
}),
Expand Down Expand Up @@ -152,6 +172,14 @@ export function SummaryCharts({
options={{
...CHART_OPTS,
plugins: { legend: { display: true } },
scales: {
x: { stacked: true },
y: {
stacked: true,
beginAtZero: true,
ticks: { precision: 0 },
},
},
}}
/>
</Box>
Expand Down
6 changes: 6 additions & 0 deletions inspect_api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,12 @@ def _rd_vals(fld):
"n_hits": se.filter(
finding__decision=Event.Decision.HIT
).count(),
"n_no_hit": se.filter(
finding__decision=Event.Decision.NO_HIT
).count(),
"n_ambiguous": se.filter(
finding__decision=Event.Decision.AMBIGUOUS
).count(),
})
return {
"analysed": n_events > 0,
Expand Down
Loading