Skip to content

Commit

Permalink
working on centralizing config information in msgspec.Struct objects
Browse files Browse the repository at this point in the history
  • Loading branch information
iskandr committed May 28, 2024
1 parent e11085d commit b13a543
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 98 deletions.
66 changes: 4 additions & 62 deletions vaxrank/cli/parser.py → vaxrank/cli/arg_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import sys
import logging
import logging.config
import pkg_resources

import msgspec

from argparse import ArgumentParser

from isovar.cli import make_isovar_arg_parser
from mhctools.cli import add_mhc_args

import pandas as pd
import serializable


from .version import __version__
from .core_logic import run_vaxrank
from .epitope_config import DEFAULT_MIN_EPITOPE_SCORE
from .gene_pathway_check import GenePathwayCheck
from .report import (
make_ascii_report,
make_html_report,
make_pdf_report,
make_csv_report,
make_minimal_neoepitope_report,
TemplateDataCreator,
)
from .patient_info import PatientInfo
from .epitope_config import epitope_config_from_args
from .epitope_config_args import add_epitope_prediction_args
from .vaccine_config_args import add_vaccine_peptide_args
from ..version import __version__

logger = logging.getLogger(__name__)


def make_vaxrank_arg_parser():
Expand Down Expand Up @@ -199,39 +180,6 @@ def add_output_args(arg_parser):
help="Number of mutations to report")


def add_vaccine_peptide_args(arg_parser):
vaccine_peptide_group = arg_parser.add_argument_group("Vaccine peptide options")
vaccine_peptide_group.add_argument(
"--vaccine-peptide-length",
default=25,
type=int,
help="Number of amino acids in the vaccine peptides. (default: %(default)s)")

vaccine_peptide_group.add_argument(
"--padding-around-mutation",
default=5,
type=int,
help=(
"Number of off-center windows around the mutation to consider "
"as vaccine peptides. (default: %(default)s)"
))

vaccine_peptide_group.add_argument(
"--max-vaccine-peptides-per-mutation",
default=1,
type=int,
help=(
"Number of vaccine peptides to generate for each mutation. "
"(default: %(default)s)"
))

vaccine_peptide_group.add_argument(
"--num-epitopes-per-vaccine-peptide",
type=int,
help=(
"Maximum number of mutant epitopes to consider when scoring "
"each vaccine peptide. (default: %(default)s)"))


def add_supplemental_report_args(arg_parser):
report_args_group = arg_parser.add_argument_group("Supplemental report options")
Expand Down Expand Up @@ -262,12 +210,6 @@ def check_args(args):
"--output-passing-variants-csv, "
"--output-isovar-csv")

def configure_logging(args):
logging.config.fileConfig(
pkg_resources.resource_filename(
__name__,
'logging.conf'),
defaults={'logfilename': args.log_path})

def choose_arg_parser(args_list):
# TODO: replace this with a command sub-parser
Expand Down
26 changes: 24 additions & 2 deletions vaxrank/cli/entry_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,30 @@
# limitations under the License.



import logging
import logging.config

import sys
import pkg_resources


import pandas as pd
import serializable


from varcode.cli import variant_collection_from_args
from isovar import isovar_results_to_dataframe
from mhctools.cli import (
mhc_alleles_from_args,
mhc_binding_predictor_from_args,
)

from .parser import parse_vaxrank_args
from ..core_logic import run_vaxrank
from .arg_parser import parse_vaxrank_args
from .epitope_config_args import epitope_config_from_args
from .vaccine_config_args import vaccine_config_from_args

from ..core_logic import run_vaxrank, run_vaxrank_from_parsed_args
from ..gene_pathway_check import GenePathwayCheck
from ..report import (
make_ascii_report,
Expand All @@ -34,6 +46,16 @@
)
from ..patient_info import PatientInfo

logger = logging.getLogger(__name__)

