From 2ff71d88615a2d813d362d6e08a89df44119dbbd Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Tue, 16 Jul 2024 11:50:20 -0400 Subject: [PATCH] Add intergenicConsequenceSummaries in annotationSummary and add variantClassification --- .../VariantClassificationResolver.java | 21 ++++++++ .../model/IntergenicConsequenceSummary.java | 53 +++++++++++++++++++ .../model/VariantAnnotationSummary.java | 10 +++- .../VariantAnnotationSummaryServiceImpl.java | 46 +++++++++++----- 4 files changed, 115 insertions(+), 15 deletions(-) create mode 100644 model/src/main/java/org/cbioportal/genome_nexus/model/IntergenicConsequenceSummary.java diff --git a/component/src/main/java/org/cbioportal/genome_nexus/component/annotation/VariantClassificationResolver.java b/component/src/main/java/org/cbioportal/genome_nexus/component/annotation/VariantClassificationResolver.java index 00adcf64..e0a5fcf3 100644 --- a/component/src/main/java/org/cbioportal/genome_nexus/component/annotation/VariantClassificationResolver.java +++ b/component/src/main/java/org/cbioportal/genome_nexus/component/annotation/VariantClassificationResolver.java @@ -11,6 +11,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; @Component public class VariantClassificationResolver @@ -46,6 +47,21 @@ public String resolve(VariantAnnotation variantAnnotation, TranscriptConsequence this.consequencePrioritizer.pickHighestPriorityConsequence(transcriptConsequence.getConsequenceTerms()), variantType, isInframe); } + // if variant has no transcript and has intergenicConsequences instead, try to resolve the variant classification from intergenicConsequences + else if (variantAnnotation != null && variantAnnotation.getIntergenicConsequences() != null && !variantAnnotation.getIntergenicConsequences().isEmpty()) { + // pick the highest priority consequence from the intergenic consequences + // get every getConsequenceTerms() from each intergenic consequence and put in a list + variantClassification = this.resolveVariantClassification( + this.consequencePrioritizer.pickHighestPriorityConsequence( + variantAnnotation.getIntergenicConsequences() + .stream() + .flatMap(consequence -> consequence.getConsequenceTerms() + .stream()) + .collect(Collectors.toList())), + variantType, + isInframe + ); + } // use the most severe consequence to resolve the variant classification else if (variantAnnotation != null) { @@ -186,9 +202,13 @@ private static Map initVariantMap() variantMap.put("missense_variant", "Missense_Mutation"); variantMap.put("protein_altering_variant", "Missense_Mutation"); // Not always correct, resolveVariantClassification handles the exceptions variantMap.put("coding_sequence_variant", "Missense_Mutation"); // Not always correct, resolveVariantClassification handles the exceptions + variantMap.put("coding_transcript_variant", "Missense_Mutation"); // Not always correct, resolveVariantClassification handles the exceptions variantMap.put("conservative_missense_variant", "Missense_Mutation"); variantMap.put("rare_amino_acid_variant", "Missense_Mutation"); variantMap.put("transcript_amplification", "Intron"); + variantMap.put("feature_elongation", "Feature_Elongation"); + variantMap.put("feature_truncation", "Feature_Elongation"); + variantMap.put("sequence_variant", "Sequence_Variant"); variantMap.put("splice_region_variant", "Splice_Region"); variantMap.put("splice_donor_region_variant", "Splice_Region"); variantMap.put("splice_polypyrimidine_tract_variant", "Splice_Region"); @@ -216,6 +236,7 @@ private static Map initVariantMap() variantMap.put("regulatory_region_variant", "IGR"); variantMap.put("regulatory_region_amplification", "IGR"); variantMap.put("regulatory_region", "IGR"); + variantMap.put("regulatory_region_ablation", "IGR"); variantMap.put("intergenic_variant", "IGR"); variantMap.put("intergenic_region", "IGR"); variantMap.put("upstream_gene_variant", "5'Flank"); diff --git a/model/src/main/java/org/cbioportal/genome_nexus/model/IntergenicConsequenceSummary.java b/model/src/main/java/org/cbioportal/genome_nexus/model/IntergenicConsequenceSummary.java new file mode 100644 index 00000000..70ee01a8 --- /dev/null +++ b/model/src/main/java/org/cbioportal/genome_nexus/model/IntergenicConsequenceSummary.java @@ -0,0 +1,53 @@ +package org.cbioportal.genome_nexus.model; + +import java.util.List; + +public class IntergenicConsequenceSummary { + private String impact; + + public String getImpact() + { + return impact; + } + + public void setImpact(String impact) + { + this.impact = impact; + } + + private String variantAllele; + + public String getVariantAllele() + { + return variantAllele; + } + + public void setVariantAllele(String variantAllele) + { + this.variantAllele = variantAllele; + } + + private List consequenceTerms; + + public List getConsequenceTerms() + { + return consequenceTerms; + } + + public void setConsequenceTerms(List consequenceTerms) + { + this.consequenceTerms = consequenceTerms; + } + + private String variantClassification; + + public String getVariantClassification() + { + return variantClassification; + } + + public void setVariantClassification(String variantClassification) + { + this.variantClassification = variantClassification; + } +} diff --git a/model/src/main/java/org/cbioportal/genome_nexus/model/VariantAnnotationSummary.java b/model/src/main/java/org/cbioportal/genome_nexus/model/VariantAnnotationSummary.java index fdf416cc..0704b39d 100644 --- a/model/src/main/java/org/cbioportal/genome_nexus/model/VariantAnnotationSummary.java +++ b/model/src/main/java/org/cbioportal/genome_nexus/model/VariantAnnotationSummary.java @@ -21,8 +21,8 @@ public class VariantAnnotationSummary // most impactful canonical annotation, when looking to pick a single // annotation private TranscriptConsequenceSummary transcriptConsequenceSummary; - private Vues vues; + private List intergenicConsequenceSummaries; private AlphaMissense alphaMissense; @@ -113,4 +113,12 @@ public Vues getVues() { public void setVues(Vues vues) { this.vues = vues; } + + public List getIntergenicConsequenceSummaries() { + return intergenicConsequenceSummaries; + } + + public void setIntergenicConsequenceSummaries(List intergenicConsequenceSummaries) { + this.intergenicConsequenceSummaries = intergenicConsequenceSummaries; + } } diff --git a/service/src/main/java/org/cbioportal/genome_nexus/service/internal/VariantAnnotationSummaryServiceImpl.java b/service/src/main/java/org/cbioportal/genome_nexus/service/internal/VariantAnnotationSummaryServiceImpl.java index 9d70e980..52f8252d 100644 --- a/service/src/main/java/org/cbioportal/genome_nexus/service/internal/VariantAnnotationSummaryServiceImpl.java +++ b/service/src/main/java/org/cbioportal/genome_nexus/service/internal/VariantAnnotationSummaryServiceImpl.java @@ -3,6 +3,8 @@ import org.cbioportal.genome_nexus.component.annotation.*; import org.cbioportal.genome_nexus.model.TranscriptConsequenceSummary; import org.cbioportal.genome_nexus.model.VariantAnnotationSummary; +import org.cbioportal.genome_nexus.model.IntergenicConsequenceSummary; +import org.cbioportal.genome_nexus.model.IntergenicConsequences; import org.cbioportal.genome_nexus.model.RevisedProteinEffectJsonRecord; import org.cbioportal.genome_nexus.model.TranscriptConsequence; import org.cbioportal.genome_nexus.model.VariantAnnotation; @@ -21,6 +23,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -109,20 +112,35 @@ public VariantAnnotationSummary getAnnotationSummaryForCanonical(VariantAnnotati VariantAnnotationSummary annotationSummary = this.getVariantAnnotationSummary(annotation); TranscriptConsequence canonicalTranscript = this.canonicalTranscriptResolver.resolve(annotation); - if (annotationSummary != null && canonicalTranscript != null) - { - annotationSummary.setTranscriptConsequenceSummary(this.getTranscriptSummary(annotation, canonicalTranscript, vuesMap)); - annotationSummary.setCanonicalTranscriptId(canonicalTranscript.getTranscriptId()); - - // for backwards compatibility set transcriptConsequences - List transcriptConsequences = new ArrayList<>(1); - transcriptConsequences.add(annotationSummary.getTranscriptConsequenceSummary()); - annotationSummary.setTranscriptConsequences(transcriptConsequences); - // if this variant is VUE, add Vues infomation - if (annotationSummary.getTranscriptConsequenceSummary() != null && - annotationSummary.getTranscriptConsequenceSummary().getIsVue() != null && - annotationSummary.getTranscriptConsequenceSummary().getIsVue() == true) { - annotationSummary.setVues(this.vuesMap.get(annotationSummary.getTranscriptConsequenceSummary().getTranscriptId())); + if (annotationSummary != null) { + if (canonicalTranscript == null && annotation.getIntergenicConsequences() != null && !annotation.getIntergenicConsequences().isEmpty()) { + // Set intergenicConsequenceSummaries when variant is "intergenic_variant", add variant classification based on consequence terms. + // This is useful for genome nexus annotation pipeline, so when doing curation, those mutations will be filtered out by "IGR" rule, instead of being imported as "MUTATED". + List intergenicConsequenceSummaries = new ArrayList<>(); + for (IntergenicConsequences intergenicConsequence : annotation.getIntergenicConsequences()) { + IntergenicConsequenceSummary intergenicConsequenceSummary = new IntergenicConsequenceSummary(); + intergenicConsequenceSummary.setVariantClassification(this.variantClassificationResolver.resolve(annotation, canonicalTranscript)); + intergenicConsequenceSummary.setImpact(intergenicConsequence.getImpact()); + intergenicConsequenceSummary.setVariantAllele(intergenicConsequence.getVariantAllele()); + intergenicConsequenceSummary.setConsequenceTerms(intergenicConsequence.getConsequenceTerms()); + intergenicConsequenceSummaries.add(intergenicConsequenceSummary); + } + annotationSummary.setIntergenicConsequenceSummaries(intergenicConsequenceSummaries); + } + else { + annotationSummary.setTranscriptConsequenceSummary(this.getTranscriptSummary(annotation, canonicalTranscript, vuesMap)); + annotationSummary.setCanonicalTranscriptId(canonicalTranscript.getTranscriptId()); + // for backwards compatibility set transcriptConsequences + List transcriptConsequences = new ArrayList<>(1); + transcriptConsequences.add(annotationSummary.getTranscriptConsequenceSummary()); + annotationSummary.setTranscriptConsequences(transcriptConsequences); + + // if this variant is VUE, add Vues information + if (annotationSummary.getTranscriptConsequenceSummary() != null && + annotationSummary.getTranscriptConsequenceSummary().getIsVue() != null && + annotationSummary.getTranscriptConsequenceSummary().getIsVue()) { + annotationSummary.setVues(this.vuesMap.get(annotationSummary.getTranscriptConsequenceSummary().getTranscriptId())); + } } }