Add NetCleave predictor for MHC-I/II C-terminal cleavage (#213) - #217
Merged
Conversation
Adds NetCleave, filling the MHC-II antigen-processing gap: NetChop and pepsickle only cover MHC-I proteasomal cleavage, and no class-II (endolysosomal) option existed. - New Kind.endolysosomal_cleavage (MHC-II, cathepsin) alongside the existing proteasome_cleavage (MHC-I, cytosolic); PeptideResult.endolysosomal_cleavage accessor. Naming per the decision recorded on #213. - NetCleave predictor (+ NetCleave_I / NetCleave_II subclasses). Unlike NetChop/pepsickle it emits one C-terminal score per peptide, so it shells out to NetCleave.py (NetChop-style subprocess) rather than subclassing ProcessingPredictor. Class I -> proteasome_cleavage, class II -> endolysosomal_cleavage. - predict(peptides, c_flanks=...) scores peptides given their downstream residues; predict_proteins() scans proteins so peptides are scored in real context. DataFrame variants included. NetCleave ships its Keras .h5 weights in-repo (git clone, no download); the R dependency in its README is only for training-data generation, not prediction (confirmed: not referenced by any Python in the predict path). Tests reproduce NetCleave's own CLI output exactly (abs 1e-3) on both the class-I and class-II pan models, from upstream `NetCleave.py --predict` (non-circular). Model-free constructor/validation tests run in CI without an install; model tests skip-gate on NETCLEAVE_DIR. A class-I > class-II signal check reflects the paper's AUC 0.91 vs 0.66. Version 3.15.0 -> 3.16.0. Claude-Session: https://claude.ai/code/session_01LZahFhBSCiehXTESCYQ7wG
Addresses two bugs found in review (self-review + ultrareview):
1. predict_proteins crashed ("NetCleave returned N rows for M epitopes") on
any protein containing a repeated peptide, and predict() failed when a
peptide recurred within peptide+flank. NetCleave's pred_input 3 emits one
row per regex occurrence of the epitope, so output rows are not 1:1 with
input rows. Fix: score each peptide in its own surrogate protein
(peptide + downstream flank) and de-multiplex output back to inputs by
row id + expected cleavage site, instead of asserting positional 1:1. The
surrogate yields identical scores (the site depends only on the C-terminal
4 + 3 downstream residues) and shrinks the predict_proteins CSV.
2. Concurrent NetCleave instances collided on a shared output/<basename>.csv
(basename was pid + per-instance counter). Fix: use uuid4 in the basename.
Also: document that an instance isn't thread-safe, and return [] from
predict([]) instead of raising.
Adds regression tests: repeated peptide in predict_proteins (both occurrences
scored in their own downstream context, cross-checked against predict()),
peptide recurring in flank, two-instance independence, and empty input.
Claude-Session: https://claude.ai/code/session_01LZahFhBSCiehXTESCYQ7wG
Belt-and-suspenders for the occurrence-mapping fix: when resolving each input row's score, verify NetCleave's output rows for that row id actually carry the requested epitope, so a future NetCleave output-contract change raises loudly instead of silently misaligning scores. Claude-Session: https://claude.ai/code/session_01LZahFhBSCiehXTESCYQ7wG
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.
Closes #213.
Adds NetCleave, filling the MHC-II antigen-processing gap:
NetChopandpepsickleonly cover MHC-I proteasomal cleavage, and no class-II (endolysosomal) option existed in the predictor set.What's new
Ontology
Kind.endolysosomal_cleavage(MHC-II, cathepsin pathway) alongside the existingproteasome_cleavage(MHC-I, cytosolic). Naming follows the decision recorded on #213: name the machine when one dominates, the compartment when the machinery is a diffuse family.PeptideResult.endolysosomal_cleavageaccessor.Predictor
NetCleave+NetCleave_I/NetCleave_IIsubclasses. Class I →proteasome_cleavage, class II →endolysosomal_cleavage.Design: why not a
ProcessingPredictorsubclassNetChop/pepsickleproduce a per-position cleavage profile that the base class collapses to a per-peptide score. NetCleave instead emits one C-terminal score per peptide (the 4+3 cleavage site: last 4 residues of the peptide + 3 downstream). So it doesn't fit thecleavage_probscontract — it's a standalone subprocess predictor (NetChop-style: write a temp CSV, shell out toNetCleave.py --predict --pred_input 3, parse the output). Because the C-terminal site needs downstream residues,predict()requiresc_flanks(≥3);predict_proteins()supplies real context automatically.Distribution — no gated download, no R for prediction
.h5files (~621 KB each), including the class-II models (II_mass-spectrometry_HLA-DR/DP/DQ). Justgit clone.iedb_processing.Ris only used in training-data generation and is not referenced by any Python in the--predictpath (verified).--predictneeds only Python (tensorflow/keras, scikit-learn, biopython, pandas). The wrapper shells out to a user-provided interpreter (python_executable=to override), vendoring nothing (NetCleave is GPL-v2)..h5files are loaded as weights into an architecture NetCleave rebuilds in code, so loading is robust across Keras versions (verified on TF 2.21 / Keras 3.14).Faithfulness — verified against upstream CLI
Tests reproduce NetCleave's own
NetCleave.py --predictoutput exactly (abs=1e-3) on both the class-I and class-II pan models — reference values generated from the upstream CLI, not this wrapper (non-circular). A class-I > class-II signal check reflects the paper's AUC 0.91 vs 0.66.Scope
--predict(pred_input 3, protein-sequence context), both classes, protein scanning.--generate/--trainmodes and the UniProt-fetchingpred_input 2(avoids network inpredict()); no vendoring.Tests
NETCLEAVE_DIR(skip when absent, mirroringtest_nettcr.py): CLI-reference reproduction for both classes, kind mapping +kind_supportmetadata,predict_proteinswith correct offset/context,c_flanksrequired, short-flank → empty result with 1:1 alignment, dataframe schema, determinism, subclasses.Full suite: 238 passed, 25 skipped without the DTU/NetCleave installs; 15/15 NetCleave model tests pass with the install. Ruff clean. Version 3.15.0 → 3.16.0.
https://claude.ai/code/session_01LZahFhBSCiehXTESCYQ7wG