Claude
Skills
Sign in
Back

bio-immunoinformatics-immunogenicity-scoring

Included with Lifetime
$97 forever

Rank and prioritize neoantigen/epitope candidates by likely T-cell response using NeoFox feature annotation, PRIME2.0, BigMHC-IM, the Łuksza/Balachandran fitness model (agretopicity + foreignness), and pVACtools tiering. Encodes the field's hard truths that immunogenicity is the least-solved layer (dedicated scores ~AUROC 0.6-0.7, modest PPV), that scores are valid only for RANKING within one patient (never absolute go/no-go or cross-patient), that DAI has anchor-inflation and WT-denominator traps, and that stacking weak correlated scores into one number is a red flag. Use when ordering a candidate list for a vaccine. Binding lives in mhc-binding-prediction; calling in neoantigen-prediction.

General

What this skill does


## Version Compatibility

Reference examples tested with: NeoFox 1.0+, pVACtools 4.1+, pandas 2.2+, numpy 1.26+

Before using code patterns, verify installed versions match. If versions differ:
- Python: `pip show <package>` then `help(module.function)` to check signatures
- CLI: `<tool> --version` then `<tool> --help` to confirm flags

If code throws ImportError, AttributeError, or TypeError, introspect the installed
package and adapt the example to match the actual API rather than retrying.

Notes specific to this skill: NeoFox annotates ~16 published features (it does not rank candidates automatically); PRIME 2.x requires MixMHCpred v3.0+ on PATH; BigMHC has separate `-m el` and `-m im` heads. ImmunoBERT is a PRESENTATION model, not an immunogenicity predictor — do not use it here. PRIME2.0 is the *Cell Systems* 2023 paper (the *Cell Reports Medicine* 2021 paper is PRIME v1). Re-verify tool versions and the supported-allele lists before scoring.

# Immunogenicity Scoring

**"Rank my neoantigen candidates by how likely a T cell responds"** -> Annotate presentation + recognition features and order candidates within a patient; never assign an absolute immunogenicity verdict.
- Python: `NeoFox` to compute the published feature panel; `PRIME` / `BigMHC -m im` for recognition scores
- CLI: pVACtools aggregate-report tiering as the auditable, rule-based default ranking

## The Single Most Important Modern Insight -- this is the least-solved layer; rank within a patient, never threshold

Binding/presentation is genuinely good (AUROC high-0.9s); immunogenicity is not close. Predicting whether a displayed peptide provokes a T-cell response requires knowing whether a cognate TCR exists in this patient's repertoire, whether that clone survived thymic negative selection (escaped tolerance), and whether it activates in a suppressive tumor microenvironment — none observable from sequence. Dedicated immunogenicity tools land around AUROC 0.6-0.7 on their own test sets and worse on independent data; in TESLA the dedicated in-silico immunogenicity scores correlated poorly with validated immunogenicity, while presentation strength, binding stability, abundance/expression, agretopicity, and foreignness carried the signal. Two operational rules follow. First, immunogenicity scores are calibrated within a context (a tool, an allele, often a patient's HLA), so they are legitimate for ordering one patient's candidate list and illegitimate for absolute go/no-go or cross-patient/cross-allele comparison. Second, a confident single composite number is a red flag: stacking weak, correlated, IEDB-bias-trained scores into one value launders the bias at higher apparent precision. The honest deliverable is an ordered, feature-annotated shortlist with its uncertainty stated out loud.

## Why "Best Binder" Lost to "Best Quality"

The best-binder heuristic fails on a tolerance argument: a peptide that binds MHC superbly but closely resembles a self-peptide the thymus presented has had its cognate T cells deleted, so display does not help. A moderate binder that looks strikingly un-self may have a full, un-tolerized repertoire. The modern requirement is conjunctive — a useful neoantigen must be both PRESENTED (binding) AND FOREIGN enough (different from self) to have escaped tolerance. The Łuksza/Balachandran fitness model formalizes this: quality = amplitude (how much better the mutant is presented than its WT, a DAI-like term) x recognition potential R (resemblance to known immunogenic foreign epitopes). This is why agretopicity and foreignness, not raw affinity, recur in every validated analysis.

## Tool Taxonomy

