Skip to content

Commit

Permalink
Merge 9955288 into ba9d719
Browse files Browse the repository at this point in the history
  • Loading branch information
iskandr committed Feb 13, 2020
2 parents ba9d719 + 9955288 commit 926405e
Show file tree
Hide file tree
Showing 19 changed files with 300 additions and 181 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sudo: true
language: python
python:
- "2.7"
- "3.6"
- "3.5"
git:
# don't need the default depth of 50
# but don't want to use a depth of 1 since that affects
Expand Down Expand Up @@ -57,7 +57,7 @@ addons:
install:
- >
conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION
numpy nose pylint cython
numpy nose pylint cython tensorflow tensorboard
- source activate test-environment
# install pysam from conda because I'm having trouble installing Cython
# for Python 3 on Travis
Expand Down
10 changes: 4 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Copyright (c) 2016-2018. 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
Expand Down Expand Up @@ -45,12 +43,12 @@
name='vaxrank',
version=version,
description="Mutant peptide ranking for personalized cancer vaccines",
author="Alex Rubinsteyn",
author_email="alex.rubinsteyn@gmail.com",
url="https://github.com/hammerlab/vaxrank",
author="Alex Rubinsteyn, Julia Kodysh",
author_email="alex@openvax.org, julia@openvax.org",
url="https://github.com/openvax/vaxrank",
license="http://www.apache.org/licenses/LICENSE-2.0.html",
classifiers=[
'Development Status :: 3 - Alpha',
'Development Status :: 4 - Beta',
'Environment :: Console',
'Operating System :: OS Independent',
'Intended Audience :: Science/Research',
Expand Down
13 changes: 13 additions & 0 deletions test/test_cancer_driver_gene.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# 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 vaxrank.gene_pathway_check import (
GenePathwayCheck,
_IFNG_RESPONSE_COLUMN_NAME,
Expand Down
21 changes: 18 additions & 3 deletions test/test_epitope_prediction.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Copyright (c) 2016-2018. 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
Expand All @@ -19,7 +17,7 @@
from mhctools import RandomBindingPredictor
from pyensembl import genome_for_reference_name
from varcode import Variant
from vaxrank.epitope_prediction import predict_epitopes
from vaxrank.epitope_prediction import predict_epitopes, EpitopePrediction
from vaxrank.mutant_protein_fragment import MutantProteinFragment
from vaxrank.vaccine_peptide import VaccinePeptide

Expand Down Expand Up @@ -89,3 +87,20 @@ def predict_subsequences(self, x):
genome=mouse_genome)

eq_(0, len(epitope_predictions))

def test_EpitopePrediction_json_serialization():
e = EpitopePrediction(
allele="HLA-A*02:01",
peptide_sequence="SIINFEQL",
ic50=2.0,
wt_peptide_sequence="SIINFEKL",
wt_ic50=2000.0,
percentile_rank=0.3,
prediction_method_name="ImaginationMHCpan",
overlaps_mutation=True,
source_sequence="SSIINFEQL",
offset=1,
occurs_in_reference=False)
json = e.to_json()
e2 = EpitopePrediction.from_json((json))
eq_(e, e2)
13 changes: 13 additions & 0 deletions test/test_manufacturability.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# 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 vaxrank.manufacturability import ManufacturabilityScores


Expand Down
2 changes: 0 additions & 2 deletions test/test_mutant_protein_sequence.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Copyright (c) 2016-2018. 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
Expand Down
13 changes: 13 additions & 0 deletions test/test_shell_script.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# 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 os.path import getsize
from mock import patch
from nose.plugins.attrib import attr
Expand Down
2 changes: 0 additions & 2 deletions test/testing_helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Copyright (c) 2016-2018. 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
Expand Down
2 changes: 1 addition & 1 deletion vaxrank/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.0.2"
__version__ = "1.1.0"
4 changes: 1 addition & 3 deletions vaxrank/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Copyright (c) 2016-2018. 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
Expand Down Expand Up @@ -42,8 +40,8 @@
make_csv_report,
make_minimal_neoepitope_report,
TemplateDataCreator,
PatientInfo,
)
from .patient_info import PatientInfo

logger = logging.getLogger(__name__)

Expand Down
2 changes: 0 additions & 2 deletions vaxrank/core_logic.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Copyright (c) 2016-2018. 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
Expand Down
149 changes: 98 additions & 51 deletions vaxrank/epitope_prediction.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Copyright (c) 2016-2018. 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
Expand All @@ -13,33 +11,57 @@
# limitations under the License.

from __future__ import absolute_import, print_function, division
from collections import namedtuple, OrderedDict
from collections import OrderedDict
import traceback
import logging

import numpy as np
from serializable import Serializable

from .reference_proteome import ReferenceProteome

logger = logging.getLogger(__name__)

EpitopePredictionBase = namedtuple("EpitopePrediction", [
"allele",
"peptide_sequence",
"wt_peptide_sequence",
"length",
"ic50",
"wt_ic50",
"percentile_rank",
"prediction_method_name",
"overlaps_mutation",
"source_sequence",
"offset",
"occurs_in_reference",
])
logger = logging.getLogger(__name__)


