Skip to content

Add designed-mode panel comparison (factorial ANOVA + Tukey/Dunnett post-hoc)#471

Merged
kgdunn merged 4 commits into
mainfrom
claude/stability-study-analysis-lrk3u0
Jul 24, 2026
Merged

Add designed-mode panel comparison (factorial ANOVA + Tukey/Dunnett post-hoc)#471
kgdunn merged 4 commits into
mainfrom
claude/stability-study-analysis-lrk3u0

Conversation

@kgdunn

@kgdunn kgdunn commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • New module process_improve.sensory.designed: the designed-mode complement to the observational relate, answering "which product treatments differ, and by how much, on each attribute" for a randomized complete block design (the same panelists score every treatment, panelist as the block). The sensory roadmap listed Tukey/LSD post-hoc as a planned item; this fills that gap.
  • Public API, generic in the factor column names: factorial_anova (per-attribute Type III factorial ANOVA score ~ C(f1) * C(f2) * ... + C(block), handling unbalanced grids and factor-by-factor interactions), tukey_hsd (all-pairwise Tukey HSD off the blocked-model error mean square and the studentized-range distribution, with a compact-letter display), dunnett_vs_control (Dunnett two-sided vs one control), and compare_products (orchestrator returning a ComparisonResult; a within= argument runs simple-effects post-hoc within each level of another factor, the right follow-up once an interaction is significant).
  • Built entirely on the existing statsmodels / patsy / scipy runtime dependencies; no new dependency added.

Test plan

  • uv run pytest tests/test_sensory_designed.py --no-cov (11 tests): a synthetic RCBD with planted effects (one high formulation, aging main effect, a formulation-by-condition interaction that collapses one treatment only under one condition) checked against the ANOVA F-tests, Tukey groupings, Dunnett flags and letter display.
  • Numerical cross-check: tukey_hsd p-values match scipy.stats.tukey_hsd on a balanced one-way case to 1e-6.
  • Full sensory suite green (tests/test_sensory.py, test_sensory_end_to_end.py, test_sensory_designed.py): 69 passed.
  • uv run mypy src/process_improve/sensory/designed.py clean; ruff check clean on the new files (project config).

Checklist

  • Version bumped in pyproject.toml (MINOR: new module / API additions), 1.58.0 -> 1.59.0
  • Tests added or updated where relevant
  • ruff check . passes
  • CHANGELOG.md updated (and CITATION.cff version synced)

Generated by Claude Code

…ost-hoc

New module process_improve.sensory.designed complements the observational
relate with the designed-mode question: which product treatments differ, and
by how much, on each attribute, for a randomized complete block design (the
same panelists score every treatment, panelist as the block).

Public API (generic in the factor column names):
- factorial_anova: per-attribute Type III factorial ANOVA
  (score ~ C(factor_1) * C(factor_2) * ... + C(block)), handling unbalanced
  grids and testing factor-by-factor interactions.
- tukey_hsd: all-pairwise Tukey HSD off the blocked-model error mean square
  and the studentized-range distribution, with a compact-letter display.
- dunnett_vs_control: Dunnett two-sided test of each treatment vs one control.
- compare_products: orchestrates the ANOVA + post-hoc tests and returns a
  ComparisonResult; a within= argument runs simple-effects post-hoc within
  each level of another factor.

Built on the existing statsmodels/patsy/scipy dependencies (no new deps).
Tests in tests/test_sensory_designed.py drive a synthetic RCBD with planted
effects and cross-check the Tukey maths against scipy.stats.tukey_hsd. Version
bump 1.58.0 -> 1.59.0 with matching CITATION.cff and CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Ra2KAdJeGtnUzi68yDFaR
@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.39548% with 17 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/process_improve/sensory/designed.py 90.34% 12 Missing and 5 partials ⚠️

📢 Thoughts on this report? Let us know!

claude added 3 commits July 24, 2026 06:47
…xample

Add a "Comparing designed treatments" section to the sensory panel user guide
covering compare_products / factorial_anova / tukey_hsd / dunnett_vs_control,
the randomized-complete-block model, and a worked numerical example that shows
Tukey and Dunnett reaching different (both correct) verdicts on the same
treatment-vs-control comparison. Cross-linked from the designed-versus-
observational section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Ra2KAdJeGtnUzi68yDFaR
ruff 0.16 promoted several rules into the select=["ALL"] set (CPY001, PLR0917,
and others) that fire across the existing code base, turning the lint job red
on every branch. Cap the dev dependency at ruff>=0.11.0,<0.16 (resolves to
0.15.22) so `ruff check .` passes again; the new rules can be triaged
separately before lifting the cap. Version bump 1.59.0 -> 1.59.1 with matching
CITATION.cff and CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Ra2KAdJeGtnUzi68yDFaR
…y-analysis-lrk3u0

# Conflicts:
#	CHANGELOG.md
#	CITATION.cff
#	pyproject.toml
@kgdunn
kgdunn merged commit 499a0be into main Jul 24, 2026
11 checks passed
@kgdunn
kgdunn deleted the claude/stability-study-analysis-lrk3u0 branch July 24, 2026 07:31
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.

2 participants