> ## Documentation Index
> Fetch the complete documentation index at: https://proto.evodesign.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# netMHCpan

> [netMHCpan 4.2](https://services.healthtech.dtu.dk/services/NetMHCpan-4.2/), from DTU Health Tech, predicts which peptides an [MHC class I](https://en.wikipedia.org/wiki/MHC_class_I) molecule presents. Artificial neural networks trained on more than 1,000,000 binding-affinity and mass-spectrometry eluted-ligand peptides score peptides against any MHC molecule of known sequence, including alleles with no measurements of their own. This toolkit wraps a local netMHCpan install, scores the 8-14mers that class I presents, returns the per-allele %rank that makes predictions comparable across alleles, and adds smooth summary metrics suited to use as an optimization target.

![netMHCpan](https://proto-bio.github.io/proto-assets/images/tool/netmhcpan/hero.png)[![](https://mintcdn.com/bio-pro/Bgc19Em8MDwlJakq/assets/images/cached/70810cf4189a.png?fit=max\&auto=format\&n=Bgc19Em8MDwlJakq\&q=85\&s=3ef074dd1b85870a870281cfaf68169a) DHTSB](https://proto.evodesign.org/docs/tools/organizations/dtu-health-tech-section-of-bioinformatics.md) [![](https://mintcdn.com/bio-pro/Bgc19Em8MDwlJakq/assets/images/cached/70810cf4189a.png?fit=max\&auto=format\&n=Bgc19Em8MDwlJakq\&q=85\&s=3ef074dd1b85870a870281cfaf68169a) TUD](https://proto.evodesign.org/docs/tools/organizations/technical-university-of-denmark.md)

Proto is not affiliated with DTU Health Tech, Section of Bioinformatics and Technical University of Denmark. This toolkit is open source and builds on the implementations produced by these organizations. Product names, logos, and trademarks are the property of their respective owners.

***

&#x20;Website Website  Publication Publication  Cite Cite  Tool Source Tool Source  Open as Notebook Open as Notebook  Run Locally Run Locally

&#x20;services.healthtech.dtu.dk

&#x20;Visit website

[Open](https://services.healthtech.dtu.dk/services/NetMHCpan-4.2/)

NetMHCpan-4.2: improved prediction of CD8+ epitopes by use of transfer learning and structural featuresJonas Birkelund Nilsson, Jason Greenbaum, ... Morten NielsenFrontiers in Immunology (2025)

&#x20;Read paper

[Open](https://doi.org/10.3389/fimmu.2025.1616113)

@articlenilsson2025netmhcpan\@articlenielsen2007netmhcpan

```bibtex theme={null}
@article{nilsson2025netmhcpan,
  title={NetMHCpan-4.2: improved prediction of CD8+ epitopes by use of transfer learning and structural features},
  author={Nilsson, Jonas Birkelund and Greenbaum, Jason and Peters, Bjoern and Nielsen, Morten},
  journal={Frontiers in Immunology},
  volume={16},
  pages={1616113},
  year={2025},
  publisher={Frontiers Media SA},
  doi={10.3389/fimmu.2025.1616113}
}

@article{nielsen2007netmhcpan,
  title={NetMHCpan, a Method for Quantitative Predictions of Peptide Binding to Any HLA-A and -B Locus Protein of Known Sequence},
  author={Nielsen, Morten and Lundegaard, Claus and Blicher, Thomas and Lamberth, Kasper and Harndahl, Mikkel and Justesen, Sune and R{\o}der, Gustav and Peters, Bjoern and Sette, Alessandro and Lund, Ole and Buus, S{\o}ren},
  journal={PLoS ONE},
  volume={2},
  number={8},
  pages={e796},
  year={2007},
  publisher={Public Library of Science},
  doi={10.1371/journal.pone.0000796}
}
```

&#x20;Copy citation

![Proto](https://mintcdn.com/bio-pro/cMLt8hAqaP9M3LKy/assets/logo/logo-light.svg?fit=max\&auto=format\&n=cMLt8hAqaP9M3LKy\&q=85\&s=f5e5dfd1b8f9b9db3a0be0e2eb01f678)

evo-design/proto-tools

&#x20;View source

[Open](https://github.com/evo-design/proto-tools/tree/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan)

Open Notebook

&#x20;Open notebook

[Open](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/examples/example.ipynb)

[![proto-tools on GitHub](https://opengraph.githubassets.com/1/evo-design/proto-tools)](https://github.com/evo-design/proto-tools)

Run locally with proto-tools

```bash theme={null}
pip install git+https://github.com/evo-design/proto-tools.git
```

Toolkit contributors[![](https://avatars.githubusercontent.com/u/96268994?v=4\&s=64)Xiaowei0402](https://github.com/Xiaowei0402)

| Function | Description | |
| - | - | - |
| `run_netmhcpan_peptides()` | Predict MHC class I binding for explicit peptides with netMHCpan | [ Docs](#api-run-netmhcpan-peptides) [ Source](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/netmhcpan_peptides.py#L193) |
| `run_netmhcpan_protein()` | Scan protein sequences for MHC class I binding peptides with netMHCpan | [ Docs](#api-run-netmhcpan-protein) [ Source](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/netmhcpan_protein.py#L240) |

> [!NOTE]
>
> **License:** netMHCpan is licensed under Custom (DTU Health Tech Academic Software License) and has restrictions around commercial use and may require explicit attribution when utilized. Model weights are not publicly distributed and must be requested from the provider. Please refer to [the license](https://services.healthtech.dtu.dk/services/NetMHCpan-4.2/) for full terms.
>
> netMHCpan cannot be auto-downloaded and the license forbids redistribution, so in order to use these tools you must accept terms to download the software. The agreement is shown on the [Linux download request form](https://services.healthtech.dtu.dk/cgi-bin/sw_request?software=netMHCpan\&version=4.2\&packageversion=4.2estatic\&platform=Linux), also reachable from the **Downloads** tab of the [netMHCpan 4.2 service page](https://services.healthtech.dtu.dk/services/NetMHCpan-4.2/). After agreeing to terms of use, you will be able to submit a request to download the software. An institutional e-mail address is required, and a download link is e-mailed to you once approved.
>
> The license is free for publicly funded academic, educational, and research institutions. Commercial use requires a separate license from \<[health-software@dtu.dk](mailto:health-software@dtu.dk)>. The 4.2 archive bundles its network weights and threshold tables, so the one download is all you need. See [SETUP.md](SETUP.md) for setup steps. Please cite Nilsson et al. (2025).

## Background

[MHC class I](https://en.wikipedia.org/wiki/MHC_class_I) molecules bind short peptides produced by cytosolic protein degradation and display them at the cell surface, where CD8+ T cells inspect them. Which peptides are displayed is decided largely by the MHC binding groove, whose anchor-residue preferences differ from allele to allele, and the human [HLA](https://en.wikipedia.org/wiki/Human_leukocyte_antigen) loci are among the most polymorphic in the genome. The question "is this peptide presented?" therefore has thousands of allele-specific answers, and for most alleles there is little or no direct experimental data. The "pan" in netMHCpan is the response to that: rather than fitting one model per allele, the network takes a pseudo-sequence encoding of the MHC molecule itself - the polymorphic groove positions that contact the peptide - alongside the peptide, so a single model generalizes to alleles it was never trained on ([Nielsen et al., 2007](https://doi.org/10.1371/journal.pone.0000796)).

NetMHCpan-4.2 ([Nilsson et al., 2025](https://doi.org/10.3389/fimmu.2025.1616113)) is trained with an updated NNAlign\_MA framework on more than 1,000,000 peptides drawn from two kinds of measurement: quantitative binding affinity (BA) and mass-spectrometry eluted ligands (EL). The BA data covers 171 MHC molecules spanning human HLA-A, -B, -C and -E, mouse H-2, cattle BoLA, the primate Patr, Mamu and Gogo loci, swine SLA and equine Eqca; the EL data covers 201, spanning human HLA-A, -B, -C and -G, mouse H-2, cattle BoLA, the primate Mamu locus and dog DLA. Eluted-ligand data mostly comes from multi-allelic cell lines, where the allele responsible for each observed peptide is unknown; NNAlign\_MA resolves that by deconvolving the binding motifs concurrently with training, and adds features for amino-acid deletions. The two measurement types become two prediction heads: an EL score, read as the likelihood that a peptide is a naturally presented ligand, and a BA score with a predicted affinity in nM. EL is the default, and the EL likelihood is what the authors use for their epitope benchmark.

Three changes in 4.2 matter when reading its output. The first is not configurable and is simply how 4.2 scores: the network takes input features encoding the structural constraints of the peptide-binding cleft, which the authors report improves both predictive power and the identification of the peptide residues that contact the MHC. The second is that the method is fine-tuned by transfer learning on experimentally validated epitopes - roughly 43,000 pathogen-derived epitopes from [IEDB](https://www.iedb.org/) and 5,200 neoepitopes from [CEDAR](https://cedar.iedb.org/) - which `include_pathogen` and `include_neoepitope` surface as extra score and %rank columns. The authors are explicit that this fine-tuning yields only a minor accuracy boost, and that transferability between cancer- and pathogen-derived epitopes is limited, so the two heads are best read as task-specific second opinions rather than replacements for the EL score. The third is that 4.2 can encode each peptide's flanking residues (`use_context` on the protein scan), which affects the ligand likelihood through the processing signal that the flanks carry.

Each raw score is accompanied by a %rank: the percentile of that score against a large background set of random natural peptides scored on the same allele. This matters in practice, because raw scores sit on different per-allele background distributions and are not comparable across alleles, whereas a %rank is. The conventional thresholds are 0.5% for a strong binder and 2% for a weak one, and they are what this toolkit's `strong_rank` and `weak_rank` default to. Finally, a presented peptide is not necessarily an [immunogenic](https://en.wikipedia.org/wiki/Immunogenicity) one: proteasomal processing, TAP transport, TCR repertoire and self-tolerance all sit between presentation and a T-cell response, so these predictions bound the space of candidate [epitopes](https://en.wikipedia.org/wiki/Epitope) rather than identifying immunogenic ones.

### Learning Resources

* [NetMHCpan-4.2 service page](https://services.healthtech.dtu.dk/services/NetMHCpan-4.2/) (DTU Health Tech) - the canonical home: usage instructions, the output-column description, the supported-allele list, the changelog, and the gated academic download.
* [IEDB](https://www.iedb.org/) (NIAID / La Jolla Institute for Immunology) - a major public source of the curated binding measurements these methods are trained on, and the place to check whether a candidate peptide already has experimental support. Its companion [CEDAR](https://cedar.iedb.org/) covers cancer epitopes and is the source of the neoepitopes 4.2 is fine-tuned on.

## Tools

### netMHCpan Peptides (`netmhcpan-peptides`)

Scores explicit 8-14mer peptides against a panel of MHC class I alleles, returning one prediction per peptide per allele with the EL score, the EL %rank, a binder class, and - with `include_binding_affinity`, `include_pathogen` or `include_neoepitope` - the binding-affinity, pathogen-epitope and neoepitope scores and %ranks.

#### API Reference

[ Source](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/netmhcpan_peptides.py#L25)

> **Input: NetMHCpanPeptidesInput**
>
> **peptides** `List[string]` *required*
>
> MHC class I peptides (8-14 standard uppercase amino acids), each scored against every configured allele. A single string is normalized to a one-element list.

[ Source](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/netmhcpan_peptides.py#L58)

> **Config: NetMHCpanPeptidesConfig**
>
> **verbose** `integer` (default: 0)
>
> Verbosity level (0=quiet, 1=info, 2=debug, 3=raw subprocess stderr). `True` is coerced to `1` and `False` to `0`.
>
> **device** `string` (default: cpu)
>
> Device to run the tool on.
>
> **timeout** `integer` (default: 3600)
>
> Maximum execution time in seconds. `None` waits indefinitely.
>
> **seed** `integer`
>
> Random seed. When set, tools run reproducibly up to small GPU float noise (see `BaseToolOutput.approx_equal`), and the seed participates in cache keys. When None, cacheable seed-sensitive tools skip cache until seeded.
>
> **alleles** `List[string]` (default: \['HLA-A02:01'])
>
> MHC class I alleles to predict against. Accepts the `HLA-A02:01`, `HLA-A*02:01` and `A*02:01` spellings. Defaults to the netMHCpan default allele.
>
> **include\_binding\_affinity** `boolean` (default: False)
>
> Also predict binding affinity (`-BA`), adding BA score, BA %rank and nM affinity alongside the eluted-ligand columns.
>
> **include\_pathogen** `boolean` (default: False)
>
> Also report the pathogen-epitope head (`-pathogen`), fine-tuned on IEDB epitopes.
>
> **include\_neoepitope** `boolean` (default: False)
>
> Also report the neoepitope head (`-neo`), fine-tuned on CEDAR neoepitopes.
>
> **strong\_rank** `number` (default: 0.5)
>
> %rank at or below which a peptide is a strong binder.
>
> **weak\_rank** `number` (default: 2.0)
>
> %rank at or below which a peptide is a weak binder.
>
> **netmhcpan\_dir** `string`
>
> Path to a local netMHCpan install root.

[ Source](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/netmhcpan_peptides.py#L96)

> **Output: NetMHCpanPeptidesOutput**
>
> **predictions** `List[PeptidePrediction]` *required*
>
> One entry per input peptide, index-aligned with `inputs.peptides`.
>
> **PeptidePrediction**
>
> **peptide** `string` *required*
>
> The scored peptide.
>
> **bindings** `List[NetMHCpanBinding]` *required*
>
> One prediction per configured allele, in the order the alleles were configured.
>
> **primary\_metric** `string`
>
> Headline metric used to rank results.
>
> **metric\_type** `string`
>
> Concrete Metrics subclass tag; enables typed reconstruction after a serialization round-trip.
>
> **netmhcpan\_version** `string`
>
> Version string reported by the invoked binary.
>
> **Metrics** (one set per `predictions` item)
>
> | Metric | Type | Range | Availability |
> | - | - | - | - |
> | `strong_binder_count` | int | ≥ 0.0 | always |
> | `weak_binder_count` | int | ≥ 0.0 | always |
> | `strong_binder_fraction` | float | 0.0 to 1.0 | always |
> | `best_rank` | float | 0.0 to 100.0 | always |
> | `binding_propensity` | float | 0.0 to 1.0 | always |
> | `best_rank_ba` | float | 0.0 to 100.0 | only when include\_binding\_affinity is set |
> | `best_affinity_nm` | float | ≥ 0.0 | only when include\_binding\_affinity is set |
> | `best_rank_pathogen` | float | 0.0 to 100.0 | only when include\_pathogen is set |
> | `best_rank_neo` | float | 0.0 to 100.0 | only when include\_neoepitope is set |

#### Applications

Use this when the peptides already exist: a list of candidate vaccine epitopes to rank, mutation-derived [neoantigens](https://en.wikipedia.org/wiki/Neoantigen) enumerated upstream from variant calls, peptides identified by immunopeptidomics, or a set of designed sequences you want checked against a population-representative allele panel. The whole panel is scored in a single netMHCpan invocation, so adding alleles costs rows rather than runs.

#### Usage Tips

* **Threshold and compare on `rank_el`, not `score_el`.** Raw EL scores sit on different per-allele background distributions, so a score of 0.3 does not mean the same thing for `HLA-A02:01` as for `HLA-B07:02`. The %rank is a percentile against random natural peptides scored on the same allele and is the quantity that is comparable across alleles; `strong_rank` (default `0.5`) and `weak_rank` (default `2.0`) are applied to it.
* **`include_binding_affinity` adds the BA columns, it does not swap the mode.** netMHCpan's `-BA` flag is additive: with it set, `score_ba`, `rank_ba` and `affinity_nm` are populated alongside the EL fields, which stay the default and stay populated. Two summary metrics, `best_rank_ba` and `best_affinity_nm`, appear with it as well, and are absent rather than zero without it, so a stored result never implies an affinity that was never predicted. Leave it off unless you specifically need a nM number; the EL likelihood is what netMHCpan reports by default and what its authors benchmark epitope prediction on.
* **`include_pathogen` and `include_neoepitope` are additive too, and are second opinions rather than upgrades.** Each adds its own score and %rank from a head fine-tuned by transfer learning on experimentally validated epitopes: IEDB pathogen epitopes for `-pathogen`, CEDAR neoepitopes for `-neo`. They leave the EL fields untouched, and bring `best_rank_pathogen` and `best_rank_neo` with them. The authors report that this fine-tuning gives only a minor accuracy gain and that pathogen and cancer epitopes transfer poorly to each other, so match the head to the task - `include_neoepitope` for tumour neoantigens, `include_pathogen` for infectious-disease epitopes - and keep ranking on `rank_el` unless you have a reason not to. Requesting both is fine and costs one run.
* **`binder_class` is always derived from `rank_el`, including when BA is requested.** The `BindLevel` column netMHCpan prints is computed from the EL %rank even under `-BA`, which makes it ambiguous about which rank produced it. This wrapper classifies explicitly from `rank_el` so the reported class and the reported rank always agree.
* **There is deliberately no peptide-length setting on this tool.** netMHCpan silently ignores `-l` in peptide mode and scores every peptide at its own length, so a length config field here would be a lie. Lengths are validated instead (8-14, the class I range the netMHCpan server accepts), and k-mer enumeration lives in `netmhcpan-protein`, which is the reason the two input granularities are separate tools.
* **Allele spellings are normalized, and unknown alleles fail loudly.** `HLA-A02:01`, `HLA-A*02:01` and `A*02:01` are all accepted and converge on the unstarred `HLA-A02:01` form, which is the only spelling the binary itself accepts. Names are then checked against the allele list in the install before the binary is spawned, so a typo raises an error naming the offending allele with near-miss suggestions rather than surfacing as a tool crash.
* **Peptides must use the 20 standard uppercase amino acids.** netMHCpan silently rewrites anything else to `X`, which would mean scoring a peptide you did not ask about, so off-alphabet input is rejected up front.

### netMHCpan Protein Scan (`netmhcpan-protein`)

Enumerates every k-mer window of each protein sequence, scores all of them against the configured allele panel, and returns the per-window predictions together with summary metrics and epitope density for the sequence.

#### API Reference

[ Source](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/netmhcpan_protein.py#L27)

> **Input: NetMHCpanProteinInput**
>
> **sequences** `List[string]` *required*
>
> Protein sequences (standard uppercase amino acids) to enumerate k-mers from and score. A single string is normalized to a one-element list.

[ Source](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/netmhcpan_protein.py#L60)

> **Config: NetMHCpanProteinConfig**
>
> **peptide\_lengths** `List[integer]` (default: \[8, 9, 10, 11])
>
> k-mer lengths to enumerate from each sequence (netMHCpan `-l`). Defaults to the 8-11 class I screening range, which is wider than 4.2's own `-l` default of 9.
>
> **use\_context** `boolean` (default: False)
>
> Encode each window's flanking residues (`-context`), read off the supplied protein. Changes every reported score.
>
> **terminal\_context\_as\_alanine** `boolean` (default: False)
>
> Pad context that runs past a sequence terminus with alanine instead of `X` (`-termAcon`). Requires `use_context`.
>
> **verbose** `integer` (default: 0)
>
> Verbosity level (0=quiet, 1=info, 2=debug, 3=raw subprocess stderr). `True` is coerced to `1` and `False` to `0`.
>
> **device** `string` (default: cpu)
>
> Device to run the tool on.
>
> **timeout** `integer` (default: 3600)
>
> Maximum execution time in seconds. `None` waits indefinitely.
>
> **seed** `integer`
>
> Random seed. When set, tools run reproducibly up to small GPU float noise (see `BaseToolOutput.approx_equal`), and the seed participates in cache keys. When None, cacheable seed-sensitive tools skip cache until seeded.
>
> **alleles** `List[string]` (default: \['HLA-A02:01'])
>
> MHC class I alleles to predict against. Accepts the `HLA-A02:01`, `HLA-A*02:01` and `A*02:01` spellings. Defaults to the netMHCpan default allele.
>
> **include\_binding\_affinity** `boolean` (default: False)
>
> Also predict binding affinity (`-BA`), adding BA score, BA %rank and nM affinity alongside the eluted-ligand columns.
>
> **include\_pathogen** `boolean` (default: False)
>
> Also report the pathogen-epitope head (`-pathogen`).
>
> **include\_neoepitope** `boolean` (default: False)
>
> Also report the neoepitope head (`-neo`).
>
> **strong\_rank** `number` (default: 0.5)
>
> %rank at or below which a peptide is a strong binder.
>
> **weak\_rank** `number` (default: 2.0)
>
> %rank at or below which a peptide is a weak binder.
>
> **netmhcpan\_dir** `string`
>
> Path to a local netMHCpan install root.

[ Source](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/netmhcpan_protein.py#L141)

> **Output: NetMHCpanProteinOutput**
>
> **results** `List[ProteinScan]` *required*
>
> One entry per input sequence, index-aligned with `inputs.sequences`.
>
> **ProteinScan**
>
> **sequence\_length** `integer` *required*
>
> Length of the scanned protein, in residues.
>
> **num\_windows** `integer` *required*
>
> Distinct peptide windows enumerated from the sequence.
>
> **bindings** `List[NetMHCpanBinding]` *required*
>
> One prediction per window per allele.
>
> **primary\_metric** `string`
>
> Headline metric used to rank results.
>
> **metric\_type** `string`
>
> Concrete Metrics subclass tag; enables typed reconstruction after a serialization round-trip.
>
> **netmhcpan\_version** `string`
>
> Version string reported by the invoked binary.
>
> **Metrics** (one set per `results` item)
>
> | Metric | Type | Range | Availability |
> | - | - | - | - |
> | `strong_binder_count` | int | ≥ 0.0 | always |
> | `weak_binder_count` | int | ≥ 0.0 | always |
> | `strong_binder_fraction` | float | 0.0 to 1.0 | always |
> | `best_rank` | float | 0.0 to 100.0 | always |
> | `binding_propensity` | float | 0.0 to 1.0 | always |
> | `best_rank_ba` | float | 0.0 to 100.0 | only when include\_binding\_affinity is set |
> | `best_affinity_nm` | float | ≥ 0.0 | only when include\_binding\_affinity is set |
> | `best_rank_pathogen` | float | 0.0 to 100.0 | only when include\_pathogen is set |
> | `best_rank_neo` | float | 0.0 to 100.0 | only when include\_neoepitope is set |
> | `strong_binders_per_100_residues` | float | ≥ 0.0 | always |

#### Applications

Use this to screen whole sequences rather than peptide lists: scanning a designed protein, antibody or other biologic for class I epitopes before deimmunization, surveying a pathogen antigen for vaccine epitope candidates, or scoring a round of designs so that predicted immunogenicity can be traded off against the rest of an objective. Windowing happens inside the tool, and `position` is reported 1-indexed against the sequence you supplied.

#### Usage Tips

* **`peptide_lengths` (default `[8, 9, 10, 11]`) is the one setting the peptides tool does not have.** It is netMHCpan's `-l` flag, which is honoured only in FASTA mode. The default is the full class I screening range, which is deliberately wider than netMHCpan's own `-l` default of `9`; `[9]` alone is a reasonable, much cheaper restriction when only the dominant class I length matters. Lengths are de-duplicated, sorted, and bounded to 8-14.
* **`use_context` is the 4.2 feature this tool can offer and the peptides tool cannot.** netMHCpan's `-context` encodes the residues flanking each window, which carry a processing signal the peptide alone does not, and it changes every reported score - a context run and a plain run are not comparable, so pick one per experiment. It is free here because the flanks are read off the protein you supplied, whereas peptide mode would need you to hand over each peptide's flanks in netMHCpan's PEPTIDECONT format. `terminal_context_as_alanine` (`-termAcon`) only changes how context that runs off either terminus is padded, from `X` to alanine, and is rejected unless `use_context` is also set rather than being silently ignored.
* **`binding_propensity` is the primary metric and the one to optimize against.** A strong-binder count is piecewise-constant in the underlying sequence, so a sampler gets no gradient signal from it until a window crosses a threshold. `binding_propensity` is a logistic in log-rank space, centred so that it is exactly 0.5 at `weak_rank` and strictly decreasing in %rank, which gives a smooth 0-1 objective. The counts, `strong_binder_fraction` and `best_rank` are reported alongside it for the reading immunologists actually do.
* **`strong_binders_per_100_residues` is the metric to compare across sequences of different length.** Raw counts grow with sequence length and with panel size; this normalizes by both, so a 90-residue domain and a 500-residue scaffold can be ranked against each other. It does not normalize by `peptide_lengths`, since more lengths mean more windows over the same residues, so compare it only across runs that used the same lengths. `strong_binder_fraction` normalizes by window count as well and is the one to reach for when the lengths differ.
* **Cost scales as windows times alleles, not as sequences.** One scan produces one row per window per allele, so a 300-residue protein at four lengths against six alleles is already around 7,000 predictions. Trim `peptide_lengths` or the allele panel before trimming the sequence set.
* **Sequences must use the 20 standard uppercase amino acids and be at least 8 residues long.** As in the peptides tool, off-alphabet residues are rejected rather than silently rewritten to `X` by the binary.

## Toolkit Notes

These apply to every netMHCpan tool in this toolkit (`netmhcpan-peptides`, `netmhcpan-protein`).

* **CPU-only, and parallelised by fan-out rather than by threads.** netMHCpan is a single-threaded precompiled binary with no CUDA path, so both tools declare `cpus_per_instance = 1` and opt into ToolPool CPU fan-out: throughput comes from running many one-core instances over chunks of the input. Per-call cost is dominated by process startup, which is why the peptides tool chunks generously and the protein tool, whose rows multiply by window and allele, chunks much smaller.
* **Gated software, and local-only by license.** DTU gates the netMHCpan download behind per-user registration, so the install is provisioned by hand once; the archive bundles the networks and threshold tables, so nothing is fetched at run time. The DTU academic license is non-transferable and forbids giving the software to third parties, alone or integrated into other software, so both tools are registered `local_only` and can never run on a remote or hosted worker. Run them locally with `device='cpu'`. Place the install in the managed cache so it is found with no environment variable, or point `NETMHCPAN_HOME` (or `NMHOME`, or `PROTO_NETMHCPAN_WEIGHTS_DIR`) or the `netmhcpan_dir` config field at the `netMHCpan-4.2` root. See [SETUP.md](SETUP.md) for copy-paste steps. A missing install skips cleanly on an unconfigured host; a path that is set but wrong or incomplete fails fast with an actionable message.
* **No file in the install needs editing.** The netMHCpan install instructions have you edit the shipped `netMHCpan` tcsh launcher to hardcode `NMHOME` and `TMPDIR`. proto-tools does not: it invokes the platform binary directly with `-rdir` and `-tdir` and exports the `NETMHCpan` variable the launcher would have set. That keeps the install byte-identical to what DTU shipped - the license forbids modifying the source without written consent - and means tcsh need not be installed at all.
* **4.2e is the version this toolkit was developed and verified against.** An install that does not provide `<Platform>_<arch>/bin/netMHCpan-4.2` fails the setup precheck with an actionable message rather than running. Scores are version-specific, and output columns have differed across netMHCpan releases, so the parser keys on the result table's header row rather than fixed column offsets - which is also what absorbs the extra columns `-BA`, `-pathogen` and `-neo` add. The version the binary reported is returned as `netmhcpan_version` and recorded in the output metadata; check it before comparing runs.
* **Deterministic and cacheable.** The networks are fixed and no sampling is involved, so the same peptides, alleles and thresholds always give the same scores; both tools are registered `cacheable=True` and declare no seed.

> [!TIP]
>
> **Example notebook:** See the [full working example](https://github.com/evo-design/proto-tools/blob/2cb961a77981438592bc527f8469b6b0c18cb98e/proto_tools/tools/epitope_prediction/netmhcpan/examples/example.ipynb) for a copy-paste-ready walkthrough.

## Infrastructure Guides

The following guides cover how to run tools efficiently and at scale.

> **[Tool Persistence](https://proto.evodesign.org/docs/tools/guides/tool-persistence.md)**
>
> Keep a tool's model warm across calls instead of reloading it every invocation.

> **[Device Management](https://proto.evodesign.org/docs/tools/guides/device-management.md)**
>
> How GPUs are allocated to tools and how to target specific devices.

> **[Parallel Execution](https://proto.evodesign.org/docs/tools/guides/parallel-execution.md)**
>
> Fan a batch of inputs out across multiple GPUs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.