Skip to content

Peptide outlier guard and decoupled deff gate - #149

Merged
ammarcsj merged 2 commits into
mainfrom
revision-v5-aggregation-fixes
Oct 1, 2026
Merged

ammarcsj merged 2 commits into
mainfrom
revision-v5-aggregation-fixes

Conversation

@ammarcsj

@ammarcsj ammarcsj commented Oct 1, 2026

Copy link
Copy Markdown
Member
  • Peptide outlier filtering may now only lower a protein's significance, never raise it.
  • residual_decorrelation_tolerance default update
  • New residual_deff_gate_tolerance param, the deff gate no longer uses the pruning tolerance

ammarcsj and others added 2 commits August 21, 2026 14:44
Peptide outlier candidates are flagged on their two-sided p-value, which
carries no direction, while the protein-level aggregation in
sum_and_re_scale_zvalues sums *signed* z-values. Discarding a peptide whose
z-value opposes the protein's direction therefore raises |sum(z)| and lowers
n, making the protein more significant - the opposite of what the filter is
for, and contrary to what its docstring claimed.

apply_peptide_outlier_filtering now delegates each protein to
_filter_and_aggregate_protein, which re-aggregates and, if |z| grew, un-flags
every peptide and restores the unfiltered aggregate. Removing peptides can
now only ever lower a protein's significance.

Verified by replaying both Spectronaut species-mixture benchmarks from their
exported iontrees (the replay reproduces the pipeline's stored per-peptide
is_outlier_peptide flags and gene p-values exactly):

- LargeFC: 1005 of 8595 proteins had their significance inflated, worst case
  46x (p 0.945 -> 0.021). All were unregulated background. The sets of
  significant proteins are identical before and after this change at 5%, 1%
  and 0.1% FDR, and the empirical FDR is unchanged at 3.30%.
- SmallFC: 189 of 10634 affected, worst case 37222x. 7 of 1337 significant
  proteins are lost (0.5% at 5% FDR), all spiked-in true positives that
  reached significance through the removal of a single peptide. Empirical FDR
  unchanged at 1.50%.
- No protein gains significance at any threshold in either dataset, and the
  mechanism never rendered an unregulated protein significant.

A sign-aware variant (drop only candidates concordant with the protein) was
tested and rejected: it is worse than no fix at all, because the discordant
candidate that is then retained keeps inflating the aggregate once its
concordant partner has been removed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
residual_decorrelation_tolerance default 0.10 -> 0.08.
New residual_deff_gate_tolerance (default 0.05): the deff gate no longer uses
the pruning tolerance. None restores the old coupled behaviour.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ammarcsj
ammarcsj merged commit 5915974 into main Oct 1, 2026
4 checks passed
@ammarcsj
ammarcsj deleted the revision-v5-aggregation-fixes branch October 1, 2026 06:05
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