def configure_logging(args):
logging.config.fileConfig(
pkg_resources.resource_filename(
__name__,
'logging.conf'),
defaults={'logfilename': args.log_path})


def main(args_list=None):
"""
Script to generate vaccine peptide predictions from somatic cancer variants,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import msgspec

import argparse

DEFAULT_MIN_EPITOPE_SCORE = 0.00001
DEFAULT_BINDING_AFFINITY_CUTOFF = 5000.0

class EpitopeConfig(msgspec.Struct):
import msgspec

"""Parameters for score, filtering, and ranking both epitopes and vaccine peptides"""
logistic_epitope_score_midpoint : float = 350.0
logistic_epitope_score_width : float = 150.0

min_epitope_score : float = DEFAULT_MIN_EPITOPE_SCORE
binding_affinity_cutoff : float = DEFAULT_BINDING_AFFINITY_CUTOFF
from ..epitope_config import EpitopeConfig


def add_epitope_prediction_args(arg_parser : argparse.ArgumentParser):
Expand Down
70 changes: 70 additions & 0 deletions vaxrank/cli/vaccine_config_args.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# 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.

import argparse

import msgspec

from ..vaccine_config import VaccineConfig



def add_vaccine_peptide_args(arg_parser : argparse.ArgumentParser) -> None:
vaccine_peptide_group = arg_parser.add_argument_group("Vaccine peptide options")
vaccine_peptide_group.add_argument(
"--vaccine-peptide-length",
default=25,
type=int,
help="Number of amino acids in the vaccine peptides. (default: %(default)s)")

vaccine_peptide_group.add_argument(
"--padding-around-mutation",
default=5,
type=int,
help=(
"Number of off-center windows around the mutation to consider "
"as vaccine peptides. (default: %(default)s)"
))

vaccine_peptide_group.add_argument(
"--max-vaccine-peptides-per-mutation",
default=1,
type=int,
help=(
"Number of vaccine peptides to generate for each mutation. "
"(default: %(default)s)"
))

vaccine_peptide_group.add_argument(
"--num-epitopes-per-vaccine-peptide",
type=int,
help=(
"Maximum number of mutant epitopes to consider when scoring "
"each vaccine peptide. (default: %(default)s)"))





def vaccine_config_from_args(args : argparse.Namespace) -> VaccineConfig:
"""
Extract config path and overrides from argument namespace
"""
epitope_config_kwargs = {}
if args.epitope_prediction_config:
with open(args.epitope_prediction_config) as f:
epitope_config_kwargs.update(msgspec.yaml.decode(f.read()))

if args.min_epitope_score is not None:
epitope_config_kwargs["min_epitope_score"] = args.min_epitope_score
epitope_config = msgspec.convert(epitope_config_kwargs, EpitopeConfig)
return epitope_config
41 changes: 25 additions & 16 deletions vaxrank/core_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from mhctools.base_predictor import BasePredictor

from .epitope_config import EpitopeConfig
from .vaccine_config import VaccineConfig
from .epitope_logic import slice_epitope_predictions, predict_epitopes
from .mutant_protein_fragment import MutantProteinFragment
from .vaccine_peptide import VaccinePeptide
Expand All @@ -32,7 +33,8 @@ def run_vaxrank(
vaccine_peptide_length : int = 25,
max_vaccine_peptides_per_variant : int = 1,
num_mutant_epitopes_to_keep : int = 10000,
config : EpitopeConfig = None):
epitope_config : EpitopeConfig = None,
vaccine_config : VaccineConfig = None):
"""
Parameters
----------
Expand All @@ -54,16 +56,20 @@ def run_vaxrank(
Number of top-ranking epitopes for each vaccine peptide to include in
computation.
config
epitope_config
Configuration options for epitope scoring, using defaults if not provided
vaccine_config
Configuration options for vaccine peptide selection, using defaults if not provided
"""
variant_to_vaccine_peptides_dict = create_vaccine_peptides_dict(
isovar_results=isovar_results,
mhc_predictor=mhc_predictor,
vaccine_peptide_length=vaccine_peptide_length,
max_vaccine_peptides_per_variant=max_vaccine_peptides_per_variant,
num_mutant_epitopes_to_keep=num_mutant_epitopes_to_keep,
config=config)
epitope_config=epitope_config,
vaccine_config=vaccine_config)
ranked_list = ranked_vaccine_peptides(variant_to_vaccine_peptides_dict)

return VaxrankResults(
Expand All @@ -78,7 +84,8 @@ def create_vaccine_peptides_dict(
vaccine_peptide_length : int = 25,
max_vaccine_peptides_per_variant : int = 1,
num_mutant_epitopes_to_keep : int = 10 ** 5,
config : EpitopeConfig = None):
epitope_config : EpitopeConfig = None,
vaccine_config : VaccineConfig = None):
"""
Parameters
----------
Expand All @@ -99,9 +106,11 @@ def create_vaccine_peptides_dict(
Number of top-ranking epitopes for each vaccine peptide to include in
computation.
config
epitope_config
Configuration options for epitope scoring, using defaults if not provided
vaccine_config
Configuration options for vaccine peptide selection, using defaults if not provided
Returns
-------
Expand All @@ -117,7 +126,8 @@ def create_vaccine_peptides_dict(
vaccine_peptide_length=vaccine_peptide_length,
max_vaccine_peptides_per_variant=max_vaccine_peptides_per_variant,
num_mutant_epitopes_to_keep=num_mutant_epitopes_to_keep,
config=config)
epitope_config=epitope_config,
vaccine_config=vaccine_config)

if any(x.contains_mutant_epitopes() for x in vaccine_peptides):
vaccine_peptides_dict[variant] = vaccine_peptides
Expand All @@ -130,7 +140,8 @@ def vaccine_peptides_for_variant(
vaccine_peptide_length : int,
max_vaccine_peptides_per_variant : int,
num_mutant_epitopes_to_keep : int = None,
config : EpitopeConfig = None):
epitope_config : EpitopeConfig = None,
vaccine_config : VaccineConfig = None):
"""
Parameters
----------
Expand All @@ -146,14 +157,10 @@ def vaccine_peptides_for_variant(
max_vaccine_peptides_per_variant
Number of vaccine peptides to generate for each mutation.
num_mutant_epitopes_to_keep : int, optional
num_mutant_epitopes_to_keep
Number of top-ranking epitopes for each vaccine peptide to include in
computation.
min_epitope_score : float, optional
Ignore peptides with binding predictions whose normalized score is less
than this.
Returns
-------
Sorted list of VaccinePeptide objects. If there are no suitable vaccine
Expand All @@ -175,9 +182,11 @@ def vaccine_peptides_for_variant(
epitope_predictions = predict_epitopes(
mhc_predictor=mhc_predictor,
protein_fragment=long_protein_fragment,
config=config,
epitope_config=epitope_config,
genome=variant.ensembl).values()


# TODO: make a function called vaccine_peptides_from_epitopes that
# takes vaccine_config as an option
candidate_vaccine_peptides = []

for offset, candidate_fragment in long_protein_fragment.sorted_subsequences(
Expand Down
25 changes: 25 additions & 0 deletions vaxrank/epitope_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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.

import msgspec

DEFAULT_MIN_EPITOPE_SCORE = 0.00001
DEFAULT_BINDING_AFFINITY_CUTOFF = 5000.0

class EpitopeConfig(msgspec.Struct):

"""Parameters for score, filtering, and ranking both epitopes and vaccine peptides"""
logistic_epitope_score_midpoint : float = 350.0
logistic_epitope_score_width : float = 150.0

min_epitope_score : float = DEFAULT_MIN_EPITOPE_SCORE
binding_affinity_cutoff : float = DEFAULT_BINDING_AFFINITY_CUTOFF
Loading

0 comments on commit b13a543

Please sign in to comment.