Skip to content

Commit

Permalink
Merge pull request #165 from openvax/support-netmhcpan41
Browse files Browse the repository at this point in the history
Support netmhcpan41
  • Loading branch information
timodonnell authored Jun 22, 2023
2 parents 4e09abe + 38a75e8 commit 820d661
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 7 deletions.
2 changes: 2 additions & 0 deletions mhctools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .netmhc_pan28 import NetMHCpan28
from .netmhc_pan3 import NetMHCpan3
from .netmhc_pan4 import NetMHCpan4, NetMHCpan4_BA, NetMHCpan4_EL
from .netmhc_pan41 import NetMHCpan41, NetMHCpan41_BA, NetMHCpan41_EL
from .netmhcii_pan import NetMHCIIpan, NetMHCIIpan3, NetMHCIIpan4, NetMHCIIpan4_BA, NetMHCIIpan4_EL
from .random_predictor import RandomBindingPredictor
from .unsupported_allele import UnsupportedAllele
Expand All @@ -43,6 +44,7 @@
"NetMHCpan28",
"NetMHCpan3",
"NetMHCpan4",
"NetMHCpan41",
"NetMHCpan4_BA",
"NetMHCpan4_EL",
"NetMHCIIpan",
Expand Down
6 changes: 6 additions & 0 deletions mhctools/cli/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
NetMHCpan4,
NetMHCpan4_EL,
NetMHCpan4_BA,
NetMHCpan41,
NetMHCpan41_EL,
NetMHCpan41_BA,
NetMHCIIpan,
NetMHCIIpan3,
NetMHCIIpan4,
Expand Down Expand Up @@ -61,6 +64,9 @@
"netmhcpan4": NetMHCpan4,
"netmhcpan4-ba": NetMHCpan4_BA,
"netmhcpan4-el": NetMHCpan4_EL,
"netmhcpan41": NetMHCpan41,
"netmhcpan41-ba": NetMHCpan41_BA,
"netmhcpan41-el": NetMHCpan41_EL,
"netmhcpan28": NetMHCpan28,
"netmhcpan3": NetMHCpan3,
"netmhciipan": NetMHCIIpan,
Expand Down
9 changes: 4 additions & 5 deletions mhctools/netmhc_pan.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from .netmhc_pan28 import NetMHCpan28
from .netmhc_pan3 import NetMHCpan3
from .netmhc_pan4 import NetMHCpan4

from .netmhc_pan41 import NetMHCpan41

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -52,13 +52,12 @@ def NetMHCpan(
}
if "NetMHCpan version 2.8" in output_str:
return NetMHCpan28(**common_kwargs)

elif "NetMHCpan version 3.0" in output_str:
return NetMHCpan3(**common_kwargs)

elif "NetMHCpan version 4.0" in output_str:
return NetMHCpan4(**common_kwargs)

elif "NetMHCpan version 4.1" in output_str:
return NetMHCpan4(**common_kwargs)
else:
raise RuntimeError(
"This software expects NetMHCpan version 2.8, 3.0, or 4.0")
"This software expects NetMHCpan version 2.8, 3.0, or 4.0, or 4.1")
4 changes: 2 additions & 2 deletions mhctools/netmhc_pan4.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from __future__ import print_function, division, absolute_import

from .base_commandline_predictor import BaseCommandlinePredictor
from .parsing import parse_netmhcpan4_stdout
from .parsing import parse_netmhcpan4_stdout, parse_netmhcpan41_stdout
from functools import partial

class NetMHCpan4(BaseCommandlinePredictor):
Expand Down Expand Up @@ -93,4 +93,4 @@ def __init__(
program_name=program_name,
process_limit=process_limit,
mode="binding_affinity",
extra_flags=extra_flags)
extra_flags=extra_flags)
98 changes: 98 additions & 0 deletions mhctools/netmhc_pan41.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Copyright (c) 2016-2023. Mount Sinai School of Medicine
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function, division, absolute_import

from .base_commandline_predictor import BaseCommandlinePredictor
from .parsing import parse_netmhc41_stdout
from functools import partial


class NetMHCpan41(BaseCommandlinePredictor):
def __init__(
self,
alleles,
default_peptide_lengths=[9],
program_name="netMHCpan",
process_limit=-1,
mode="binding_affinity",
extra_flags=[]):
"""
Wrapper for NetMHCpan4.1.
The mode argument should be one of "binding_affinity" (default) or
"elution_score".
"""

# The -BA flag is required to predict binding affinity
if mode == "binding_affinity":
flags = ["-BA"]
elif mode == "elution_score":
flags = []
else:
raise ValueError("Unsupported mode", mode)

BaseCommandlinePredictor.__init__(
self,
program_name=program_name,
alleles=alleles,
default_peptide_lengths=default_peptide_lengths,
parse_output_fn=partial(parse_netmhc41_stdout, mode=mode),
supported_alleles_flag="-listMHC",
input_file_flag="-f",
length_flag="-l",
allele_flag="-a",
extra_flags=flags + extra_flags,
process_limit=process_limit)

