Beispiel #1
0
    def test_neofox(self):
        """
        This test is equivalent to the command line call:
        neofox --candidate-file /projects/SUMMIT/WP1.2/neofox/development/Pt29.sequences4testing.txt --patient-id Pt29
        --patients-data ../resources/patient.pt29.csv

        NOTE: we will need to check the output when the calculation of resuls and printing to stdout have been decoupled
        """
        output_file = pkg_resources.resource_filename(
            neofox.tests.__name__,
            "resources/output_{:%Y%m%d%H%M%S}_neoantigen_candidates_annotated.tsv"
            .format(datetime.now()),
        )
        output_file_neoantigens = pkg_resources.resource_filename(
            neofox.tests.__name__,
            "resources/output_{:%Y%m%d%H%M%S}.neoantigens.tsv".format(
                datetime.now()),
        )
        output_json_neoantigens = pkg_resources.resource_filename(
            neofox.tests.__name__,
            "resources/output_{:%Y%m%d%H%M%S}.neoantigen_candidates.json".
            format(datetime.now()),
        )
        annotations = NeoFox(
            neoantigens=self.neoantigens,
            patient_id=self.patient_id,
            patients=self.patients,
            num_cpus=4,
        ).get_annotations()
        annotation_names = [
            a.name for n in annotations
            for a in n.neofox_annotations.annotations
        ]

        # check it does contain any of the MixMHCpred annotations
        self.assertIn("MixMHC2pred_best_peptide", annotation_names)
        self.assertIn("MixMHC2pred_best_rank", annotation_names)
        self.assertIn("MixMHC2pred_best_allele", annotation_names)
        self.assertIn("MixMHCpred_best_peptide", annotation_names)
        self.assertIn("MixMHCpred_best_score", annotation_names)
        self.assertIn("MixMHCpred_best_rank", annotation_names)
        self.assertIn("MixMHCpred_best_allele", annotation_names)
        # checks it does have some of the NetMHCpan annotations
        self.assertIn("Best_affinity_MHCI_9mer_position_mutation",
                      annotation_names)
        self.assertIn("Best_rank_MHCII_score", annotation_names)

        # writes output
        ModelConverter.annotations2table(neoantigens=annotations).to_csv(
            output_file, sep="\t", index=False)
        ModelConverter._objects2dataframe(annotations).to_csv(
            output_file_neoantigens, sep="\t", index=False)
        with open(output_json_neoantigens, "wb") as f:
            f.write(json.dumps(ModelConverter.objects2json(annotations)))

        # regression test
        self._regression_test_on_output_file(new_file=output_file)
 def test_overriding_patient_id(self):
     candidate_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_data.txt"
     )
     with open(candidate_file) as f:
         self.count_lines = len(f.readlines())
     neoantigens = ModelConverter().parse_candidate_file(candidate_file, patient_id="patientX")
     for n in neoantigens:
         self.assertEqual(n.patient_identifier, "patientX")
     neoantigens = ModelConverter().parse_candidate_file(candidate_file)
     for n in neoantigens:
         self.assertEqual(n.patient_identifier, "Ptx")
Beispiel #3
0
 def _get_test_data(self):
     input_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_model_file.txt")
     data = pd.read_csv(input_file, sep="\t")
     data = data.replace({np.nan: None})
     neoantigens = ModelConverter._neoantigens_csv2objects(data)
     patients_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_patient_file.txt")
     patients = ModelConverter.parse_patients_file(patients_file,
                                                   self.hla_database)
     patient_id = "Pt29"
     return neoantigens, patients, patient_id
