protected CodonChange(Variant variant, Transcript transcript, VariantEffects variantEffects) { Transcript = transcript; VariantEffects = variantEffects; Variant = variant; }
/// <summary> /// Calculate the effect on an exon /// </summary> /// <param name="exon"></param> /// <returns></returns> protected virtual bool ChangeCodon(Exon exon) { throw new InvalidOperationException("Unimplemented method codonChangeSingle() for\n\t\tVariant type : " + Variant.GetType().Name + "\n\t\tClass : " + GetType().Name + "\n\t\tVariant : " + Variant); }
/// <summary> /// Check that the base in the exon corresponds with the one in the SNP /// </summary> /// <param name="variant"></param> /// <returns></returns> public ErrorWarningType SanityCheck(Variant variant) { if (!Intersects(variant)) { return(ErrorWarningType.NONE); } // Only makes sense for SNPs and MNPs if ((variant.VarType != Variant.VariantType.SNV) && (variant.VarType != Variant.VariantType.MNV)) { return(ErrorWarningType.NONE); } // Calculate reference sequence coordinates long mstart = Math.Max(variant.OneBasedStart, OneBasedStart); long idxStart = mstart - OneBasedStart; if (Sequence.Count <= 0) { return(ErrorWarningType.WARNING_SEQUENCE_NOT_AVAILABLE); } if (idxStart >= Sequence.Count) { return(ErrorWarningType.ERROR_OUT_OF_EXON); } long mend = Math.Min(variant.OneBasedEnd, OneBasedEnd); long len = mend - mstart + 1; ISequence realReference = basesAt(idxStart, len); // Get variant's reference coordinates long varRefStart = mstart - variant.OneBasedStart; if (varRefStart < 0) { return(ErrorWarningType.ERROR_OUT_OF_EXON); } long varRefEnd = mend - variant.OneBasedStart; // Variant's reference sequence string refStr; //if (variant.isNonRef()) // used for some advanced stuff in SnpEff, comparing cancer vs somatic tissue //{ // refStr = ((VariantNonRef)variant).getVariantRef().getAlt(); //} //else //{ refStr = variant.ReferenceAlleleString; //} if (varRefEnd >= refStr.Length) { return(ErrorWarningType.ERROR_OUT_OF_EXON); } int varRefLen = (int)(varRefEnd - varRefStart + 1); string variantReference = refStr.Substring((int)varRefStart, varRefLen); // Reference sequence different than expected? if (!realReference.Equals(variantReference)) { // return(ErrorWarningType.WARNING_REF_DOES_NOT_MATCH_GENOME); } // OK return(ErrorWarningType.NONE); }
/// <summary> /// Calculate additional effect due to codon changes, e.g. A frame-shift that also affects a stop codon /// </summary> /// <param name="codonsOld"></param> /// <param name="codonsNew"></param> /// <param name="codonNum"></param> /// <param name="codonIndex"></param> /// <returns></returns> protected EffectType AdditionalEffect(string codonsOld, string codonsNew, int codonNum, int codonIndex) { EffectType newEffectType = EffectType.NONE; bool hasOldAa = CodonExtensions.TryTranslateCodon(Transcript.Gene.Chromosome.Mitochondrial, codonsOld, out byte oldAA); bool hasNewAa = CodonExtensions.TryTranslateCodon(Transcript.Gene.Chromosome.Mitochondrial, codonsNew, out byte newAA); bool isStartNew = Transcript.Gene.Chromosome.Mitochondrial ? CodonsVertebrateMitochondrial.START_CODONS.Contains(codonsNew.ToUpper(CultureInfo.InvariantCulture)) : CodonsStandard.START_CODONS.Contains(codonsNew.ToUpper(CultureInfo.InvariantCulture)); bool isStartOld = Transcript.Gene.Chromosome.Mitochondrial ? CodonsVertebrateMitochondrial.START_CODONS.Contains(codonsOld.ToUpper(CultureInfo.InvariantCulture)) : CodonsStandard.START_CODONS.Contains(codonsOld.ToUpper(CultureInfo.InvariantCulture)); bool isStopOld = hasOldAa && oldAA == Alphabets.Protein.Ter; bool isStopNew = hasNewAa && newAA == Alphabets.Protein.Ter; if (Variant.isSnv() || Variant.isMnv()) { // SNM and MNP effects if (oldAA.Equals(newAA)) { // Same AA: Synonymous coding if (codonNum == 0 && isStartOld) { // It is in the first codon (which also is a start codon) if (isStartNew) { newEffectType = EffectType.SYNONYMOUS_START; } // The new codon is also a start codon => SYNONYMOUS_START else { newEffectType = EffectType.START_LOST; } // The AA is the same, but the codon is not a start codon => start lost } else if (isStopOld) { // Stop codon if (isStopNew) { newEffectType = EffectType.SYNONYMOUS_STOP; } // New codon is also a stop => SYNONYMOUS_STOP else { newEffectType = EffectType.STOP_LOST; } // New codon is not a stop, the we've lost a stop } else { newEffectType = EffectType.SYNONYMOUS_CODING; // All other cases are just SYNONYMOUS_CODING } } else { // Different AA: Non-synonymous coding if ((codonNum == 0) && isStartOld) { // It is in the first codon (which also is a start codon) if (isStartNew) { newEffectType = EffectType.NON_SYNONYMOUS_START; } // Non-synonymous mutation on first codon => start lost else { newEffectType = EffectType.START_LOST; } // Non-synonymous mutation on first codon => start lost } else if (isStopOld) { // Stop codon if (isStopNew) { newEffectType = EffectType.NON_SYNONYMOUS_STOP; } // Notice: This should never happen for SNPs! (for some reason I removed this comment at some point and that create some confusion): http://www.biostars.org/post/show/51352/in-snpeff-impact-what-is-difference-between-stop_gained-and-non-synonymous_stop/ else { newEffectType = EffectType.STOP_LOST; } } else if (isStopNew) { newEffectType = EffectType.STOP_GAINED; } else { newEffectType = EffectType.NON_SYNONYMOUS_CODING; // All other cases are just NON_SYN } } } else { // Add a new effect in some cases if ((codonNum == 0) && isStartOld && !isStartNew) { newEffectType = EffectType.START_LOST; } else if (isStopOld && !isStopNew) { newEffectType = EffectType.STOP_LOST; } else if (!isStopOld && isStopNew) { newEffectType = EffectType.STOP_GAINED; } } return(newEffectType); }
/// <summary> /// Apply a variant to this exon interval and sequence /// </summary> /// <param name="variant"></param> /// <returns></returns> public override Interval ApplyVariant(Variant variant) { IntervalSequence i = base.ApplyVariant(variant) as IntervalSequence; return(new Exon(i.Parent as Transcript, i.Sequence, i.Source, i.OneBasedStart, i.OneBasedEnd, i.ChromosomeID, i.Strand, i.Variants, FeatureMetadata)); }