Skip to content

Commit 820d661

Browse files
authored
Merge pull request #165 from openvax/support-netmhcpan41
Support netmhcpan41
2 parents 4e09abe + 38a75e8 commit 820d661

File tree

7 files changed

+189
-7
lines changed

7 files changed

+189
-7
lines changed

mhctools/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from .netmhc_pan28 import NetMHCpan28
1919
from .netmhc_pan3 import NetMHCpan3
2020
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
@@ -43,6 +44,7 @@
4344
"NetMHCpan28",
4445
"NetMHCpan3",
4546
"NetMHCpan4",
47+
"NetMHCpan41",
4648
"NetMHCpan4_BA",
4749
"NetMHCpan4_EL",
4850
"NetMHCIIpan",

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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from __future__ import print_function, division, absolute_import
1616

1717
from .base_commandline_predictor import BaseCommandlinePredictor
18-
from .parsing import parse_netmhcpan4_stdout
18+
from .parsing import parse_netmhcpan4_stdout, parse_netmhcpan41_stdout
1919
from functools import partial
2020

2121
class NetMHCpan4(BaseCommandlinePredictor):
@@ -93,4 +93,4 @@ def __init__(
9393
program_name=program_name,
9494
process_limit=process_limit,
9595
mode="binding_affinity",
96-
extra_flags=extra_flags)
96+
extra_flags=extra_flags)

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: 76 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",
@@ -400,6 +438,44 @@ def parse_netmhcpan4_stdout(
400438
rank_index=12 if mode == "elution_score" else 13,
401439
transforms=transforms)
402440

441+
def parse_netmhcpan41_stdout(
442+
stdout,
443+
prediction_method_name="netmhcpan",
444+
sequence_key_mapping=None,
445+
mode="binding_affinity"):
446+
"""
447+
NetMHCpan version 4.1b
448+
# Rank Threshold for Strong binding peptides 0.500
449+
# Rank Threshold for Weak binding peptides 2.000
450+
---------------------------------------------------------------------------------------------------------------------------
451+
Pos MHC Peptide Core Of Gp Gl Ip Il Icore Identity Score_EL %Rank_EL Score_BA %Rank_BA Aff(nM) BindLevel
452+
---------------------------------------------------------------------------------------------------------------------------
453+
1 HLA-A*03:01 GKSGGGRCGGG GKSGGGRGG 0 7 2 0 0 GKSGGGRCGGG seq1 0.0000000 100.000 0.009240 95.346 45243.03
454+
---------------------------------------------------------------------------------------------------------------------------
455+
456+
Protein seq1. Allele HLA-A*03:01. Number of high binders 0. Number of weak binders 0. Number of peptides 1
457+
458+
-----------------------------------------------------------------------------------
459+
"""
460+
461+
# the offset specified in "pos" (at index 0) is 1-based instead of 0-based. we adjust it to be
462+
# 0-based, as in all the other netmhc predictors supported by this library.
463+
transforms = {
464+
0: lambda x: int(x) - 1,
465+
}
466+
return parse_stdout(
467+
stdout=stdout,
468+
prediction_method_name=prediction_method_name,
469+
sequence_key_mapping=sequence_key_mapping,
470+
key_index=10,
471+
offset_index=0,
472+
peptide_index=2,
473+
allele_index=1,
474+
score_index=11 if mode == "elution_score" else 13,
475+
ic50_index=None if mode == "elution_score" else 15,
476+
rank_index=12 if mode == "elution_score" else 14,
477+
transforms=transforms)
478+
403479

404480
def parse_netmhccons_stdout(
405481
stdout,

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)