class NetMHCpan41_EL(NetMHCpan41):
"""
Wrapper for NetMHCpan4 when the preferred mode is elution score
"""
def __init__(
self,
alleles,
default_peptide_lengths=[9],
program_name="netMHCpan",
process_limit=-1,
extra_flags=[]):
NetMHCpan41.__init__(
self,
alleles=alleles,
default_peptide_lengths=default_peptide_lengths,
program_name=program_name,
process_limit=process_limit,
mode="elution_score",
extra_flags=extra_flags)


class NetMHCpan41_BA(NetMHCpan41):
"""
Wrapper for NetMHCpan4 when the preferred mode is binding affinity
"""
def __init__(
self,
alleles,
default_peptide_lengths=[9],
program_name="netMHCpan",
process_limit=-1,
extra_flags=[]):
NetMHCpan41.__init__(
self,
alleles=alleles,
default_peptide_lengths=default_peptide_lengths,
program_name=program_name,
process_limit=process_limit,
mode="binding_affinity",
extra_flags=extra_flags)
76 changes: 76 additions & 0 deletions mhctools/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,44 @@ def parse_netmhc4_stdout(
rank_index=13,
score_index=11)

def parse_netmhc41_stdout(
stdout,
mode,
prediction_method_name="netmhc41",
sequence_key_mapping=None):
"""
# NetMHCpan version 4.1b
# Tmpdir made /tmp/netMHCpanGjkOCb
# Input is in PEPTIDE format
# Make both EL and BA predictions
HLA-A02:01 : Distance to training data 0.000 (using nearest neighbor HLA-A02:01)
# Rank Threshold for Strong binding peptides 0.500
# Rank Threshold for Weak binding peptides 2.000
---------------------------------------------------------------------------------------------------------------------------
Pos MHC Peptide Core Of Gp Gl Ip Il Icore Identity Score_EL %Rank_EL Score_BA %Rank_BA Aff(nM) BindLevel
---------------------------------------------------------------------------------------------------------------------------
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
---------------------------------------------------------------------------------------------------------------------------
Protein PEPLIST. Allele HLA-A*02:01. Number of high binders 0. Number of weak binders 0. Number of peptides 1
"""
assert mode in ("binding_affinity", "elution_score")
return parse_stdout(
stdout=stdout,
prediction_method_name=prediction_method_name,
sequence_key_mapping=sequence_key_mapping,
key_index=10,
offset_index=0,
peptide_index=2,
allele_index=1,
ic50_index=15 if mode == "binding_affinity" else None,
rank_index=14 if mode == "binding_affinity" else 12,
score_index=13 if mode == "binding_affinity" else 11)

def parse_netmhcpan28_stdout(
stdout,
prediction_method_name="netmhcpan",
Expand Down Expand Up @@ -400,6 +438,44 @@ def parse_netmhcpan4_stdout(
rank_index=12 if mode == "elution_score" else 13,
transforms=transforms)

def parse_netmhcpan41_stdout(
stdout,
prediction_method_name="netmhcpan",
sequence_key_mapping=None,
mode="binding_affinity"):
"""
NetMHCpan version 4.1b
# Rank Threshold for Strong binding peptides 0.500
# Rank Threshold for Weak binding peptides 2.000
---------------------------------------------------------------------------------------------------------------------------
Pos MHC Peptide Core Of Gp Gl Ip Il Icore Identity Score_EL %Rank_EL Score_BA %Rank_BA Aff(nM) BindLevel
---------------------------------------------------------------------------------------------------------------------------
1 HLA-A*03:01 GKSGGGRCGGG GKSGGGRGG 0 7 2 0 0 GKSGGGRCGGG seq1 0.0000000 100.000 0.009240 95.346 45243.03
---------------------------------------------------------------------------------------------------------------------------
Protein seq1. Allele HLA-A*03:01. Number of high binders 0. Number of weak binders 0. Number of peptides 1
-----------------------------------------------------------------------------------
"""

# the offset specified in "pos" (at index 0) is 1-based instead of 0-based. we adjust it to be
# 0-based, as in all the other netmhc predictors supported by this library.
transforms = {
0: lambda x: int(x) - 1,
}
return parse_stdout(
stdout=stdout,
prediction_method_name=prediction_method_name,
sequence_key_mapping=sequence_key_mapping,
key_index=10,
offset_index=0,
peptide_index=2,
allele_index=1,
score_index=11 if mode == "elution_score" else 13,
ic50_index=None if mode == "elution_score" else 15,
rank_index=12 if mode == "elution_score" else 14,
transforms=transforms)


def parse_netmhccons_stdout(
stdout,
Expand Down
1 change: 1 addition & 0 deletions test/test_netmhc_pan.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"netMHCpan-2.8",
"netMHCpan-3.0",
"netMHCpan-4.0",
"netMHCpan-4.1",
]


Expand Down

0 comments on commit 820d661

Please sign in to comment.