Skip to content

Commit 3b5d606

Browse files
authored
Merge pull request #168 from fkgruber/master
added support to NetMHCIIpan 4.3
2 parents 781c756 + 1626197 commit 3b5d606

File tree

5 files changed

+153
-11
lines changed

5 files changed

+153
-11
lines changed

mhctools/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from .netmhc_pan3 import NetMHCpan3
2020
from .netmhc_pan4 import NetMHCpan4, NetMHCpan4_BA, NetMHCpan4_EL
2121
from .netmhc_pan41 import NetMHCpan41, NetMHCpan41_BA, NetMHCpan41_EL
22-
from .netmhcii_pan import NetMHCIIpan, NetMHCIIpan3, NetMHCIIpan4, NetMHCIIpan4_BA, NetMHCIIpan4_EL
22+
from .netmhcii_pan import NetMHCIIpan, NetMHCIIpan3, NetMHCIIpan4, NetMHCIIpan4_BA, NetMHCIIpan4_EL, NetMHCIIpan43, NetMHCIIpan43_BA, NetMHCIIpan43_EL
2323
from .random_predictor import RandomBindingPredictor
2424
from .netmhcstabpan import NetMHCstabpan
2525
from .unsupported_allele import UnsupportedAllele
@@ -48,7 +48,7 @@
4848
"NetMHCpan41",
4949
"NetMHCpan4_BA",
5050
"NetMHCpan4_EL",
51-
"NetMHCpan41_BA",
51+
"NetMHCpan41_BA",
5252
"NetMHCpan41_EL",
5353
"NetMHCIIpan",
5454
"NetMHCIIpan3",

