diff --git a/VariantValidator/modules/mappers.py b/VariantValidator/modules/mappers.py index da933e29..6416816c 100644 --- a/VariantValidator/modules/mappers.py +++ b/VariantValidator/modules/mappers.py @@ -759,18 +759,28 @@ def transcripts_to_gene(variant, validator, select_transcripts_dict_plus_version hgvs_refseq = 'RefSeqGene record not available' # Predicted effect on protein + logger.info(f"Translating {hgvs_coding} in transcripts_to_gene") try: protein_dict = validator.myc_to_p(hgvs_coding, variant.evm, re_to_p=False, hn=variant.hn) except NotImplementedError as e: + # import traceback + # traceback.print_exc() logger.info(f"Protein dict creation failed with exception: {str(e)}") protein_dict = {'hgvs_protein': None, 'error': str(e)} variant.warnings.append(str(e)) except vvhgvs.exceptions.HGVSDataNotAvailableError as e: + # import traceback + # traceback.print_exc() + logger.info(f"Protein dict creation failed with exception: {str(e)}") protein_dict = {'hgvs_protein': None, 'error': str(e)} variant.warnings.append(str(e)) + else: + logger.info(f"Protein dict creation successful: {protein_dict}") - if protein_dict['error'] == '': + if protein_dict['error'] == '' or protein_dict['error'].startswith('ProteinTranslationInfo:'): hgvs_protein = protein_dict['hgvs_protein'] + if protein_dict['error']: + variant.warnings.append(protein_dict['error']) else: error = protein_dict['error'] if not error.startswith('ProteinTranslationError:' ): @@ -829,8 +839,10 @@ def transcripts_to_gene(variant, validator, select_transcripts_dict_plus_version try: # Predicted effect on protein protein_dict = validator.myc_to_p(c_for_p, variant.evm, re_to_p=False, hn=variant.hn) - if protein_dict['error'] == '': + if protein_dict['error'] == '' or protein_dict['error'].startswith('ProteinTranslationInfo:'): hgvs_protein = protein_dict['hgvs_protein'] + if protein_dict['error']: + variant.warnings.append(protein_dict['error']) else: error = protein_dict['error'] if error == 'Cannot identify an in-frame Termination codon in the variant mRNA sequence': @@ -846,8 +858,10 @@ def transcripts_to_gene(variant, validator, select_transcripts_dict_plus_version if hgvs_coding.posedit.pos.start.offset == 0 and hgvs_coding.posedit.pos.start.offset == 0 and \ '?' in str(hgvs_protein): protein_dict = validator.myc_to_p(hgvs_coding, variant.evm, re_to_p=False, hn=variant.hn) - if protein_dict['error'] == '': + if protein_dict['error'] == '' or protein_dict['error'].startswith('ProteinTranslationInfo:'): hgvs_protein = protein_dict['hgvs_protein'] + if protein_dict['error']: + variant.warnings.append(protein_dict['error']) else: error = protein_dict['error'] if error == 'Cannot identify an in-frame Termination codon in the variant mRNA sequence': diff --git a/VariantValidator/modules/seq_data.py b/VariantValidator/modules/seq_data.py index 6d267aab..f483cd28 100644 --- a/VariantValidator/modules/seq_data.py +++ b/VariantValidator/modules/seq_data.py @@ -1742,7 +1742,6 @@ def to_accession(chr_num, primary_assembly): 'HSCHR1_6_CTG31': 'NW_025791755.1', 'HG1384_PATCH': 'NW_021159988.1', 'HG2231_HG2496_PATCH': 'NW_025791767.1', - 'NW_025791768.1': 'NW_025791768.1', 'HG2052_PATCH' : 'NW_025791766.1', 'HSCHR2_6_CTG1': 'NW_025791763.1', 'HSCHR2_10_CTG7_2': 'NW_025791760.1', @@ -3305,7 +3304,6 @@ def to_chr_num_refseq(accession, primary_assembly): 'NW_025791755.1': 'HSCHR1_6_CTG31', 'NW_021159988.1': 'HG1384_PATCH', 'NW_025791767.1': 'HG2231_HG2496_PATCH', - 'NW_025791768.1': 'NW_025791768.1', 'NW_025791766.1': 'HG2052_PATCH', 'NW_025791763.1': 'HSCHR2_6_CTG1', 'NW_025791760.1': 'HSCHR2_10_CTG7_2', diff --git a/VariantValidator/modules/utils.py b/VariantValidator/modules/utils.py index 928c60d5..2d873b3e 100644 --- a/VariantValidator/modules/utils.py +++ b/VariantValidator/modules/utils.py @@ -294,6 +294,7 @@ def pro_inv_info(prot_ref_seq, prot_var_seq): """ Function which predicts the protein effect of c. inversions """ + logger.info("pro_inv_info function called") info = { 'variant': 'true', 'prot_del_seq': '', @@ -392,6 +393,7 @@ def pro_inv_info(prot_ref_seq, prot_var_seq): def pro_delins_info(prot_ref_seq, prot_var_seq, in_frame=False): + logger.info(f"pro_delins_info function called") info = { 'variant': 'true', 'prot_del_seq': '', diff --git a/VariantValidator/modules/vvMixinInit.py b/VariantValidator/modules/vvMixinInit.py index 47a2f838..b9b24e5b 100644 --- a/VariantValidator/modules/vvMixinInit.py +++ b/VariantValidator/modules/vvMixinInit.py @@ -14,10 +14,12 @@ import vvhgvs.edit import vvhgvs.normalizer from vvhgvs.location import AAPosition, Interval -from vvhgvs.edit import AARefAlt, AAExt, Dup +from vvhgvs.edit import AARefAlt, AAExt, Dup, AAFs +from vvhgvs.posedit import PosEdit from Bio.Seq import Seq import re +import logging from .vvDatabase import Database from . import utils from VariantValidator.settings import CONFIG_DIR @@ -25,6 +27,8 @@ from VariantValidator.modules.hgvs_utils import hgvs_delins_parts_to_hgvs_obj,\ VVPosEdit +logger = logging.getLogger(__name__) + class InitialisationError(Exception): pass @@ -246,6 +250,7 @@ def my_config(self): } def myc_to_p(self, hgvs_transcript, evm, re_to_p, hn): + logger.info(f"Translating {hgvs_transcript} to with myc_to_p") # Create dictionary to store the information hgvs_transcript_to_hgvs_protein = {'error': '', 'hgvs_protein': '', 'ref_residues': ''} @@ -287,6 +292,7 @@ def _fb_unc(prot,base): aa=base)), edit = "", # this sets the response to ? uncertain = True)) + # same for unknown without set pos def _tot_unc(prot): return vvhgvs.sequencevariant.SequenceVariant( @@ -296,6 +302,7 @@ def _tot_unc(prot): pos=Interval(),# empty interval start means '' edit = "", # this sets the response to ? uncertain=True)) + # recreate obj to set PosEdit to a VVPosEdit, to handle formatting def _remake_unc(prot,nucleotide_not_equal=False): if prot.posedit is None: @@ -310,9 +317,12 @@ def _remake_unc(prot,nucleotide_not_equal=False): nucleotide_not_equal=nucleotide_not_equal )) - # Handle non inversions with simple c_to_p mapping - if hgvs_transcript.posedit.edit.type not in ['inv', 'dup', 'delins', 'sub', 'identity'] and (re_to_p is False): + # Handle unlisted variant types with simple c_to_p mapping + if (hgvs_transcript.posedit.edit.type not in ['inv', 'dup', 'delins', 'sub', 'identity', 'del', 'ins'] + and (re_to_p is False)): + logger.info(f"Passing {hgvs_transcript} into simple c_to_p mapping") hgvs_protein = None + # Does the edit affect the start codon? if ((1 <= hgvs_transcript.posedit.pos.start.base <= 3 and hgvs_transcript.posedit.pos.start.offset == 0) or (1 <= hgvs_transcript.posedit.pos.end.base <= 3 and hgvs_transcript.posedit.pos.end.offset @@ -361,6 +371,7 @@ def _remake_unc(prot,nucleotide_not_equal=False): # Note, this code was developed for VariantValidator and is not native to the biocommons hgvs # Python package # Convert positions to n. position + logger.info(f"Passing {hgvs_transcript} into VV handled c_to_p mapping") hgvs_naughty = self.vm.c_to_n(hgvs_transcript) # Collect the deleted sequence using fetch_seq @@ -382,6 +393,8 @@ def _remake_unc(prot,nucleotide_not_equal=False): inv_seq = hgvs_transcript.posedit.edit.alt elif 'identity' in hgvs_transcript.posedit.edit.type: inv_seq = hgvs_transcript.posedit.edit.ref + elif 'ins' in hgvs_transcript.posedit.edit.type: + inv_seq = f"{del_seq[0]}{hgvs_transcript.posedit.edit.alt}{del_seq[-1]}" shifts = '' # Look for p. delins or del @@ -452,19 +465,27 @@ def _remake_unc(prot,nucleotide_not_equal=False): hgvs_naughty.posedit.pos.start.base, hgvs_naughty.posedit.pos.end.base) + logger.info(f"\nReference sequence:\n{ref_seq}\nDeletion sequence:\n{del_seq}\nInserted sequence:\n{inv_seq}\nVar sequence:\n{var_seq}") + # Check for modified amino acids prot_seq = self.sf.fetch_seq(associated_protein_accession) if "U" in prot_seq: modified_aa = "Sec" + hgvs_transcript_to_hgvs_protein['error'] = \ + 'ProteinTranslationInfo: Selenocysteine detected in the original protein sequnce'+\ + ' it may be incorporated instead of terminating at TGA/UGA termination codons' + logger.info(f"Modified amino acid {modified_aa} identified, update translation dict") else: modified_aa = None + logger.info("No modified amino acid identified, use standard translation dict") # Translate the reference and variant proteins + logger.info("Translating reference and variant CDS outcomes") try: prot_ref_seq = utils.translate(ref_seq, cds_start, modified_aa) except IndexError: - import traceback - traceback.print_exc() + # import traceback + # traceback.print_exc() hgvs_transcript_to_hgvs_protein['error'] = \ 'ProteinTranslationError: Cannot generate a protein without an identifiable in-' +\ 'frame Termination codon in the reference mRNA sequence, this transcript may be ' +\ @@ -472,8 +493,8 @@ def _remake_unc(prot,nucleotide_not_equal=False): hgvs_transcript_to_hgvs_protein['hgvs_protein'] = _tot_unc(associated_protein_accession) return hgvs_transcript_to_hgvs_protein except KeyError: - import traceback - traceback.print_exc() + # import traceback + # traceback.print_exc() hgvs_transcript_to_hgvs_protein['error'] = \ 'ProteinTranslationError: Unable to build protein sequence due to a non-CATG ' +\ 'base included in the reference mRNA sequence, only standard unambiguous bases '+\ @@ -481,7 +502,6 @@ def _remake_unc(prot,nucleotide_not_equal=False): hgvs_transcript_to_hgvs_protein['hgvs_protein'] = _tot_unc(associated_protein_accession) return hgvs_transcript_to_hgvs_protein - try: prot_var_seq = utils.translate(var_seq, cds_start, modified_aa) except IndexError: @@ -499,6 +519,8 @@ def _remake_unc(prot,nucleotide_not_equal=False): ' accepted input for protein generation.' hgvs_transcript_to_hgvs_protein['hgvs_protein'] = _tot_unc(associated_protein_accession) return hgvs_transcript_to_hgvs_protein + + # Continue processing no_start_err = 'ProteinTranslationError: Unable to generate protein variant description '+\ 'due to the sequence missing an accepted start codon.' if prot_ref_seq == 'error': @@ -532,9 +554,13 @@ def _remake_unc(prot,nucleotide_not_equal=False): # Gather the required information regarding variant interval and sequences if hgvs_transcript.posedit.edit.type != 'delins' and \ - hgvs_transcript.posedit.edit.type != 'dup': + hgvs_transcript.posedit.edit.type != 'dup' and \ + hgvs_transcript.posedit.edit.type != 'del' and \ + hgvs_transcript.posedit.edit.type != 'ins': + logger.info(f"passing {hgvs_transcript} translations to pro_inv_info function") pro_inv_info = utils.pro_inv_info(prot_ref_seq, prot_var_seq) else: + logger.info(f"passing {hgvs_transcript} translations to pro_delins_info function") # Test whether the length of the deletion, plus the insertion can be divided by 3 # This is trying to spot the difference between amino acid deletions # and early terminations @@ -546,6 +572,14 @@ def _remake_unc(prot,nucleotide_not_equal=False): minus = False plus = False + # Handle deletions + if hgvs_naughty.posedit.edit.type == 'del': + hgvs_naughty.posedit.edit.alt = "" + if hgvs_naughty.posedit.edit.type == 'ins': + hgvs_naughty.posedit.edit.ref = del_seq + hgvs_naughty.posedit.edit.alt = f"{del_seq[0]}{hgvs_naughty.posedit.edit.alt}{del_seq[-1]}" + + try: if len(hgvs_naughty.posedit.edit.ref) > len(hgvs_naughty.posedit.edit.alt): var_cds_len = cds_len - (len(hgvs_naughty.posedit.edit.ref) @@ -564,7 +598,7 @@ def _remake_unc(prot,nucleotide_not_equal=False): # Do we have an in-frame variant i.e. divisible by 3? in_frame = False if minus is True: - loss_gain = (cds_len) - (var_cds_len) + loss_gain = cds_len - var_cds_len if loss_gain % 3 == 0: loss_gain = loss_gain / 3 loss_gain = 0 - loss_gain @@ -580,6 +614,10 @@ def _remake_unc(prot,nucleotide_not_equal=False): prot_var_seq, in_frame) + logger.info(f"RefSeq: {prot_ref_seq}") + logger.info(f"VarSeq: {prot_var_seq}") + logger.info(f"pro_inv_info: {pro_inv_info}") + # Error has occurred if pro_inv_info['error'] == 'true': error = 'Translation error occurred, please contact admin' @@ -644,29 +682,103 @@ def _remake_unc(prot,nucleotide_not_equal=False): # Adjust extended aas if necessary if modified_aa == "Sec": if "U" in pro_inv_info['prot_ins_seq'] and "U" not in pro_inv_info['prot_del_seq']: - pro_inv_info['prot_ins_seq'] = pro_inv_info['prot_ins_seq'].replace("U", "*") + logger.info("Sec identified in pro_inv_info['prot_ins_seq']") + + # legacy code ################################################################# + # pro_inv_info['prot_ins_seq'] = pro_inv_info['prot_ins_seq'].replace("U", "*") + # pro_inv_info['ter_pos'] = pro_inv_info['edit_start'] + len( + # pro_inv_info['prot_ins_seq'].split("*")[0]) + ################################################################################ + pro_inv_info['ter_pos'] = pro_inv_info['edit_start'] + len( - pro_inv_info['prot_ins_seq'].split("*")[0]) + pro_inv_info['prot_ins_seq']) + + # Set posedit + posedit = False # Early termination i.e. stop gained + logger.info(f"Identify early termination") if pro_inv_info['terminate'] == 'true' and \ (hgvs_transcript.posedit.edit.type == 'delins' or hgvs_transcript.posedit.edit.type == 'dup' or - hgvs_transcript.posedit.edit.type == 'inv'): + hgvs_transcript.posedit.edit.type == 'inv' or + hgvs_transcript.posedit.edit.type == 'ins'): + + # Identify missed frameshifts + edit = hgvs_naughty.posedit.edit + pos = hgvs_naughty.posedit.pos + frameshift = False + logger.info(f"Early termination identified from edit type {edit.type}") + + if edit.type == "dup": + length = pos.end.base - pos.start.base + 1 + frameshift = length % 3 != 0 + + elif edit.type == "del": + ref = edit.ref or "" + frameshift = len(ref) % 3 != 0 + + elif edit.type == "ins": + alt = edit.alt or "" + frameshift = len(alt) % 3 != 0 + + elif edit.type == "delins": + ref = edit.ref or "" + alt = edit.alt or "" + frameshift = (len(alt) - len(ref)) % 3 != 0 + + elif edit.type == "inv": + frameshift = False + + if frameshift: + logger.info("Identified unhandled frameshift in pro_inv_info['pro_ins_seq']") + + ref = pro_inv_info['prot_del_seq'][0] # "D" + alt = pro_inv_info['prot_ins_seq'][0] # "U" + + length = pro_inv_info['prot_ins_seq'].find("*") + length = length if length >= 0 else None + + posedit = PosEdit( + pos=Interval( + start=AAPosition( + base=pro_inv_info['edit_start'], + aa=ref # THIS is the fix + ), + end=AAPosition( + base=pro_inv_info['edit_start'], + aa=ref + ) + ), + edit=AAFs( + ref=ref, + alt=alt, + length=length + ) + ) + logger.info(f"Posedit updated to {posedit}") + hgvs_protein = vvhgvs.sequencevariant.SequenceVariant( + ac=associated_protein_accession, type='p', posedit=posedit) + + hgvs_transcript_to_hgvs_protein['hgvs_protein'] = hgvs_protein + return hgvs_transcript_to_hgvs_protein # This deals with early terminating delins in-frame prventing the format # NP_733765.1:p.(Gln259_Ser1042delinsProAla*) in issue #214 also #282 - if len(pro_inv_info['prot_del_seq']) + \ + elif len(pro_inv_info['prot_del_seq']) + \ int(pro_inv_info['edit_start'] - 1) == int(pro_inv_info['ter_pos']): + logger.info(f"Identified unhandled frameshift") end = 'Ter' + str(pro_inv_info['ter_pos']) pro_inv_info['prot_ins_seq'].replace('*', end) pro_inv_info['prot_ins_seq'] = pro_inv_info['prot_ins_seq'] pro_inv_info['prot_del_seq'] = pro_inv_info['prot_del_seq'][0] pro_inv_info['edit_end'] = pro_inv_info['edit_start'] + elif hgvs_transcript.posedit.edit.type == 'dup' and pro_inv_info["prot_del_seq"] \ == "" and (int(pro_inv_info["edit_end"]) < int(pro_inv_info["edit_start"])): # Handles in-frame dups only + logger.info(f"Identified unhandled frameshift from dup") dup_len = (int(hgvs_transcript.posedit.pos.end.base) - int( hgvs_transcript.posedit.pos.start.base) + 1) / 3 pro_inv_info['prot_del_seq'] = pro_inv_info['prot_ins_seq'] @@ -678,9 +790,10 @@ def _remake_unc(prot,nucleotide_not_equal=False): pro_inv_info['prot_del_seq'] = start_aa pro_inv_info['prot_ins_seq'] = start_aa + \ pro_inv_info['prot_ins_seq'] + else: + logger.info("No unhandled frameshift in pro_inv_info['pro_ins_seq']") # Complete variant description - # Write the HGVS position and edit # start by handling delins->ins transitions from the cds to prot mapping if not pro_inv_info['prot_del_seq']: @@ -800,6 +913,7 @@ def _remake_unc(prot,nucleotide_not_equal=False): alt = pro_inv_info["prot_ins_seq"][1:]),#[3:]), uncertain = True, nucleotide_not_equal=nucleotide_not_equal) + # Handle extended proteins i.e. stop_lost elif pro_inv_info["prot_del_seq"] == '*' and ( len(pro_inv_info["prot_ins_seq"]) > len(pro_inv_info["prot_del_seq"])): @@ -858,6 +972,7 @@ def _remake_unc(prot,nucleotide_not_equal=False): posedit = posedit ) hgvs_transcript_to_hgvs_protein['hgvs_protein'] = hgvs_protein + # Return return hgvs_transcript_to_hgvs_protein diff --git a/tests/test_inputs.py b/tests/test_inputs.py index 95679fc5..5fc3bc61 100644 --- a/tests/test_inputs.py +++ b/tests/test_inputs.py @@ -30900,9 +30900,9 @@ def test_issue_503b(self): variant = 'NM_020451.2:c.481C>T' results = self.vv.validate(variant, 'GRCh37', 'all', liftover_level='primary').format_as_dict(test=True) print(results) - assert 'NP_065184.2:p.(Arg161Ter)' in \ + assert 'NP_065184.2:p.(Arg161Sec)' in \ results['NM_020451.2:c.481C>T']['hgvs_predicted_protein_consequence']['tlr'] - assert 'NP_065184.2:p.(R161*)' in \ + assert 'NP_065184.2:p.(R161U)' in \ results['NM_020451.2:c.481C>T']['hgvs_predicted_protein_consequence']['slr'] def test_issue_503c(self): @@ -31261,46 +31261,103 @@ def polyadenylation_b(self): results = self.vv.validate('2:g.46707878_46707879insGCAGCGGGAGCG', 'GRCh37', 'mane_select').format_as_dict(test=True) assert 'NM_001145051.2:c.457_458insGGGAGCGGCAGC' in results - def cnv_del_vcf(self): - # Test that it fails for genome mismatch + def test_cnv_del_vcf(self): + # Test that copy number variant VCF input works results = self.vv.validate('chr1\t1000000\t.\tN\t\t.\tPASS\tSVTYPE=DEL;END=1005000', 'GRCh38', 'all').format_as_dict(test=True) assert 'intergenic_variant_1' in results assert results["intergenic_variant_1"]["primary_assembly_loci"]["grch38"][ "hgvs_genomic_description"] == "NC_000001.11:g.1000000_1005000del" - def issue_786_part_B(self): - # Test that it fails for genome mismatch + def test_issue_786_part_B(self): + # Test that we successfully round trip results = self.vv.validate('NC_000023.10:g.18908328_18911824delinsGCCTGCAGAG', 'GRCh37', 'all', liftover_level=True).format_as_dict(test=True) - assert 'intergenic_variant_1' in results + print(results) assert results["intergenic_variant_1"]["primary_assembly_loci"]["grch37"][ "hgvs_genomic_description"] == "NC_000023.10:g.18908328_18911824delinsGCCTGCAGAG" assert results["intergenic_variant_1"]["primary_assembly_loci"]["grch38"][ "hgvs_genomic_description"] == "NC_000023.11:g.18890210_18893706delinsGCCTGCAGAG" - def issue_786_part_A1(self): - # Test that it fails for genome mismatch + def test_issue_786_part_A1(self): + # Test that we successfully round trip results = self.vv.validate('NC_000015.9:g.72105928del', 'GRCh37', 'mane_select', liftover_level=True).format_as_dict(test=True) - assert 'intergenic_variant_1' in results + print(results) assert results["NM_014249.4:c.947A>C"]["primary_assembly_loci"]["grch37"][ "hgvs_genomic_description"] == "NC_000015.9:g.72105928del" assert results["NM_014249.4:c.947A>C"]["primary_assembly_loci"]["grch38"][ "hgvs_genomic_description"] == "NC_000015.10:g.71813588A>C" - def issue_786_part_A2(self): - # Test that it fails for genome mismatch + def test_issue_786_part_A2(self): + # Test that we successfully round trip results = self.vv.validate('NC_000015.9:g.72105933dup', 'GRCh37', 'mane_select', liftover_level=True).format_as_dict(test=True) - assert 'intergenic_variant_1' in results - assert results["NM_014249.4:c.947A>C"]["primary_assembly_loci"]["grch37"][ + print(results) + assert results["NM_014249.4:c.950_951dup"]["primary_assembly_loci"]["grch37"][ "hgvs_genomic_description"] == "NC_000015.9:g.72105933dup" - assert results["NM_014249.4:c.947A>C"]["primary_assembly_loci"]["grch38"][ + assert results["NM_014249.4:c.950_951dup"]["primary_assembly_loci"]["grch38"][ "hgvs_genomic_description"] == "NC_000015.10:g.71813591_71813592dup" - def issue_801(self): + def test_issue_801(self): results = self.vv.validate('15-71818229-TA-T', 'GRCh38', 'all', liftover_level=True).format_as_dict(test=True) assert "NM_014249.4:c.*557del" in results.keys() assert "NM_001281446.1:c.*557del" in results.keys() - + def test_issue_815a(self): + results = self.vv.validate('NM_020451.3:c.447dup', 'GRCh38', 'all', liftover_level=True).format_as_dict(test=True) + assert "NM_020451.3:c.447dup" in results.keys() + assert results["NM_020451.3:c.447dup"]["hgvs_predicted_protein_consequence"]['slr'] == "NP_065184.2:p.D150Ufs*2" + assert results["NM_020451.3:c.447dup"]["hgvs_predicted_protein_consequence"]['tlr'] == "NP_065184.2:p.Asp150SecfsTer2" + #assert results["NM_020451.3:c.447dup"]["hgvs_predicted_protein_consequence"]['lrg_slr'] == "LRG_857p1:p.D150Ufs*2" + #assert results["NM_020451.3:c.447dup"]["hgvs_predicted_protein_consequence"]['lrg_tlr'] == "LRG_857p1:p.Asp150SecfsTer2" + + def test_issue_815b(self): + results = self.vv.validate('NM_020451.3:c.407del', 'GRCh38', 'all', liftover_level=True).format_as_dict(test=True) + assert "NM_020451.3:c.407del" in results.keys() + assert results["NM_020451.3:c.407del"]["hgvs_predicted_protein_consequence"]['slr'] == "NP_065184.2:p.(S136*)" + assert results["NM_020451.3:c.407del"]["hgvs_predicted_protein_consequence"]['tlr'] == "NP_065184.2:p.(Ser136Ter)" + #assert results["NM_020451.3:c.407del"]["hgvs_predicted_protein_consequence"]['lrg_slr'] == "LRG_857p1:p.(S136*)" + #assert results["NM_020451.3:c.407del"]["hgvs_predicted_protein_consequence"]['lrg_tlr'] == "LRG_857p1:p.(Ser136Ter)" + + def test_issue_815c(self): + results = self.vv.validate('NM_020451.3:c.532del', 'GRCh38', 'all', liftover_level=True).format_as_dict(test=True) + assert "NM_020451.3:c.532del" in results.keys() + assert results["NM_020451.3:c.532del"]["hgvs_predicted_protein_consequence"]['slr'] == "NP_065184.2:p.(L178*)" + assert results["NM_020451.3:c.532del"]["hgvs_predicted_protein_consequence"]['tlr'] == "NP_065184.2:p.(Leu178Ter)" + #assert results["NM_020451.3:c.532del"]["hgvs_predicted_protein_consequence"]['lrg_slr'] == "LRG_857p1:p.(L178*)" + #assert results["NM_020451.3:c.532del"]["hgvs_predicted_protein_consequence"]['lrg_tlr'] == "LRG_857p1:p.(Leu178Ter)" + + def test_issue_815d(self): + results = self.vv.validate('NM_020451.3:c.406_407insG', 'GRCh38', 'all', liftover_level=True).format_as_dict(test=True) + assert "NM_020451.3:c.406_407insG" in results.keys() + assert results["NM_020451.3:c.406_407insG"]["hgvs_predicted_protein_consequence"]['slr'] == "NP_065184.2:p.S136Cfs*16" + assert results["NM_020451.3:c.406_407insG"]["hgvs_predicted_protein_consequence"]['tlr'] == "NP_065184.2:p.Ser136CysfsTer16" + #assert results["NM_020451.3:c.406_407insG"]["hgvs_predicted_protein_consequence"]['lrg_slr'] == "LRG_857p1:p.S136Cfs*16" + #assert results["NM_020451.3:c.406_407insG"]["hgvs_predicted_protein_consequence"]['lrg_tlr'] == "LRG_857p1:p.Ser136CysfsTer16" + + def test_issue_815e(self): + # test that variants affected by selenocysteine edits inform users + results = self.vv.validate('NM_020451.3:c.406_407insG', 'GRCh38', 'all', liftover_level=True).format_as_dict(test=True) + print(results) + assert "NM_020451.3:c.406_407insG" in results.keys() + assert results["NM_020451.3:c.406_407insG"]["hgvs_predicted_protein_consequence"]['slr'] == "NP_065184.2:p.S136Cfs*16" + assert results["NM_020451.3:c.406_407insG"]["hgvs_predicted_protein_consequence"]['tlr'] == "NP_065184.2:p.Ser136CysfsTer16" + #assert results["NM_020451.3:c.406_407insG"]["hgvs_predicted_protein_consequence"]['lrg_slr'] == "LRG_857p1:p.S136Cfs*16" + #assert results["NM_020451.3:c.406_407insG"]["hgvs_predicted_protein_consequence"]['lrg_tlr'] == "LRG_857p1:p.Ser136CysfsTer16" + + sec_warn_found = False + for warn in results["NM_020451.3:c.406_407insG"]["validation_warnings"]: + if warn.startswith('ProteinTranslationInfo: Sel'): + sec_warn_found = True + assert sec_warn_found + + def issue_818(self): + results = self.vv.validate('NC_000022.10:g.19929250_19929251insCCCCGCC', 'GRCh38', 'mane_select', liftover_level=True).format_as_dict(test=True) + assert "NM_006440.5:c.70_76dup" in results.keys() + assert results["NM_006440.5:c.70_76dup"][ + "hgvs_predicted_protein_consequence"] == { + "lrg_slr": "LRG_417p1:p.V26Gfs*132", + "lrg_tlr": "LRG_417p1:p.Val26GlyfsTer132", + "slr": "NP_006431.2:p.V26Gfs*132", + "tlr": "NP_006431.2:p.Val26GlyfsTer132" + } # # Copyright (C) 2016-2026 VariantValidator Contributors