| Tool | Citation | What it scores | Note |
|------|----------|----------------|------|
| NeoFox | Lang 2021 | ~16 features at once (DAI, foreignness, dissimilarity, PRIME, PHBR, ...) | Annotates, does NOT rank — the right division of labor |
| pVACtools tiering | Hundal 2020 | Rule-based tiers + within-tier sort | Auditable default; quarantines anchor/subclonal traps |
| PRIME2.0 | Gfeller 2023 | Class I immunogenicity (presentation x TCR-recognition) | Strong; needs MixMHCpred v3.0+ |
| BigMHC-IM | Albert 2023 | Class I immunogenicity (transfer-learned) | High precision; pan-allelic |
| IEDB immunogenicity | Calis 2013 | Class I (AA + position) | Weak, allele-pooled, no self-comparison; one feature only |
| DeepImmuno | Li 2021 | Class I CNN | 9/10mer only; limited alleles |
| fitness model (foreignness) | Łuksza 2017; Balachandran 2017 | Quality = amplitude x recognition | The conceptual backbone |

## Decision Tree by Scenario

| Scenario | Recommended | Why |
|----------|-------------|-----|
| Default: rank a patient's candidates | NeoFox features -> pVACtools tiering -> human curation | Transparent features + auditable tiers, not a black-box score |
| Need a single recognition score | PRIME2.0 or BigMHC-IM | Best-validated class I; report alongside features, not alone |
| "Is this one immunogenic, yes/no?" | Reframe to ranking | No honest tool gives an absolute verdict |
| CD4 / class II immunogenicity | Flag as a frontier (TLimmuno2 etc.) | Class II immunogenicity is even less solved |
| Final shortlist for synthesis | Feature-annotated table + expression/clonality filters | Presentation + abundance carry most real signal (TESLA) |

## Annotate Features, Then Rank Within Patient

**Goal:** Order one patient's candidates without collapsing fragile features into a single over-trusted number.

**Approach:** Compute the feature panel (NeoFox), apply the non-negotiable expression/clonality filters first, then sort by presentation + abundance + quality features, keeping the features visible side by side for human curation. Cross-patient comparison is invalid.

```python
import pandas as pd

def rank_within_patient(df, expr_col='gene_expression', vaf_col='rna_vaf'):
    '''Filter (not score) on expression/clonality first, then order by presentation,
    abundance, and quality. Returns a feature-annotated table for human curation, not
    a verdict. Scores are within-patient only - never compare across patients/alleles.'''
    keep = df[(df[expr_col] >= 1.0) & (df[vaf_col] >= 0.25)].copy()
    sort_cols = ['presentation_rank', 'gene_expression', 'agretopicity', 'foreignness']
    ascending = [True, False, False, False]
    cols = [c for c in sort_cols if c in keep.columns]
    asc = [a for c, a in zip(sort_cols, ascending) if c in keep.columns]
    return keep.sort_values(cols, ascending=asc)
```

## Compute Agretopicity (DAI) Defensively

**Goal:** Use the mutant-vs-WT binding gain without falling into its two traps.

**Approach:** Agretopicity (ratio, IC50_WT / IC50_MT; the DAI family — Duan 2014 uses the difference form) rewards a mutant that binds while WT does not. Trap 1: an anchor-position mutation inflates it without changing the TCR-facing surface (quarantine via the Anchor tier). Trap 2: when WT binds very poorly, the denominator explodes and the ratio is dominated by prediction noise — a value of 200 on a barely-estimable WT is not 100x more meaningful than a value of 2.

```python
def defensive_dai(df, wt='wt_ic50', mt='mt_ic50', anchor='mutation_at_anchor', wt_cap=5000):
    '''Flag anchor-inflated and denominator-unstable DAI rather than trusting the number.'''
    out = df.copy()
    out['dai'] = out[wt] / out[mt]
    out['dai_anchor_artifact'] = out[anchor]                 # surface unchanged -> DAI is artifact
    out['dai_unstable'] = out[wt] > wt_cap                   # WT barely presented -> ratio is noise
    out['dai_trustworthy'] = ~out['dai_anchor_artifact'] & ~out['dai_unstable']
    return out
```

## Per-Method Failure Modes

### Treating a score as a verdict
**Trigger:** "score > X means immunogenic" or comparing scores across patients. **Mechanism:** scores are calibrated within tool/allele/patient. **Symptom:** false confidence; cross-patient mis-ranking. **Fix:** rank within a patient; state uncertainty; never threshold absolutely.

### 

Related in General