Beispiel #4
0
def _read_data(
        candidate_file, json_file, patients_data, patient_id,
        mhc_database: MhcDatabase) -> Tuple[List[Neoantigen], List[Patient]]:
    # parse patient data
    patients = ModelConverter.parse_patients_file(patients_data, mhc_database)
    # parse the neoantigen candidate data
    if candidate_file is not None:
        neoantigens = ModelConverter.parse_candidate_file(
            candidate_file, patient_id)
    else:
        neoantigens = ModelConverter.parse_neoantigens_json_file(json_file)

    return neoantigens, patients
    def test_annotations2short_wide_df(self):

        neoantigens = [
            Neoantigen(
                mutation=Mutation(wild_type_xmer="AAAAAAA", mutated_xmer="AAACAAA", position=[]),
                neofox_annotations=NeoantigenAnnotations(
                    annotations=[
                        Annotation(name="this_name", value="this_value"),
                        Annotation(name="that_name", value="that_value"),
                        Annotation(name="diese_name", value="diese_value"),
                        Annotation(name="das_name", value="das_value"),
                    ]
                )
            ),
            Neoantigen(
                mutation=Mutation(wild_type_xmer="AAAGAAA", mutated_xmer="AAAZAAA", position=[1, 2, 3]),
                neofox_annotations=NeoantigenAnnotations(
                    annotations=[
                        Annotation(name="this_name", value="0"),
                        Annotation(name="that_name", value="1"),
                        Annotation(name="diese_name", value="2"),
                        Annotation(name="das_name", value="3"),
                    ],
                )
            ),
        ]
        df = ModelConverter.annotations2table(neoantigens=neoantigens)
        self.assertEqual(df.shape[0], 2)
        self.assertEqual(df.shape[1], 13)
        self.assertEqual(0, df[df["mutation.position"].transform(lambda x: isinstance(x, list))].shape[0])
    def test_csv_neoantigens2model(self):
        neoantigens_file = pkg_resources.resource_filename(
            neofox.tests.__name__, "resources/test_data_model.txt"
        )
        data = pd.read_csv(neoantigens_file, sep="\t")
        neoantigens = ModelConverter._neoantigens_csv2objects(data)
        self.assertEqual(5, len(neoantigens))
        for n in neoantigens:
            self.assertTrue(isinstance(n, Neoantigen))
            self.assertNotEmpty(n.mutation)
            self.assertNotEmpty(n.patient_identifier)
            self.assertNotEmpty(n.gene)
            self.assertTrue(isinstance(n.mutation, Mutation))
            self.assertNotEmpty(n.mutation.mutated_xmer)
            self.assertNotEmpty(n.mutation.wild_type_xmer)
            self.assertIsNotNone(n.mutation.position)

            # test external annotations
            self._assert_external_annotations(
                expected_external_annotations=["external_annotation_1", "external_annotation_2"],
                neoantigen_annotations=n.external_annotations,
                non_nullable_annotations=["external_annotation_1", "external_annotation_2"]
            )
            for a in n.external_annotations:
                if a.name == "external_annotation_1":
                    self.assertEqual(a.value, "blah1")
                elif a.name == "external_annotation_2":
                    self.assertEqual(a.value, "blah2")
 def test_patients_csv_file2model_without_mhc2(self):
     patients_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/balachandran_supplementary_table1_patients.tsv"
     )
     patients = ModelConverter.parse_patients_file(patients_file, self.hla_database)
     self.assertIsNotNone(patients)
     self.assertIsInstance(patients, list)
     self.assertTrue(len(patients) == 58)
 def test_model2csv(self):
     neoantigen = get_random_neoantigen()
     csv_data = ModelConverter._objects2dataframe([neoantigen])
     self.assertIsNotNone(csv_data)
     self.assertIsInstance(csv_data, pd.DataFrame)
     self.assertEqual(
         neoantigen.dna_variant_allele_frequency,
         csv_data.iloc[0].dnaVariantAlleleFrequency,
     )
 def test_candidate_neoantigens2model_with_mutation_in_column_name(self):
     candidate_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_data_with_mutation_in_column_name.txt"
     )
     with open(candidate_file) as f:
         self.count_lines = len(f.readlines())
     neoantigens = ModelConverter().parse_candidate_file(candidate_file)
     for n in neoantigens:
         self.assertTrue(sum(a.name == "mutation" for a in n.external_annotations) > 0)