mhctools/base_commandline_predictor.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ def predict_peptides(self, peptides):
301301
prefix="tmp_%d_%d_%s" % (
302302
i,
303303
j,
304-
self.program_name))
304+
self.program_name),
305+
suffix="XXXXXX")
305306
logger.debug(
306307
"Created temporary directory %s for allele %s",
307308
temp_dirname,

mhctools/netmhcii_pan.py

+71-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from mhcnames import parse_classi_or_classii_allele_name
1919

2020
from .base_commandline_predictor import BaseCommandlinePredictor
21-
from .parsing import parse_netmhciipan_stdout, parse_netmhciipan4_stdout
21+
from .parsing import parse_netmhciipan_stdout, parse_netmhciipan4_stdout, parse_netmhciipan43_stdout
2222

2323
logger = logging.getLogger(__name__)
2424

@@ -216,3 +216,73 @@ def NetMHCIIpan(
216216
return NetMHCIIpan3(**kwargs)
217217
else:
218218
raise ValueError("This software expects NetMHCIIpan version 3.x or 4.0")
219+
220+
221+
class NetMHCIIpan43(NetMHCIIpanBase):
222+
"""
223+
Wrapper for NetMHCIIpan 4.3, using a different parser.
224+
"""
225+
def __init__(
226+
self,
227+
alleles,
228+
default_peptide_lengths=[15, 16, 17, 18, 19, 20],
229+
program_name="netMHCIIpan",
230+
process_limit=-1,
231+
mode="elution_score",
232+
extra_flags=[]):
233+
234+
if mode not in ['binding_affinity', 'elution_score']:
235+
raise ValueError("Unsupported mode", mode)
236+
237+
# Always include binding affinity data (-BA flag), though the main score and %rank will
238+
# still be EL-based. This gives us access to the BA-based score and %rank columns.
239+
240+
NetMHCIIpanBase.__init__(
241+
self,
242+
alleles=alleles,
243+
program_name=program_name,
244+
process_limit=process_limit,
245+
parse_output_fn=partial(parse_netmhciipan43_stdout, mode=mode),
246+
default_peptide_lengths=default_peptide_lengths,
247+
extra_flags=['-BA'] + extra_flags)
248+
249+
class NetMHCIIpan43_EL(NetMHCIIpan43):
250+
"""
251+
Wrapper for NetMHCIIpan43 when the preferred mode is elution score
252+
"""
253+
def __init__(
254+
self,
255+
alleles,
256+
default_peptide_lengths=[15, 16, 17, 18, 19, 20],
257+
program_name="netMHCIIpan",
258+
process_limit=-1,
259+
extra_flags=[]):
260+
NetMHCIIpan43.__init__(
261+
self,
262+
alleles=alleles,
263+
default_peptide_lengths=default_peptide_lengths,
264+
program_name=program_name,
265+
process_limit=process_limit,
266+
mode="elution_score",
267+
extra_flags=extra_flags)
268+
269+
270+
class NetMHCIIpan43_BA(NetMHCIIpan43):
271+
"""
272+
Wrapper for NetMHCIIpan43 when the preferred mode is binding affinity
273+
"""
274+
def __init__(
275+
self,
276+
alleles,
277+
default_peptide_lengths=[15, 16, 17, 18, 19, 20],
278+
program_name="netMHCIIpan",
279+
process_limit=-1,
280+
extra_flags=[]):
281+
NetMHCIIpan43.__init__(
282+
self,
283+
alleles=alleles,
284+
default_peptide_lengths=default_peptide_lengths,
285+
program_name=program_name,
286+
process_limit=process_limit,
287+
mode="binding_affinity",
288+
extra_flags=extra_flags)

mhctools/parsing.py

+57-7
Original file line numberDiff line numberDiff line change
@@ -565,13 +565,13 @@ def parse_netmhciipan4_stdout(
565565
--------------------------------------------------------------------------------------------------------------------------------------------
566566
Pos MHC Peptide Of Core Core_Rel Identity Score_EL %Rank_EL Exp_Bind Score_BA Affinity(nM) %Rank_BA BindLevel
567567
--------------------------------------------------------------------------------------------------------------------------------------------
568-
1 DRB1_0101 PAPAPSWPLSSSVPS 4 PSWPLSSSV 0.327 test 0.000857 79.79 NA 0.327674 1442.91 54.35
569-
2 DRB1_0101 APAPSWPLSSSVPSQ 3 PSWPLSSSV 0.333 test 0.001268 71.87 NA 0.346949 1171.30 50.15
570-
3 DRB1_0101 PAPSWPLSSSVPSQK 4 WPLSSSVPS 0.713 test 0.002836 54.45 NA 0.412004 579.40 36.66
571-
4 DRB1_0101 APSWPLSSSVPSQKT 3 WPLSSSVPS 0.773 test 0.003677 49.14 NA 0.448939 388.53 29.75
572-
5 DRB1_0101 PSWPLSSSVPSQKTY 2 WPLSSSVPS 0.407 test 0.001602 66.79 NA 0.470979 306.09 25.98
573-
6 DRB1_0101 SWPLSSSVPSQKTYQ 3 LSSSVPSQK 0.633 test 0.001671 65.82 NA 0.476222 289.21 25.07
574-
7 DRB1_0101 WPLSSSVPSQKTYQG 3 SSSVPSQKT 0.553 test 0.001697 65.45 NA 0.447217 395.83 30.05
568+
1 DRB1_0101 PAPAPSWPLSSSVPS 4 PSWPLSSSV 0.327 test 0.000857 79.79 NA 0.327674 1442.91 54.35
569+
2 DRB1_0101 APAPSWPLSSSVPSQ 3 PSWPLSSSV 0.333 test 0.001268 71.87 NA 0.346949 1171.30 50.15
570+
3 DRB1_0101 PAPSWPLSSSVPSQK 4 WPLSSSVPS 0.713 test 0.002836 54.45 NA 0.412004 579.40 36.66
571+
4 DRB1_0101 APSWPLSSSVPSQKT 3 WPLSSSVPS 0.773 test 0.003677 49.14 NA 0.448939 388.53 29.75
572+
5 DRB1_0101 PSWPLSSSVPSQKTY 2 WPLSSSVPS 0.407 test 0.001602 66.79 NA 0.470979 306.09 25.98
573+
6 DRB1_0101 SWPLSSSVPSQKTYQ 3 LSSSVPSQK 0.633 test 0.001671 65.82 NA 0.476222 289.21 25.07
574+
7 DRB1_0101 WPLSSSVPSQKTYQG 3 SSSVPSQKT 0.553 test 0.001697 65.45 NA 0.447217 395.83 30.05
575575
576576
577577
"""
@@ -643,3 +643,53 @@ def parse_netmhcstabpan(
643643
rank_index=6,
644644
transforms=transforms)
645645

646+
def parse_netmhciipan43_stdout(
647+
stdout,
648+
prediction_method_name="netmhciipan",
649+
sequence_key_mapping=None,
650+
mode="elution_score"):
651+
"""
652+
# Threshold for Strong binding peptides (%Rank) 1.00%
653+
# Threshold for Weak binding peptides (%Rank) 5.00%
654+
655+
# DRB1_0101 : Distance to training data 0.000 (using nearest neighbor DRB1_0101)
656+
657+
# Allele: DRB1_0101
658+
--------------------------------------------------------------------------------------------------------------------------------------------
659+
Pos MHC Peptide Of Core Core_Rel Inverted Identity Score_EL %Rank_EL Exp_Bind Score_BA %Rank_BA Affinity(nM) BindLevel
660+
--------------------------------------------------------------------------------------------------------------------------------------------
661+
1 DRB1_0101 AAAGAEAGKATTE 1 AAGAEAGKA 0.740 0 Sequence 0.000143 72.70 0.000 0.086339 95.13 19645.62
662+
2 DRB1_0101 AALAAAAGVPPADKY 2 LAAAAGVPP 0.950 0 Sequence 0.030661 15.86 0.300 0.616438 7.87 63.44
663+
3 DRB1_0101 EKPGNRNPYENL 3 GNRNPYENL 0.680 0 Sequence 0.000000 100.00 0.670 0.030746 98.27 35850.53
664+
4 DRB1_0101 STWLLKPGAGIMIFD 2 WLLKPGAGI 0.420 0 Sequence 0.027506 16.58 0.000 0.708645 2.85 23.39
665+
5 DRB1_0101 KSVPLEMLLINLTTI 4 LEMLLINLT 0.980 0 Sequence 0.007346 26.97 0.560 0.662093 4.95 38.71
666+
6 DRB1_0101 KTKEDLFGKKNLIPS 5 LFGKKNLIP 0.560 0 Sequence 0.000144 72.62 0.670 0.298919 55.60 1969.51
667+
7 DRB1_0101 KIYHKCDNACIGSIR 2 YHKCDNACI 0.830 0 Sequence 0.003393 34.40 0.940 0.407849 34.13 606.04
668+
8 DRB1_0101 PCLFMRTVSHVILHG 3 FMRTVSHVI 0.960 0 Sequence 0.047565 13.05 0.345 0.664932 4.80 37.54
669+
9 DRB1_0101 GAATVAAGAATTAAG 4 VAAGAATTA 0.920 0 Sequence 0.164981 6.81 0.000 0.514261 17.98 191.63
670+
"""
671+
check_stdout_error(stdout, "NetMHCIIpan")
672+
673+
if mode not in ["elution_score", "binding_affinity"]:
674+
raise ValueError("Mode is %s but must be one of: elution_score, binding affinity" % mode)
675+
676+
# the offset specified in "pos" (at index 0) is 1-based instead of 0-based. we adjust it to be
677+
# 0-based, as in all the other netmhc predictors supported by this library.
678+
transforms = {
679+
0: lambda x: int(x) - 1,
680+
}
681+
682+
# we're running NetMHCIIpan 4.3 with -BA every time so both EL and BA are available, but only
683+
# return one of them depending on the input mode
684+
return parse_stdout(
685+
stdout=stdout,
686+
prediction_method_name=prediction_method_name,
687+
sequence_key_mapping=sequence_key_mapping,
688+
key_index=7,
689+
offset_index=0,
690+
peptide_index=2,
691+
allele_index=1,
692+
ic50_index=13 if mode == "binding_affinity" else None,
693+
rank_index=9 if mode == "elution_score" else 12,
694+
score_index=8 if mode == "elution_score" else 11,
695+
transforms=transforms)

tests/test_netmhcii_pan32.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from mhctools import NetMHCIIpan43, NetMHCIIpan43_EL, NetMHCIIpan43_BA
2+
3+
4+
def test_netmhciipan43():
5+
predictor=NetMHCIIpan43(alleles=['DRB1_0101'])
6+
predictions=predictor.predict_subsequences(["AAGAARIIAVDINKD","AAGIVESVGEGVTTV"]).to_dataframe()
7+
assert predictions.shape==(2, 9)
8+
assert all([pp==None for pp in predictions.affinity])==True ## no binding predictions
9+
10+
def test_netmhciipan43_ba():
11+
predictor_ba=NetMHCIIpan43_BA(alleles=['DRB1_0101',"HLA-DQA1*05:11-DQB1*03:02"])
12+
binding_predictions=predictor_ba.predict_subsequences(["AAGAARIIAVDINKD","AAGIVESVGEGVTTV"]).to_dataframe()
13+
assert binding_predictions.shape==(4, 9)
14+
assert all([pp==None for pp in binding_predictions.affinity])==False # output should preturn binding predictions
15+
16+
17+
def test_netmhciipan43_el():
18+
predictor_el=NetMHCIIpan43_EL(alleles=['DRB1_0101',"HLA-DQA1*05:11-DQB1*03:02"])
19+
EL_predictions=predictor_el.predict_subsequences(["AAGAARIIAVDINKD","AAGIVESVGEGVTTV"]).to_dataframe()
20+
assert EL_predictions.shape==(4, 9)
21+
assert all([pp==None for pp in EL_predictions.affinity])==True # no affinity predictions

0 commit comments

Comments
 (0)