Skip to content

Commit

Permalink
Add annotation search endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
calvinlu3 committed Feb 8, 2024
1 parent aba97a7 commit 68da1cf
Show file tree
Hide file tree
Showing 11 changed files with 501 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.mskcc.cbio.oncokb.model;


public enum AnnotationSearchQueryType {
GENE, VARIANT, DRUG, CANCER_TYPE
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.mskcc.cbio.oncokb.model;

public class AnnotationSearchResult {
AnnotationSearchQueryType queryType;
IndicatorQueryResp indicatorQueryResp;


public AnnotationSearchQueryType getQueryType() {
return this.queryType;
}

public void setQueryType(AnnotationSearchQueryType queryType) {
this.queryType = queryType;
}

public IndicatorQueryResp getIndicatorQueryResp() {
return this.indicatorQueryResp;
}

public void setIndicatorQueryResp(IndicatorQueryResp indicatorQueryResp) {
this.indicatorQueryResp = indicatorQueryResp;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public static Set<Alteration> findOverlapAlteration(List<Alteration> alterations
}

private static Matcher getExclusionCriteriaMatcher(String proteinChange) {
Pattern exclusionPatter = Pattern.compile("(.*)\\{\\s*(exclude|excluding)(.*)\\}", Pattern.CASE_INSENSITIVE);
Pattern exclusionPatter = Pattern.compile("(.*)[\\{\\()]\\s*(exclude|excluding)(.*)[\\}\\)]", Pattern.CASE_INSENSITIVE);
Matcher exclusionMatch = exclusionPatter.matcher(proteinChange);
return exclusionMatch;
}
Expand Down Expand Up @@ -1142,7 +1142,7 @@ private static String getMissenseVariantAllele(Alteration alteration, int positi
return null;
}

public static List<Alteration> lookupVariant(String query, Boolean exactMatch, List<Alteration> alterations) {
public static List<Alteration> lookupVariant(String query, Boolean exactMatch, Boolean omitExclusion, List<Alteration> alterations) {
List<Alteration> alterationList = new ArrayList<>();
// Only support columns(alteration/name) blur search.
query = query.toLowerCase().trim();
Expand All @@ -1152,12 +1152,12 @@ public static List<Alteration> lookupVariant(String query, Boolean exactMatch, L
return alterationList;
query = query.trim().toLowerCase();
for (Alteration alteration : alterations) {
if (isMatch(exactMatch, query, alteration.getAlteration())) {
if (isMatch(exactMatch, omitExclusion, query, alteration.getAlteration())) {
alterationList.add(alteration);
continue;
}

if (isMatch(exactMatch, query, alteration.getName())) {
if (isMatch(exactMatch, omitExclusion, query, alteration.getName())) {
alterationList.add(alteration);
continue;
}
Expand All @@ -1168,7 +1168,7 @@ public static List<Alteration> lookupVariant(String query, Boolean exactMatch, L
String fullName = NamingUtils.getFullName(query);
if (fullName != null) {
for (Alteration alteration : alterations) {
if (isMatch(exactMatch, fullName, alteration.getName())) {
if (isMatch(exactMatch, omitExclusion, fullName, alteration.getName())) {
alterationList.add(alteration);
}
}
Expand All @@ -1177,8 +1177,11 @@ public static List<Alteration> lookupVariant(String query, Boolean exactMatch, L
return alterationList;
}

private static Boolean isMatch(Boolean exactMatch, String query, String string) {
private static Boolean isMatch(Boolean exactMatch, Boolean omitExclusion, String query, String string) {
if (string != null) {
if (omitExclusion) {
string = AlterationUtils.removeExclusionCriteria(string);
}
if (exactMatch) {
if (StringUtils.containsIgnoreCase(string, query)) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import org.mskcc.cbio.oncokb.bo.ArticleBo;
import org.mskcc.cbio.oncokb.bo.EvidenceBo;
import org.mskcc.cbio.oncokb.model.*;
import org.mskcc.cbio.oncokb.model.TumorType;

import javax.xml.parsers.ParserConfigurationException;
import java.util.*;
Expand Down Expand Up @@ -181,7 +180,7 @@ private static Set<Evidence> getEvidence(ReferenceGenome referenceGenome, Eviden

if (query.getGene() != null) {
genes.add(query.getGene());
if (query.getExactMatchedAlteration() == null && query.getAlterations().isEmpty() && query.getAlleles().isEmpty()) {
if ((query.getExactMatchedAlteration() != null && query.getExactMatchedAlteration().getAlteration().length() == 0) && query.getAlterations().isEmpty() && query.getAlleles().isEmpty()) {
alterations.addAll(AlterationUtils.getAllAlterations(referenceGenome, query.getGene()));
} else {
if (query.getAlterations() != null) {
Expand Down Expand Up @@ -366,6 +365,8 @@ private static Set<Evidence> filterEvidence(Set<Evidence> evidences, EvidenceQue
//Add all gene specific evidences
if (evidence.getAlterations().isEmpty()) {
filtered.add(evidence);
} else if (evidenceQuery.getExactMatchedAlteration() != null && StringUtils.isEmpty(evidenceQuery.getExactMatchedAlteration().getAlteration())) {
filtered.add(evidence);
} else {
boolean hasjointed = !Collections.disjoint(evidence.getAlterations(), evidenceQuery.getAlterations());
if (!hasjointed) {
Expand Down
85 changes: 46 additions & 39 deletions core/src/main/java/org/mskcc/cbio/oncokb/util/IndicatorUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.mskcc.cbio.oncokb.util.LevelUtils.getTherapeuticLevelsWithPriorityLIstIterator;
import static org.mskcc.cbio.oncokb.util.SummaryUtils.allelesToStr;
Expand Down Expand Up @@ -276,38 +277,37 @@ public static IndicatorQueryResp processQuery(Query query,
indicatorQuery.setMutationEffect(mutationEffectResp);
}
}
}

if (hasTreatmentEvidence) {
if (StringUtils.isEmpty(query.getTumorType())) {
treatmentEvidences = EvidenceUtils.getRelevantEvidences(query, matchedAlt,
selectedTreatmentEvidence, levels, relevantAlterationsWithoutAlternativeAlleles, alleles);
} else {
treatmentEvidences = EvidenceUtils.keepHighestLevelForSameTreatments(
EvidenceUtils.getRelevantEvidences(query, matchedAlt,
selectedTreatmentEvidence, levels, relevantAlterationsWithoutAlternativeAlleles, alleles), query.getReferenceGenome(), matchedAlt);
}
// Set implications
if (hasTreatmentEvidence) {
if (StringUtils.isEmpty(query.getTumorType())) {
treatmentEvidences = EvidenceUtils.getRelevantEvidences(query, matchedAlt,
selectedTreatmentEvidence, levels, relevantAlterationsWithoutAlternativeAlleles, alleles);
} else {
treatmentEvidences = EvidenceUtils.keepHighestLevelForSameTreatments(
EvidenceUtils.getRelevantEvidences(query, matchedAlt,
selectedTreatmentEvidence, levels, relevantAlterationsWithoutAlternativeAlleles, alleles), query.getReferenceGenome(), matchedAlt);
}
}

if (hasDiagnosticImplicationEvidence) {
List<Implication> implications = new ArrayList<>();
implications.addAll(getImplications(matchedAlt, alleles, relevantAlterationsWithoutAlternativeAlleles, EvidenceType.DIAGNOSTIC_IMPLICATION, matchedTumorType, StringUtils.isEmpty(query.getTumorType()) ? null : relevantDownwardTumorTypes, query.getHugoSymbol(), Collections.singleton(LevelOfEvidence.LEVEL_Dx1)));

// For Dx2 and Dx3, the logic is the same as Tx/Px
Set<LevelOfEvidence> levelOfEvidences = new HashSet<>();
levelOfEvidences.add(LevelOfEvidence.LEVEL_Dx2);
levelOfEvidences.add(LevelOfEvidence.LEVEL_Dx3);
implications.addAll(getImplications(matchedAlt, alleles, relevantAlterationsWithoutAlternativeAlleles, EvidenceType.DIAGNOSTIC_IMPLICATION, matchedTumorType, StringUtils.isEmpty(query.getTumorType()) ? null : relevantUpwardTumorTypes, query.getHugoSymbol(), levelOfEvidences));
indicatorQuery.setDiagnosticImplications(implications);
if (indicatorQuery.getDiagnosticImplications().size() > 0) {
indicatorQuery.setHighestDiagnosticImplicationLevel(LevelUtils.getHighestDiagnosticImplicationLevel(indicatorQuery.getDiagnosticImplications().stream().map(implication -> implication.getLevelOfEvidence()).collect(Collectors.toSet())));
}
if (gene != null && hasDiagnosticImplicationEvidence) {
List<Implication> implications = new ArrayList<>();
Set<LevelOfEvidence> levelOfEvidences = new HashSet<>();
levelOfEvidences.add(LevelOfEvidence.LEVEL_Dx1);
levelOfEvidences.add(LevelOfEvidence.LEVEL_Dx2);
levelOfEvidences.add(LevelOfEvidence.LEVEL_Dx3);
implications.addAll(getImplications(gene, matchedAlt, alleles, relevantAlterationsWithoutAlternativeAlleles, EvidenceType.DIAGNOSTIC_IMPLICATION, matchedTumorType, StringUtils.isEmpty(query.getTumorType()) ? null : relevantUpwardTumorTypes, query.getHugoSymbol(), levelOfEvidences));
indicatorQuery.setDiagnosticImplications(implications);
if (indicatorQuery.getDiagnosticImplications().size() > 0) {
indicatorQuery.setHighestDiagnosticImplicationLevel(LevelUtils.getHighestDiagnosticImplicationLevel(indicatorQuery.getDiagnosticImplications().stream().map(implication -> implication.getLevelOfEvidence()).collect(Collectors.toSet())));
}
}

if (hasPrognosticImplicationEvidence) {
indicatorQuery.setPrognosticImplications(getImplications(matchedAlt, alleles, relevantAlterationsWithoutAlternativeAlleles, EvidenceType.PROGNOSTIC_IMPLICATION, matchedTumorType, StringUtils.isEmpty(query.getTumorType()) ? null : relevantUpwardTumorTypes, query.getHugoSymbol(), null));
if (indicatorQuery.getPrognosticImplications().size() > 0) {
indicatorQuery.setHighestPrognosticImplicationLevel(LevelUtils.getHighestPrognosticImplicationLevel(indicatorQuery.getPrognosticImplications().stream().map(implication -> implication.getLevelOfEvidence()).collect(Collectors.toSet())));
}
if (gene != null && hasPrognosticImplicationEvidence) {
indicatorQuery.setPrognosticImplications(getImplications(gene, matchedAlt, alleles, relevantAlterationsWithoutAlternativeAlleles, EvidenceType.PROGNOSTIC_IMPLICATION, matchedTumorType, StringUtils.isEmpty(query.getTumorType()) ? null : relevantUpwardTumorTypes, query.getHugoSymbol(), null));
if (indicatorQuery.getPrognosticImplications().size() > 0) {
indicatorQuery.setHighestPrognosticImplicationLevel(LevelUtils.getHighestPrognosticImplicationLevel(indicatorQuery.getPrognosticImplications().stream().map(implication -> implication.getLevelOfEvidence()).collect(Collectors.toSet())));
}
}

Expand Down Expand Up @@ -536,23 +536,30 @@ private static List<Implication> getImplicationFromEvidence(List<Evidence> evide
return implications;
}

private static List<Implication> getImplications(Alteration matchedAlt, List<Alteration> alternativeAlleles, List<Alteration> relevantAlterations, EvidenceType evidenceType, TumorType matchedTumorType, List<TumorType> tumorTypes, String queryHugoSymbol, Set<LevelOfEvidence> levelOfEvidences) {
private static List<Implication> getImplications(Gene gene, Alteration matchedAlt, List<Alteration> alternativeAlleles, List<Alteration> relevantAlterations, EvidenceType evidenceType, TumorType matchedTumorType, List<TumorType> tumorTypes, String queryHugoSymbol, Set<LevelOfEvidence> levelOfEvidences) {
List<Implication> implications = new ArrayList<>();

// Find alteration specific evidence
List<Evidence> selfAltEvis = EvidenceUtils.getEvidence(Collections.singletonList(matchedAlt), Collections.singleton(evidenceType), matchedTumorType, tumorTypes, levelOfEvidences);
if (selfAltEvis != null && selfAltEvis.size() > 0) {
implications.addAll(getImplicationFromEvidence(selfAltEvis, queryHugoSymbol));
}
if (matchedAlt != null && !StringUtils.isEmpty(matchedAlt.getAlteration())) {
// Find alteration specific evidence
List<Evidence> selfAltEvis = EvidenceUtils.getEvidence(Collections.singletonList(matchedAlt), Collections.singleton(evidenceType), matchedTumorType, tumorTypes, levelOfEvidences);
if (selfAltEvis != null && selfAltEvis.size() > 0) {
implications.addAll(getImplicationFromEvidence(selfAltEvis, queryHugoSymbol));
}

List<Alteration> listToBeRemoved = new ArrayList<>(alternativeAlleles);
listToBeRemoved.add(matchedAlt);
List<Alteration> listToBeRemoved = new ArrayList<>(alternativeAlleles);
listToBeRemoved.add(matchedAlt);

for (Alteration alt : AlterationUtils.removeAlterationsFromList(relevantAlterations, listToBeRemoved)) {
List<Evidence> altEvis = EvidenceUtils.getEvidence(Collections.singletonList(alt), Collections.singleton(evidenceType), matchedTumorType, tumorTypes, levelOfEvidences);
if (altEvis != null && altEvis.size() > 0) {
implications.addAll(getImplicationFromEvidence(altEvis, queryHugoSymbol));
for (Alteration alt : AlterationUtils.removeAlterationsFromList(relevantAlterations, listToBeRemoved)) {
List<Evidence> altEvis = EvidenceUtils.getEvidence(Collections.singletonList(alt), Collections.singleton(evidenceType), matchedTumorType, tumorTypes, levelOfEvidences);
if (altEvis != null && altEvis.size() > 0) {
implications.addAll(getImplicationFromEvidence(altEvis, queryHugoSymbol));
}
}
} else {
Set<Evidence> geneEvisSet = EvidenceUtils.getEvidenceByGeneAndEvidenceTypes(gene, Stream.of(evidenceType).collect(Collectors.toSet()));
List<Evidence> geneEvis = new ArrayList<>();
geneEvis.addAll(geneEvisSet);
implications.addAll(getImplicationFromEvidence(geneEvis, queryHugoSymbol));
}
return filterImplication(implications);
}
Expand Down
12 changes: 12 additions & 0 deletions core/src/main/java/org/mskcc/cbio/oncokb/util/LevelUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,18 @@ public static List<LevelOfEvidence> getIndexedTherapeuticLevels() {
return new ArrayList<>(THERAPEUTIC_LEVELS_WITH_PRIORITY);
}

public static List<LevelOfEvidence> getIndexedDiagnosticLevels() {
return new ArrayList<>(DIAGNOSTIC_LEVELS);
}

public static List<LevelOfEvidence> getIndexedPrognosticLevels() {
return new ArrayList<>(PROGNOSTIC_LEVELS);
}

public static List<LevelOfEvidence> getIndexedFdaLevels() {
return new ArrayList<>(FDA_LEVELS);
}

public static Set<LevelOfEvidence> getPrognosticLevels() {
return new HashSet<>(CollectionUtils.intersection(PUBLIC_LEVELS, PROGNOSTIC_LEVELS));
}
Expand Down
37 changes: 37 additions & 0 deletions core/src/main/java/org/mskcc/cbio/oncokb/util/MainUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ public class MainUtils {
)
);

private static final List<AnnotationSearchQueryType> PRIORITIZED_QUERY_TYPES = Collections.unmodifiableList(
Arrays.asList(
AnnotationSearchQueryType.GENE,
AnnotationSearchQueryType.VARIANT,
AnnotationSearchQueryType.CANCER_TYPE,
AnnotationSearchQueryType.DRUG
)
);

public static Oncogenicity getCuratedAlterationOncogenicity(Alteration alteration) {
List<Evidence> selfAltOncogenicEvis = EvidenceUtils.getEvidence(Collections.singletonList(alteration),
Collections.singleton(EvidenceType.ONCOGENIC), null);
Expand Down Expand Up @@ -822,4 +831,32 @@ public static String toLowerCaseExceptAllCaps(String text) {
}
return sb.toString();
}

public static <T> LinkedHashSet<T> getLimit(LinkedHashSet<T> result, Integer limit) {
final Integer DEFAULT_RETURN_LIMIT = 5;
if (limit == null)
limit = DEFAULT_RETURN_LIMIT;
Integer count = 0;
LinkedHashSet<T> firstFew = new LinkedHashSet<>();
Iterator<T> itr = result.iterator();
while (itr.hasNext() && count < limit) {
firstFew.add(itr.next());
count++;
}
return firstFew;
}

public static Integer compareAnnotationSearchQueryType(AnnotationSearchQueryType q1, AnnotationSearchQueryType q2, Boolean asc) {
if (asc == null) {
asc = true;
}
if (q1 == null) {
if (q2 == null)
return 0;
return asc ? 1 : -1;
}
if (q2 == null)
return asc ? -1 : 1;
return (PRIORITIZED_QUERY_TYPES.indexOf(q2) - PRIORITIZED_QUERY_TYPES.indexOf(q1)) * (asc ? 1 : -1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

import io.swagger.annotations.*;
import org.mskcc.cbio.oncokb.config.annotation.PremiumPublicApi;
import org.mskcc.cbio.oncokb.config.annotation.PublicApi;
import org.mskcc.cbio.oncokb.model.EvidenceQueries;
import org.mskcc.cbio.oncokb.model.IndicatorQueryResp;
import org.mskcc.cbio.oncokb.model.ReferenceGenome;
import org.mskcc.cbio.oncokb.model.StructuralVariantType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -107,7 +108,7 @@ private List<Alteration> getVariants(VariantSearchQuery query) throws ApiExcepti
alterationSet.addAll(allAlterations);
} else {
AlterationBo alterationBo = new ApplicationContextSingleton().getAlterationBo();
List<Alteration> alterations = AlterationUtils.lookupVariant(query.getVariant(), true, allAlterations);
List<Alteration> alterations = AlterationUtils.lookupVariant(query.getVariant(), true, false, allAlterations);

// If this variant is not annotated
if (alterations == null || alterations.isEmpty()) {
Expand Down Expand Up @@ -138,7 +139,7 @@ private List<Alteration> getVariants(VariantSearchQuery query) throws ApiExcepti
alterationSet.addAll(AlterationUtils.getAlterationsByKnownEffectInGene(gene, AlterationUtils.getInferredAlterationsKnownEffect(query.getVariant()), false));
}
} else {
alterationList = AlterationUtils.lookupVariant(query.getVariant(), false, AlterationUtils.getAllAlterations());
alterationList = AlterationUtils.lookupVariant(query.getVariant(), false, false, AlterationUtils.getAllAlterations());
}
}
}
Expand Down
Loading

0 comments on commit 68da1cf

Please sign in to comment.