Beispiel #10
0
    def test_neomouse(self):
        output_file = pkg_resources.resource_filename(
            neofox.tests.__name__,
            "resources/output_mouse_{:%Y%m%d%H%M%S}_neoantigen_candidates_annotated.tsv"
            .format(datetime.now()),
        )
        output_file_neoantigens = pkg_resources.resource_filename(
            neofox.tests.__name__,
            "resources/output_mouse_{:%Y%m%d%H%M%S}.neoantigens.tsv".format(
                datetime.now()),
        )
        output_json_neoantigens = pkg_resources.resource_filename(
            neofox.tests.__name__,
            "resources/output_mouse_{:%Y%m%d%H%M%S}.neoantigen_candidates.json"
            .format(datetime.now()),
        )
        annotations = NeoFox(
            neoantigens=self.neoantigens_mouse,
            patient_id=self.patient_id,
            patients=self.patients_mouse,
            num_cpus=4,
            reference_folder=self.references_mouse).get_annotations()
        annotation_names = [
            a.name for n in annotations
            for a in n.neofox_annotations.annotations
        ]

        # checks it does have some of the NetMHCpan annotations
        self.assertIn("Best_affinity_MHCI_9mer_position_mutation",
                      annotation_names)
        self.assertIn("Best_rank_MHCII_score", annotation_names)

        # writes output
        ModelConverter.annotations2table(neoantigens=annotations).to_csv(
            output_file, sep="\t", index=False)
        ModelConverter._objects2dataframe(annotations).to_csv(
            output_file_neoantigens, sep="\t", index=False)
        with open(output_json_neoantigens, "wb") as f:
            f.write(json.dumps(ModelConverter.objects2json(annotations)))

        # regression test
        self._regression_test_on_output_file(
            new_file=output_file,
            previous_filename="resources/output_previous_mouse.txt")
Beispiel #11
0
def _write_results(neoantigens, output_folder, output_prefix, with_json,
                   with_table):
    # NOTE: this import here is a compromise solution so the help of the command line responds faster
    from neofox.model.conversion import ModelConverter
    # writes the output
    if with_table:
        ModelConverter.annotations2table(neoantigens).to_csv(
            os.path.join(
                output_folder,
                "{}_neoantigen_candidates_annotated.tsv".format(output_prefix),
            ),
            sep="\t",
            index=False,
        )
    if with_json:
        output_features = os.path.join(
            output_folder,
            "{}_neoantigen_candidates_annotated.json".format(output_prefix))
        with open(output_features, "wb") as f:
            f.write(json.dumps(ModelConverter.objects2json(neoantigens)))
Beispiel #12
0
    def test_neofox_synthetic_data(self):
        """
        this test just ensures that NeoFox does not crash with the synthetic data
        """
        data = [
            ("resources/synthetic_data/neoantigens_1patients_10neoantigens.2.txt",
             "resources/synthetic_data/patients_1patients_10neoantigens.2.txt"
             ),
            ("resources/synthetic_data/neoantigens_10patients_10neoantigens.0.txt",
             "resources/synthetic_data/patients_10patients_10neoantigens.0.txt"
             ),
            #("resources/synthetic_data/neoantigens_100patients_10neoantigens.2.txt",
            # "resources/synthetic_data/patients_100patients_10neoantigens.2.txt"),

            #("resources/synthetic_data/neoantigens_no_wt_1patients_10neoantigens.3.txt",
            # "resources/synthetic_data/patients_no_wt_1patients_10neoantigens.3.txt"),
            #("resources/synthetic_data/poltergeist_neoantigens.txt",
            # "resources/synthetic_data/poltergeist_patients.txt")
            ("resources/synthetic_data/neoantigens_no_wt_10patients_10neoantigens.4.txt",
             "resources/synthetic_data/patients_no_wt_10patients_10neoantigens.4.txt"
             ),
            #("resources/synthetic_data/neoantigens_100patients_10neoantigens.4.txt",
            # "resources/synthetic_data/patients_100patients_10neoantigens.4.txt"),
        ]

        for n, p, in data:
            input_file = pkg_resources.resource_filename(
                neofox.tests.__name__, n)
            data = pd.read_csv(input_file, sep="\t")
            data = data.replace({np.nan: None})
            neoantigens = ModelConverter._neoantigens_csv2objects(data)
            patients_file = pkg_resources.resource_filename(
                neofox.tests.__name__, p)
            patients = ModelConverter.parse_patients_file(
                patients_file, self.hla_database)
            annotations = NeoFox(
                neoantigens=neoantigens,
                patients=patients,
                num_cpus=4,
            ).get_annotations()
            self.assertIsNotNone(annotations)
 def test_no_expression_imputation(self):
     input_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_candidate_file.txt"
     )
     patients_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_patient_file.txt"
     )
     patients = ModelConverter.parse_patients_file(patients_file, self.hla_database)
     neoantigens = ModelConverter.parse_candidate_file(input_file)
     neofox_runner = NeoFox(
         neoantigens=neoantigens,
         patients=patients,
         reference_folder=FakeReferenceFolder(),
         configuration=FakeDependenciesConfiguration(),
     )
     for neoantigen in neoantigens:
         for neoantigen_imputed in neofox_runner.neoantigens:
             if neoantigen.mutation.mutated_xmer == neoantigen_imputed.mutation.mutated_xmer:
                 self.assertEqual(
                     neoantigen.rna_expression, neoantigen_imputed.rna_expression
                 )
