refactor(PR4): model→AnnData streamline (to_anndata, predict; retire tcri_manager) - #33
Merged
Merged
Conversation
Fresh py3.12 venv resolves the latest scverse stack (anndata 0.13.1, scanpy 1.12.2, scvi-tools 1.5.0, torch 2.13, numpy 2.4, pandas 3.0.3); pinned in requirements.txt. Fix a legacy tcri_boxplot groupby.median() call that pandas 3.0 rejects (numeric_only must be Boolean) — select the column first. Suite 36 passed / 1 skipped in the new env. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…manager stash) Phase 4 core (behavior change; the gate is the rewritten round-trip test): - TCRIModel.setup_anndata: keyword-only, returns None, drops the uns[tcri_manager] stash (registration only; no analysis/label obs mutation). - TCRIModel.predict (renamed from get_cell_phenotype_probs): returns a labelled DataFrame (obs_names x phenotypes), eval() for deterministic inference. - TCRIModel.to_anndata (replaces preprocessing.register_model): writes the canonical key set incl. the new GATE_PROB + CLASSIFIER_TEMPERATURE (+ raw P_CT, local_scale, logits, log-posterior, probabilities via predict, argmax labels). - Delete register_model / register_phenotype_key / register_clonotype_key / _compute_logits_and_prior (folded); write_adata_safely / _pop_nonserializables (inlined into save_tcri_session). Repoint fixture + tests. - Rewrite test_session_round_trip: canonical write-set, setup-obs invariant, reloaded model reproduces p_ct/latent/predict (fresh-fixture owns the global pyro store). - Onboard the 6 TCRIModel methods into the contract (_contract.pyi + IMPLEMENTED); conformance green. Suite 38 passed / 1 skipped in the pinned venv. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tick the Phase-4 removal ledger (register cluster + write helpers + tcri_manager retired; legacy tcri_*_key deferred to Phase 6/7 with their readers). Add the Model knob-test matrix (every constructor/train knob -> its mathematically-correct input/output test or a justification) and the correctness-debt note: the phenotype classifier and phenotype_weights are dead (no gradient path) — fix + their tests scheduled for a dedicated PR before Phase 6. gitignore dev/ (local-only harness). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR4 audit (workflow, 4 lenses incl. dedicated knob-test-plan lens; 23 agents): 19 confirmed, 0 refuted, all LOW/MED. Correctness lens independently confirmed the streamline is behavior-preserving (44 passed) + both dead-knob findings. Fixed: value-equality assertions for LOCAL_SCALE/GATE_PROB/CLASSIFIER_TEMPERATURE in the round-trip; pyro.clear_param_store() in the trained_model fixture; requirements count 36->44; api-doc to_anndata reconciled to the frozen contract; 7 knob-matrix corrections (Dirichlet variance is 1/(scale+1) not 1/scale; classifier_dropout is a separate un-plumbed knob; gate=1 formula testable now; guide_temperature needs post-train; co-located scale tests; sharper training-knob justifications). Deferred LOW/MED items logged in REFACTOR_NOTES. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #32 (PR3). Base =
refactor/pr3-model-split.Model→AnnData streamline (Phase 4) — behavior change. Retires the
uns['tcri_manager']hack, foldsregister_modelintomodel.to_anndata, renamesget_cell_phenotype_probs → predict(labelled DataFrame), and rewrites the round-trip gate. Full suite 44 passed in the pinned venv.Environment (prerequisite, this round)
Fresh py3.12 venv on the latest scverse stack — anndata 0.13.1, scanpy 1.12.2, scvi-tools 1.5.0, torch 2.13, numpy 2.4, pandas 3.0.3 — pinned in
requirements.txt; all runs use.venv. One pandas-3.0 compat fix in legacytcri_boxplot(groupby.median()positionalnumeric_only).Model surface
setup_anndata: keyword-only, returnsNone, registration-only — nouns['tcri_manager']stash, no analysis/labelobsmutation.predict(wasget_cell_phenotype_probs): labelledDataFrame(obs_names × phenotypes),eval()for deterministic inference, gate-aware.to_anndata(replacesregister_model): writes the canonical set incl. the newGATE_PROB+CLASSIFIER_TEMPERATURE(+P_CT, ct maps, per-cell arrays,LOCAL_SCALE,X_TCRI/X_LOGITS/X_LOGPOSTERIOR/X_PROBABILITIESfrompredict, argmax labels).register_model/register_phenotype_key/register_clonotype_key/_compute_logits_and_prior;write_adata_safely/_pop_nonserializables(h5ad write inlined). The 6TCRIModelmethods onboarded into the frozen contract — conformance now enforces the model surface.Round-trip gate
Rewritten
test_session_round_trip: canonical write-set · setup-obs invariant · reloaded model reproducesp_ct/latent/predict(a function-scoped fixture owns the process-global pyro param store, §5.2).The phenotype classifier is never trained —
cls_logitsis computed inmodel()but never enters any ELBO factor, and the training plan only touches it underno_grad(verified: weight Δ = 0.0, isolatedgate=1.0recovery = chance). End-to-endpredictrecovers perfectly on a perfect dataset, but entirely via the priorp_ct.phenotype_weights/class_weightsis dead for the same reason. Per direction, this is tracked in the agenda (Model knob-test matrix + correctness-debt note) for a dedicated fix PR before Phase 6 — not touched here.Tests
dev/real_data_to_anndata.py— LOCAL-only (gitignored, not CI): builds the 50 largest patient-specific yost clones (trb_unique = trb+patient; 7682 cells / 10 patients) → setup→train→to_anndata.Deferred (logged in REFACTOR_NOTES)
Legacy
tcri_clone_key/tcri_phenotype_key/X_tcri_phenotypesretire in Phase 6/7 (live readers in not-yet-refactored metrics/plotting). Classifier-training fix → dedicated PR.Audit
A workflow audit ran on this branch — 4 lenses (doc↔code · behavior/correctness · plan/contract · a dedicated knob-test-plan lens), each finding adversarially verified (23 agents). 19 findings confirmed, 0 refuted — all LOW/MED, zero HIGH. The correctness lens independently confirmed the streamline is behavior-preserving (44 passed) and reproduced both dead-knob findings.
Fixed in this branch: value-equality assertions for
LOCAL_SCALE/GATE_PROB/CLASSIFIER_TEMPERATURE;pyro.clear_param_store()in thetrained_modelfixture; requirements count; api-docto_anndatareconciled to the frozen contract; and 7 knob-matrix corrections — the Dirichlet draw-variance is∝ 1/(scale+1)(not1/scale);classifier_dropoutis a separate un-plumbed knob (never forwarded to the classifier); gate=1's formula is testable now (only recovery is blocked);guide_temperatureneeds a post-train test; scale-variance tests co-located;kl_weight_max/reconstruction_loss_scale/use_enumerationjustifications sharpened.Deferred (LOW/MED, logged in
REFACTOR_NOTES): thegroup_singletons-ordering guard,predictorder-preservation hardening, round-trip key-exclusivity (Phase 6/7), and a stale depgraph doc-generator.Stacked so the diff shows only PR4's changes. Living agenda + audit log + knob-test matrix:
docs/contract/REFACTOR_AGENDA.md.🤖 Generated with Claude Code