frontend: show calibration progress and relabel Pedestal as Calibration

The status-bar pill only filled a progress bar during the Measuring state,
even though the receiver already reports a real progress value during
pedestal/mask calibration. Render the same bar for the Pedestal state
(filled coral to match its pill colour), and relabel the state and its
button as "Calibration"/"CALIBRATE". The internal state value stays
"Pedestal" and the /pedestal endpoint is unchanged for back-compatibility.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-13 11:40:30 +02:00
co-authored by Claude Opus 4.8
parent d891551127
commit 069b00349f
2 changed files with 13 additions and 9 deletions
+1
View File
@@ -10,6 +10,7 @@ This is an UNSTABLE release. It includes many experimental features, as well as
* rugnux: `--model` validation now aligns the data to the model before scoring - the observed reflections are reindexed into the model's enantiomorph when the two differ only by hand (indistinguishable from merged intensities). A merohedral indexing ambiguity is resolved against the reference MTZ when one is given (so a whole campaign shares one indexing convention); only with a model and no reference does validation fall back to fitting each candidate reindexing and keeping the lowest R-free.
* rugnux: De-novo symmetry - recover a genuine high-symmetry group whose data are imperfectly scaled. Such a merge's within-orbit chi² lands just past the self-consistency bound (each real symmetry step adds a little systematic scatter), right where a merohedral twin also lands, so the chi² ratio alone cannot separate them. The candidate is now rescued when the extra intensity-proportional systematic error it invokes stays small relative to the confirmed subgroup - a genuine symmetry step gains multiplicity without inflating the merge error model's b, whereas a twin forces non-equivalent reflections together and b balloons. Fixes cubic insulin (I23 instead of I222) with no change to any other crystal in the test battery, including the twins that must stay in their lower symmetry.
* Docs: Document the French-Wilson amplitude estimation, R-free flagging, reference-based space-group/ambiguity resolution, and model-based validation/maps in CPU_DATA_ANALYSIS.md.
* Frontend: The status-bar pill now shows a progress bar during detector calibration (previously only during measurement), and the calibration state and its button are labelled "Calibration"/"CALIBRATE" (the internal `Pedestal` state name is unchanged for back-compatibility).
### 1.0.0-rc.158
This is an UNSTABLE release. It includes many experimental features, as well as many AI generated fixes. We recommend using rc.152 for production use.
+12 -9
View File
@@ -17,16 +17,15 @@ type MyProps = {
}
// A tight, strong palette: lime = good/running, coral = working/alarm (deeper = worse),
// light-blue (sidebar) = neutral/idle-connection. Measuring is handled separately.
// light-blue (sidebar) = neutral/idle-connection. Measuring and Pedestal are handled separately.
const STATE_STYLE: Record<string, { fill: string; text: string }> = {
Idle: { fill: "secondary.main", text: "rgba(0,0,0,.87)" }, // lime + black text
Busy: { fill: deepOrange[300], text: "rgba(0,0,0,.87)" }, // light coral
Pedestal: { fill: deepOrange[300], text: "rgba(0,0,0,.87)" }, // light coral
Error: { fill: deepOrange[700], text: "#fff" }, // deep coral
Inactive: { fill: indigo[100], text: "rgba(0,0,0,.87)" }, // sidebar light blue
};
// Fixed width so the pill fits the longest label ("Measuring · 100 %") and never
// Fixed width so the pill fits the longest label ("Calibration · 100 %") and never
// resizes as the state changes.
const pillSx = {
position: "relative", width: 200, height: 36, borderRadius: 999, overflow: "hidden",
@@ -57,16 +56,20 @@ function StatusChip({s}: {s?: broker_status}) {
</Box>
);
// Measuring: a light-blue (sidebar) track filled lime to the progress fraction,
// with black text that stays legible over both the track and the lime fill.
if (s.state === "Measuring") {
// Measuring and Pedestal both fill a light-blue (sidebar) track to the progress
// fraction, with black text legible over both track and fill. Measuring fills lime;
// Pedestal fills coral (matching its flat-pill colour elsewhere). The "Pedestal"
// state is shown as "Calibration" — the internal name is kept only for back-compat.
if (s.state === "Measuring" || s.state === "Pedestal") {
const pct = Math.max(0, Math.min(100, (s.progress ?? 0) * 100.0));
const fill = s.state === "Measuring" ? "secondary.main" : deepOrange[300];
const label = s.state === "Measuring" ? "Measuring" : "Calibration";
return (
<Box sx={{...pillSx, bgcolor: indigo[100]}}>
<Box sx={{position: "absolute", left: 0, top: 0, bottom: 0, width: `${pct}%`,
bgcolor: "secondary.main", transition: "width .4s ease"}}/>
bgcolor: fill, transition: "width .4s ease"}}/>
<Typography component="span" sx={{...pillLabelSx, color: "rgba(0,0,0,.87)"}}>
Measuring · {pct.toFixed(0)} %
{label} · {pct.toFixed(0)} %
</Typography>
</Box>
);
@@ -114,7 +117,7 @@ function StatusBar({s, onMenuClick}: MyProps) {
{...TIER[cancelTier]}
/>
<ButtonWithSnackbar
text={"Pedestal"}
text={"Calibrate"}
path={"/pedestal"}
disabled={!pedestalActive}
{...(pedestalActive ? TIER.active : TIER.off)}