Beispiel #14
0
 def setUp(self):
     self.references, self.configuration = integration_test_tools.load_references(
     )
     self.references_mouse, self.configuration_mouse = integration_test_tools.load_references(
         organism=ORGANISM_MUS_MUSCULUS)
     # self.fastafile = integration_test_tools.create_temp_aminoacid_fasta_file()
     # self.runner = Runner()
     self.patient_id = "Pt29"
     input_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_candidate_file.txt")
     patients_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_patient_file.txt")
     patients_file_mouse = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_patient_file_mouse.txt")
     self.hla_database = self.references.get_mhc_database()
     self.h2_database = self.references_mouse.get_mhc_database()
     self.patients = ModelConverter.parse_patients_file(
         patients_file, self.hla_database)
     self.patients_mouse = ModelConverter.parse_patients_file(
         patients_file_mouse, self.h2_database)
     self.neoantigens = ModelConverter.parse_candidate_file(input_file)
     self.neoantigens_mouse = ModelConverter.parse_candidate_file(
         input_file)
    def test_with_expression_imputation(self):
        input_file = pkg_resources.resource_filename(
            neofox.tests.__name__, "resources/test_candidate_file_Pty.txt"
        )
        neoantigens= ModelConverter.parse_candidate_file(input_file)
        import copy

        original_neoantigens = copy.deepcopy(neoantigens)
        patients_file = pkg_resources.resource_filename(
            neofox.tests.__name__, "resources/test_patient_file.txt"
        )
        patients = ModelConverter.parse_patients_file(patients_file, self.hla_database)
        neofox_runner = NeoFox(
            neoantigens=neoantigens,
            patients=patients,
            reference_folder=FakeReferenceFolder(),
            configuration=FakeDependenciesConfiguration(),
        )
        for neoantigen in original_neoantigens:
            for neoantigen_imputed in neofox_runner.neoantigens:
                self.assertFalse(
                    neoantigen.rna_expression == neoantigen_imputed.rna_expression
                )
 def test_json_neoantigens2model(self):
     neoantigens_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_data_json.json"
     )
     neoantigens = ModelConverter.parse_neoantigens_json_file(neoantigens_file)
     self.assertEqual(5, len(neoantigens))
     for n in neoantigens:
         self.assertTrue(isinstance(n, Neoantigen))
         self.assertNotEmpty(n.mutation)
         self.assertNotEmpty(n.patient_identifier)
         self.assertNotEmpty(n.rna_expression)
         self.assertNotEmpty(n.rna_variant_allele_frequency)
         self.assertNotEmpty(n.dna_variant_allele_frequency)
         self.assertTrue(isinstance(n.mutation, Mutation))
         self.assertNotEmpty(n.mutation.position)
Beispiel #17
0
 def test_neofox_only_one_neoantigen(self):
     """"""
     input_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_data_only_one.txt")
     neoantigens = ModelConverter.parse_candidate_file(input_file)
     annotations = NeoFox(
         neoantigens=neoantigens,
         patient_id=self.patient_id,
         patients=self.patients,
         num_cpus=4,
     ).get_annotations()
     self.assertEqual(1, len(annotations))
     self.assertIsInstance(annotations[0], Neoantigen)
     self.assertTrue(
         len(annotations[0].neofox_annotations.annotations) > 10)
