Skip to content

Land the phased Xbar/S stack on main (#149–#152) - #153

Merged
cnicholas merged 6 commits into
mainfrom
feat/phased-xmr-phase-stats
Oct 18, 2026
Merged

cnicholas merged 6 commits into
mainfrom
feat/phased-xmr-phase-stats

Conversation

@cnicholas

Copy link
Copy Markdown
Owner

Lands the phased Xbar/S stack on main. #149, #150, #151 and #152 were merged in quick succession after #148, but their bases were still the stacked branches (the #148 branch was not deleted, so GitHub never retargeted them), so each merged into the branch below it and none reached main. This branch is the top of that chain: it contains every commit and merge of #149 through #152, on top of the #148 commit main already has.

Contents (already reviewed in the four PRs)

Verification

No new code. Merge with a merge commit, as the others were.

cnicholas and others added 6 commits October 18, 2026 18:19
…ed paths (#144)

The global and stratified Xbar/S builders carried the same aggregation, fit and
limit code twice. It now lives in five helpers (_aggregate_subgroups,
_fit_xbar_group, _apply_xbar_limits, _apply_s_limits, _subgroup_label_column),
the lane-divider label rule is its own function (_lane_labels), and
calculate_limits_vectorized accepts a sigma-hat per row. Phased Xbar/S (#144)
is N per-stage charts on one axis, each one exactly the per-stratum estimator;
with the estimator extracted the feature adds a loop, not arithmetic.

No behaviour change. validation/xbar_s_sweep.py (new) fingerprints 504 Xbar/S
requests on T100 PM SDS 1 and 3 and prints identical output before and after;
golden masters untouched; gate 1547 passed, 0 failed, 4 pending.
execute(chart='Xbar' | 'S', phased=True) gives each factor combination its own
centre line and limits on one chart, drawn as stepped lines with a labelled
divider at each change, as phased X/mR does for its lanes. Each phase is
computed as the per-condition chart of by=[time] computes one stratum: the
mean of its subgroup means as centre, its own S-bar and sigma-hat, its own
limits (10-12 manual Eqs 11-5, 11-8, 11-9, 11-16, 11-17). With other factors
pooled into the subgroup (by=['stage', time]) the centre is the mean of the
pooled subgroup averages, as Dr. Bishop specified on 2026-10-18. On Wheeler's
four-cavity thickness data the per-cavity centres and limits match Minitab's
staged Xbar-S chart to the digit.

New result.phase_statistics(chart); chart data and chart_table gain a phase
column; metadata carries phase_by, lane_boundaries, single_point_phases and
insufficient_phases. by=[time], residual values and calibrations are refused
with messages that say what to use instead. phased=False output is unchanged
(validation/xbar_s_sweep.py: 0 differing lines); gate 1547 / 0 / 4; full
suite 2628 passed.
… factor (#144)

The canonical row order in build_keys sorted the raw factor labels, so a stage
column with categories before < after gave Xbar/S subgroups in that order (the
aggregation groups on the factor column) but X/mR lanes, phases and strata in
the order after, before. The canonical sort now uses an ordered Categorical's
category codes. Every other input sorts exactly as before: the parallel key is
built only when an ordered Categorical is present (xbar_s_sweep: 0 differing
lines; golden masters untouched; gate 1547 / 0 / 4; full suite 2638 passed).
Phased X and mR charts gain what phased Xbar/S got: a phase column (the lane
label) on the chart data and in chart_table, and result.phase_statistics(chart)
with one row per phase (phase, points, center, mR_bar, lpl, upl). A stratified
phased chart keeps one table per stratum, read with stratum= or through
focus(). The companion mR of a phased X chart now reports single_point_phases,
which only the solo mR did.

Output additions only: the per-phase arithmetic, row order, limits and signals
are unchanged, and phased=False charts are untouched (xbar_s_sweep: 0 differing
lines; gate 1547 / 0 / 4; full suite 2633 passed).
…rder

X/mR lane order honours an ordered Categorical factor (#144, PR 4)
@cnicholas
cnicholas merged commit 1c7883f into main Oct 18, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant