Skip to content

Commit 38a75e8

Browse files
committed
Support NetMHCpan-4.1
This builds on work from @denklewer and @amitschang in #163 to support NetMHCpan 4.1.
1 parent 9fc061f commit 38a75e8

File tree

7 files changed

+149
-43
lines changed

7 files changed

+149
-43
lines changed

mhctools/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
from .netmhc_pan import NetMHCpan
1818
from .netmhc_pan28 import NetMHCpan28
1919
from .netmhc_pan3 import NetMHCpan3
20-
from .netmhc_pan4 import NetMHCpan4, NetMHCpan41, NetMHCpan4_BA, NetMHCpan4_EL
20+
from .netmhc_pan4 import NetMHCpan4, NetMHCpan4_BA, NetMHCpan4_EL
21+
from .netmhc_pan41 import NetMHCpan41, NetMHCpan41_BA, NetMHCpan41_EL
2122
from .netmhcii_pan import NetMHCIIpan, NetMHCIIpan3, NetMHCIIpan4, NetMHCIIpan4_BA, NetMHCIIpan4_EL
2223
from .random_predictor import RandomBindingPredictor
2324
from .unsupported_allele import UnsupportedAllele

mhctools/cli/args.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
NetMHCpan4,
3535
NetMHCpan4_EL,
3636
NetMHCpan4_BA,
37+
NetMHCpan41,
38+
NetMHCpan41_EL,
39+
NetMHCpan41_BA,
3740
NetMHCIIpan,
3841
NetMHCIIpan3,
3942
NetMHCIIpan4,
@@ -61,6 +64,9 @@
6164
"netmhcpan4": NetMHCpan4,
6265
"netmhcpan4-ba": NetMHCpan4_BA,
6366
"netmhcpan4-el": NetMHCpan4_EL,
67+
"netmhcpan41": NetMHCpan41,
68+
"netmhcpan41-ba": NetMHCpan41_BA,
69+
"netmhcpan41-el": NetMHCpan41_EL,
6470
"netmhcpan28": NetMHCpan28,
6571
"netmhcpan3": NetMHCpan3,
6672
"netmhciipan": NetMHCIIpan,

mhctools/netmhc_pan.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from .netmhc_pan28 import NetMHCpan28
2121
from .netmhc_pan3 import NetMHCpan3
2222
from .netmhc_pan4 import NetMHCpan4
23-
23+
from .netmhc_pan41 import NetMHCpan41
2424

2525
logger = logging.getLogger(__name__)
2626

@@ -52,13 +52,12 @@ def NetMHCpan(
5252
}
5353
if "NetMHCpan version 2.8" in output_str:
5454
return NetMHCpan28(**common_kwargs)
55-
5655
elif "NetMHCpan version 3.0" in output_str:
5756
return NetMHCpan3(**common_kwargs)
58-
5957
elif "NetMHCpan version 4.0" in output_str:
6058
return NetMHCpan4(**common_kwargs)
61-
59+
elif "NetMHCpan version 4.1" in output_str:
60+
return NetMHCpan4(**common_kwargs)
6261
else:
6362
raise RuntimeError(
64-
"This software expects NetMHCpan version 2.8, 3.0, or 4.0")
63+
"This software expects NetMHCpan version 2.8, 3.0, or 4.0, or 4.1")

mhctools/netmhc_pan4.py

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -55,43 +55,6 @@ def __init__(
5555
extra_flags=flags + extra_flags,
5656
process_limit=process_limit)
5757