Beispiel #18
0
    def test_neofox_performance_single_neoantigen(self):

        input_file = pkg_resources.resource_filename(
            neofox.tests.__name__, "resources/test_data_only_one.txt")
        neoantigens, _ = ModelConverter.parse_candidate_file(input_file)

        def compute_annotations():
            return NeoFox(
                neoantigens=neoantigens,
                patient_id=self.patient_id,
                patients=self.patients,
                num_cpus=4,
            ).get_annotations()

        print("Average time: {}".format(
            timeit.timeit(compute_annotations, number=10)))
 def test_patients_csv_file2model_mouse(self):
     patients_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/alleles.Pt29_mouse.csv"
     )
     patients = ModelConverter.parse_patients_file(patients_file, self.h2_database)
     self.assertIsNotNone(patients)
     self.assertIsInstance(patients, list)
     self.assertTrue(len(patients) == 1)
     self.assertIsInstance(patients[0], Patient)
     self.assertEqual(patients[0].identifier, "Pt29")
     self.assertEqual(3, len(patients[0].mhc1))
     self.assertEqual(6, len([a for m in patients[0].mhc1 for a in m.alleles]))
     self.assertEqual(2, len(patients[0].mhc2))
     self.assertEqual(
         3, len([a for m in patients[0].mhc2 for g in m.genes for a in g.alleles])
     )
     self.assertEqual(patients[0].is_rna_available, False)
 def test_patients_csv_file2model_without_mhc1(self):
     patients_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/patient.Pt29.without_mhc1.csv"
     )
     patients = ModelConverter.parse_patients_file(patients_file, self.hla_database)
     self.assertIsNotNone(patients)
     self.assertIsInstance(patients, list)
     self.assertTrue(len(patients) == 1)
     self.assertIsInstance(patients[0], Patient)
     self.assertEqual(patients[0].identifier, "Pt29")
     for m in patients[0].mhc1:
         self.assertEqual(m.zygosity, Zygosity.LOSS)
     self.assertEqual(3, len(patients[0].mhc2))
     self.assertEqual(
         9, len([a for m in patients[0].mhc2 for g in m.genes for a in g.alleles])
     )
     self.assertEqual(patients[0].is_rna_available, True)
 def test_patients_csv_file2model3(self):
     patients_file = pkg_resources.resource_filename(
         neofox.tests.__name__, "resources/test_patient_info.txt"
     )
     patients = ModelConverter.parse_patients_file(patients_file, self.hla_database)
     self.assertIsNotNone(patients)
     self.assertIsInstance(patients, list)
     self.assertTrue(len(patients) == 1)
     self.assertIsInstance(patients[0], Patient)
     self.assertEqual(patients[0].identifier, "Ptx")
     self.assertEqual(3, len(patients[0].mhc1))
     self.assertEqual(6, len([a for m in patients[0].mhc1 for a in m.alleles]))
     self.assertEqual(3, len(patients[0].mhc2))
     self.assertEqual(
         10, len([a for m in patients[0].mhc2 for g in m.genes for a in g.alleles])
     )
     self.assertTrue(
         "HLA-A*03:01" in [a.name for m in patients[0].mhc1 for a in m.alleles]
     )
     self.assertTrue(
         "HLA-DQA1*04:01"
         in [a.name for m in patients[0].mhc2 for g in m.genes for a in g.alleles]
     )
     self.assertTrue(patients[0].is_rna_available)
 def test_model2csv2model(self):
     neoantigen = get_random_neoantigen()
     csv_data = ModelConverter._objects2dataframe([neoantigen])
     neoantigen2 = ModelConverter._neoantigens_csv2objects(csv_data)[0]
     self.assertEqual(neoantigen, neoantigen2)
 def _write_data(self, neoantigens: List[Neoantigen], neoantigens_filename,
                patients: List[Patient], patients_filename):
     ModelConverter._neoantigens2table(neoantigens).to_csv(neoantigens_filename, sep="\t", index=False)
     ModelConverter.patients2table(patients).to_csv(patients_filename, sep="\t", index=False)
    def test_candidate_neoantigens2model(self):
        candidate_file = pkg_resources.resource_filename(
            neofox.tests.__name__, "resources/test_data.txt"
        )
        with open(candidate_file) as f:
            self.count_lines = len(f.readlines())
        neoantigens = ModelConverter().parse_candidate_file(candidate_file)
        self.assertIsNotNone(neoantigens)
        self.assertEqual(self.count_lines -1, len(neoantigens))
        for n in neoantigens:
            self.assertIsInstance(n, Neoantigen)
            self.assertIsInstance(n.mutation, Mutation)
            self.assertTrue(n.gene is not None and len(n.gene) > 0)
            self.assertTrue(
                n.mutation.mutated_xmer is not None and len(n.mutation.mutated_xmer) > 1
            )
            self.assertTrue(
                n.mutation.wild_type_xmer is not None
                and len(n.mutation.wild_type_xmer) > 1
            )
            self.assertTrue(
                n.mutation.position is not None and len(n.mutation.position) >= 1
            )
            self.assertTrue(
                n.rna_variant_allele_frequency is None
                or n.rna_variant_allele_frequency == -1
                or (0 <= n.rna_variant_allele_frequency <= 1)
            )
            self.assertTrue(n.rna_expression is None or n.rna_expression >= 0)
            self.assertTrue(0 <= n.dna_variant_allele_frequency <= 1)

            # test external annotations
            self._assert_external_annotations(
                expected_external_annotations=[
                    "patient",
                    "key",
                    "mutation",
                    "RefSeq_transcript",
                    "UCSC_transcript",
                    "transcript_expression",
                    "exon",
                    "exon_expression",
                    "transcript_position",
                    "codon",
                    "substitution",
                    "+-13_AA_(SNV)_/_-15_AA_to_STOP_(INDEL)",
                    "[WT]_+-13_AA_(SNV)_/_-15_AA_to_STOP_(INDEL)",
                    "mRNA_for_+13_AA_(SNV)_/_-15_AA_to_STOP_(INDEL)",
                    "MHC_I_peptide_length_(best_prediction)",
                    "MHC_I_allele_(best_prediction)",
                    "MHC_I_score_(best_prediction)",
                    "MHC_I_epitope_(best_prediction)",
                    "MHC_I_epitope_(WT)",
                    "MHC_I_score_(WT)",
                    "MHC_II_peptide_length_(best_prediction)",
                    "MHC_II_allele_(best_prediction)",
                    "MHC_II_score_(best_prediction)",
                    "MHC_II_epitope_(best_prediction)",
                    "MHC_II_epitope_(WT)",
                    "MHC_II_score_(WT)",
                    "mutations_in_transcript",
                    "distance_to_next_mutation(AA_residues)",
                    "next_mutation(potential_to_change_27mer)",
                    "next_mutation_source",
                    "peptide_count_for_this_mutation_in_this_transcript",
                    "phase_of_next_mutation",
                    "other_transcripts_with_this_peptide",
                    "peptide_resulting_from_this_mutation",
                    "distinct_peptides_resulting_from_this_mutation",
                    "keys_of_distinct_peptides_resulting_from_this_mutation",
                    "coverage_tumor",
                    "coverage_normal",
                    "coverage_RNA",
                    "VAF_in_tumor",
                    "VAF_in_normal",
                    "VAF_in_RNA",
                    "VAF_RNA_raw",
                    "VAF_RNA_limits"
                ],
                non_nullable_annotations=[
                    "patient",
                    "key",
                    "mutation",
                    "RefSeq_transcript",
                    "UCSC_transcript",
                    "transcript_expression",
                    "exon",
                    "exon_expression",
                    "transcript_position",
                    "codon",
                    "+-13_AA_(SNV)_/_-15_AA_to_STOP_(INDEL)",
                    "[WT]_+-13_AA_(SNV)_/_-15_AA_to_STOP_(INDEL)"
                ],
                neoantigen_annotations=n.external_annotations,
            )