class EpitopePrediction(EpitopePredictionBase):
class EpitopePrediction(Serializable):
def __init__(
self,
allele,
peptide_sequence,
wt_peptide_sequence,
ic50,
wt_ic50,
percentile_rank,
prediction_method_name,
overlaps_mutation,
source_sequence,
offset,
occurs_in_reference):
self.allele = allele
self.peptide_sequence = peptide_sequence
self.wt_peptide_sequence = wt_peptide_sequence
self.length = len(peptide_sequence)
self.ic50 = ic50
self.wt_ic50 = wt_ic50
self.percentile_rank = percentile_rank
self.prediction_method_name = prediction_method_name
self.overlaps_mutation = overlaps_mutation
self.source_sequence = source_sequence
self.offset = offset
self.overlaps_mutation = overlaps_mutation
self.occurs_in_reference = occurs_in_reference

@classmethod
def from_dict(cls, d):
"""
Deserialize EpitopePrediction from a dictionary of keywords.
"""
d = d.copy()
if "length" in d:
# lenth argument removed in version 1.1.0
del d["length"]
return cls(**d)

def logistic_epitope_score(
self,
Expand Down Expand Up @@ -70,6 +92,56 @@ def logistic_epitope_score(

return logistic / normalizer

def slice_source_sequence(self, start_offset, end_offset):
"""
Parameters
----------
start_offset : int
end_offset : int
Return EpitopePrediction object with source sequence and offset
adjusted. If this slicing would shorten the mutant peptide, then
return None.
"""
if self.offset < start_offset:
# this peptide starts before the requested slice through the
# source sequence
return None

if self.offset + self.length > end_offset:
# this peptide goes beyond the end of the requested slice
# through the source sequence
return None

return EpitopePrediction(
allele=self.allele,
peptide_sequence=self.peptide_sequence,
wt_peptide_sequence=self.wt_peptide_sequence,
ic50=self.ic50,
wt_ic50=self.wt_ic50,
percentile_rank=self.percentile_rank,
prediction_method_name=self.prediction_method_name,
overlaps_mutation=self.overlaps_mutation,
source_sequence=self.source_sequence[start_offset:end_offset],
offset=self.offset - start_offset,
occurs_in_reference=self.occurs_in_reference)


def slice_epitope_predictions(
epitope_predictions,
start_offset,
end_offset):
"""
Return subset of EpitopePrediction objects which overlap the given interval
and slice through their source sequences and adjust their offset.
"""
return [
p.slice_source_sequence(start_offset, end_offset)
for p in epitope_predictions
if p.offset >= start_offset and p.offset + p.length <= end_offset
]

def predict_epitopes(
mhc_predictor,
Expand Down Expand Up @@ -150,10 +222,11 @@ def predict_epitopes(
'MHC prediction for WT peptides errored, with traceback: %s',
traceback.format_exc())

wt_predictions_grouped = {}
# break it out: (peptide, allele) -> prediction
for wt_prediction in wt_predictions:
wt_predictions_grouped[(wt_prediction.peptide, wt_prediction.allele)] = wt_prediction
wt_predictions_grouped = {
(wt_prediction.peptide, wt_prediction.allele): wt_prediction
for wt_prediction in wt_predictions
}

# convert from mhctools.BindingPrediction objects to EpitopePrediction
# which differs primarily by also having a boolean field
Expand Down Expand Up @@ -181,7 +254,8 @@ def predict_epitopes(
# compute WT epitope sequence, if this epitope overlaps the mutation
if overlaps_mutation:
wt_peptide = wt_peptides[peptide]
wt_prediction = wt_predictions_grouped.get((wt_peptide, binding_prediction.allele))
wt_prediction = wt_predictions_grouped.get(
(wt_peptide, binding_prediction.allele))
wt_ic50 = None
if wt_prediction is None:
# this can happen in a stop-loss variant: do we want to check that here?
Expand All @@ -200,7 +274,6 @@ def predict_epitopes(
allele=binding_prediction.allele,
peptide_sequence=peptide,
wt_peptide_sequence=wt_peptide,
length=len(peptide),
ic50=binding_prediction.value,
wt_ic50=wt_ic50,
percentile_rank=binding_prediction.percentile_rank,
Expand All @@ -209,6 +282,7 @@ def predict_epitopes(
source_sequence=protein_fragment.amino_acids,
offset=peptide_start_offset,
occurs_in_reference=occurs_in_reference)

if epitope_prediction.logistic_epitope_score() >= min_epitope_score:
key = (epitope_prediction.peptide_sequence, epitope_prediction.allele)
results[key] = epitope_prediction
Expand All @@ -221,30 +295,3 @@ def predict_epitopes(
num_occurs_in_reference,
num_low_scoring)
return results


def slice_epitope_predictions(
epitope_predictions,
start_offset,
end_offset):
"""
Return subset of EpitopePrediction objects which overlap the given interval
and slice through their source sequences and adjust their offset.
"""
return [
EpitopePrediction(
allele=p.allele,
peptide_sequence=p.peptide_sequence,
wt_peptide_sequence=p.wt_peptide_sequence,
length=p.length,
ic50=p.ic50,
wt_ic50=p.wt_ic50,
percentile_rank=p.percentile_rank,
prediction_method_name=p.prediction_method_name,
overlaps_mutation=p.overlaps_mutation,
source_sequence=p.source_sequence[start_offset:end_offset],
offset=p.offset - start_offset,
occurs_in_reference=p.occurs_in_reference)
for p in epitope_predictions
if p.offset >= start_offset and p.offset + p.length <= end_offset
]
2 changes: 0 additions & 2 deletions vaxrank/gene_pathway_check.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Copyright (c) 2018. 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
Expand Down
2 changes: 0 additions & 2 deletions vaxrank/manufacturability.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Copyright (c) 2016. 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
Expand Down

0 comments on commit 926405e

Please sign in to comment.