58-
class NetMHCpan41(BaseCommandlinePredictor):
59-
def __init__(
60-
self,
61-
alleles,
62-
default_peptide_lengths=[9],
63-
program_name="netMHCpan",
64-
process_limit=-1,
65-
mode="binding_affinity",
66-
extra_flags=[]):
67-
"""
68-
Wrapper for NetMHCpan4.1.
69-
70-
The mode argument should be one of "binding_affinity" (default) or
71-
"elution_score".
72-
"""
73-
74-
# The -BA flag is required to predict binding affinity
75-
if mode == "binding_affinity":
76-
flags = ["-BA"]
77-
elif mode == "elution_score":
78-
flags = []
79-
else:
80-
raise ValueError("Unsupported mode", mode)
81-
82-
BaseCommandlinePredictor.__init__(
83-
self,
84-
program_name=program_name,
85-
alleles=alleles,
86-
default_peptide_lengths=default_peptide_lengths,
87-
parse_output_fn=partial(parse_netmhcpan41_stdout, mode=mode),
88-
supported_alleles_flag="-listMHC",
89-
input_file_flag="-f",
90-
length_flag="-l",
91-
allele_flag="-a",
92-
extra_flags=flags + extra_flags,
93-
process_limit=process_limit)
94-
9558
class NetMHCpan4_EL(NetMHCpan4):
9659
"""
9760
Wrapper for NetMHCpan4 when the preferred mode is elution score

mhctools/netmhc_pan41.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copyright (c) 2016-2023. Mount Sinai School of Medicine
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from __future__ import print_function, division, absolute_import
16+
17+
from .base_commandline_predictor import BaseCommandlinePredictor
18+
from .parsing import parse_netmhc41_stdout
19+
from functools import partial
20+
21+
22+
class NetMHCpan41(BaseCommandlinePredictor):
23+
def __init__(
24+
self,
25+
alleles,
26+
default_peptide_lengths=[9],
27+
program_name="netMHCpan",
28+
process_limit=-1,
29+
mode="binding_affinity",
30+
extra_flags=[]):
31+
"""
32+
Wrapper for NetMHCpan4.1.
33+
34+
The mode argument should be one of "binding_affinity" (default) or
35+
"elution_score".
36+
"""
37+
38+
# The -BA flag is required to predict binding affinity
39+
if mode == "binding_affinity":
40+
flags = ["-BA"]
41+
elif mode == "elution_score":
42+
flags = []
43+
else:
44+
raise ValueError("Unsupported mode", mode)
45+
46+
BaseCommandlinePredictor.__init__(
47+
self,
48+
program_name=program_name,
49+
alleles=alleles,
50+
default_peptide_lengths=default_peptide_lengths,
51+
parse_output_fn=partial(parse_netmhc41_stdout, mode=mode),
52+
supported_alleles_flag="-listMHC",
53+
input_file_flag="-f",
54+
length_flag="-l",
55+
allele_flag="-a",
56+
extra_flags=flags + extra_flags,
57+
process_limit=process_limit)
58+
59+
class NetMHCpan41_EL(NetMHCpan41):
60+
"""
61+
Wrapper for NetMHCpan4 when the preferred mode is elution score
62+
"""
63+
def __init__(
64+
self,
65+
alleles,
66+
default_peptide_lengths=[9],
67+
program_name="netMHCpan",
68+
process_limit=-1,
69+
extra_flags=[]):
70+
NetMHCpan41.__init__(
71+
self,
72+
alleles=alleles,
73+
default_peptide_lengths=default_peptide_lengths,
74+
program_name=program_name,
75+
process_limit=process_limit,
76+
mode="elution_score",
77+
extra_flags=extra_flags)
78+
79+
80+
class NetMHCpan41_BA(NetMHCpan41):
81+
"""
82+
Wrapper for NetMHCpan4 when the preferred mode is binding affinity
83+
"""
84+
def __init__(
85+
self,
86+
alleles,
87+
default_peptide_lengths=[9],
88+
program_name="netMHCpan",
89+
process_limit=-1,
90+
extra_flags=[]):
91+
NetMHCpan41.__init__(
92+
self,
93+
alleles=alleles,
94+
default_peptide_lengths=default_peptide_lengths,
95+
program_name=program_name,
96+
process_limit=process_limit,
97+
mode="binding_affinity",
98+
extra_flags=extra_flags)

mhctools/parsing.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,44 @@ def parse_netmhc4_stdout(
285285
rank_index=13,
286286
score_index=11)
287287

288+
def parse_netmhc41_stdout(
289+
stdout,
290+
mode,
291+
prediction_method_name="netmhc41",
292+
sequence_key_mapping=None):
293+
"""
294+
# NetMHCpan version 4.1b
295+
296+
# Tmpdir made /tmp/netMHCpanGjkOCb
297+
# Input is in PEPTIDE format
298+
299+
# Make both EL and BA predictions
300+
301+
HLA-A02:01 : Distance to training data 0.000 (using nearest neighbor HLA-A02:01)
302+
303+
# Rank Threshold for Strong binding peptides 0.500
304+
# Rank Threshold for Weak binding peptides 2.000
305+
---------------------------------------------------------------------------------------------------------------------------
306+
Pos MHC Peptide Core Of Gp Gl Ip Il Icore Identity Score_EL %Rank_EL Score_BA %Rank_BA Aff(nM) BindLevel
307+
---------------------------------------------------------------------------------------------------------------------------
308+
1 HLA-A*02:01 SIINFEKL SII-NFEKL 0 0 0 3 1 SIINFEKL PEPLIST 0.0100620 6.723 0.110414 20.171 15140.42
309+
---------------------------------------------------------------------------------------------------------------------------
310+
311+
Protein PEPLIST. Allele HLA-A*02:01. Number of high binders 0. Number of weak binders 0. Number of peptides 1
312+
"""
313+
assert mode in ("binding_affinity", "elution_score")
314+
return parse_stdout(
315+
stdout=stdout,
316+
prediction_method_name=prediction_method_name,
317+
sequence_key_mapping=sequence_key_mapping,
318+
key_index=10,
319+
offset_index=0,
320+
peptide_index=2,
321+
allele_index=1,
322+
ic50_index=15 if mode == "binding_affinity" else None,
323+
rank_index=14 if mode == "binding_affinity" else 12,
324+
score_index=13 if mode == "binding_affinity" else 11)
325+
288326
def parse_netmhcpan28_stdout(
289327
stdout,
290328
prediction_method_name="netmhcpan",

test/test_netmhc_pan.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"netMHCpan-2.8",
2424
"netMHCpan-3.0",
2525
"netMHCpan-4.0",
26+
"netMHCpan-4.1",
2627
]
2728

2829

0 commit comments

Comments
 (0)