diff --git a/agr_api/src/main/java/org/alliancegenome/api/controller/AlleleController.java b/agr_api/src/main/java/org/alliancegenome/api/controller/AlleleController.java index 5537b9643..305c0b8e6 100644 --- a/agr_api/src/main/java/org/alliancegenome/api/controller/AlleleController.java +++ b/agr_api/src/main/java/org/alliancegenome/api/controller/AlleleController.java @@ -1,13 +1,13 @@ package org.alliancegenome.api.controller; -import java.time.LocalDateTime; - +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.core.Response; +import lombok.extern.slf4j.Slf4j; import org.alliancegenome.api.entity.AlleleDiseaseAnnotationDocument; +import org.alliancegenome.api.entity.AllelePhenotypeAnnotationDocument; import org.alliancegenome.api.rest.interfaces.AlleleRESTInterface; -import org.alliancegenome.api.service.AlleleService; -import org.alliancegenome.api.service.DiseaseESService; -import org.alliancegenome.api.service.EntityType; -import org.alliancegenome.api.service.VariantService; +import org.alliancegenome.api.service.*; import org.alliancegenome.api.service.helper.APIServiceHelper; import org.alliancegenome.api.translators.tdf.DiseaseAnnotationToTdfTranslator; import org.alliancegenome.cache.repository.helper.JsonResultResponse; @@ -17,14 +17,10 @@ import org.alliancegenome.core.translators.tdf.PhenotypeAnnotationToTdfTranslator; import org.alliancegenome.es.model.query.FieldFilter; import org.alliancegenome.es.model.query.Pagination; -import org.alliancegenome.neo4j.entity.PhenotypeAnnotation; import org.alliancegenome.neo4j.entity.node.Allele; import org.alliancegenome.neo4j.entity.node.Variant; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; -import jakarta.ws.rs.core.Response; -import lombok.extern.slf4j.Slf4j; +import java.time.LocalDateTime; @Slf4j @RequestScoped @@ -39,11 +35,13 @@ public class AlleleController implements AlleleRESTInterface { @Inject DiseaseESService diseaseESService; + @Inject + PhenotypeESService phenotypeESService; //@Inject //private HttpRequest request; private AlleleToTdfTranslator translator = new AlleleToTdfTranslator(); - private final PhenotypeAnnotationToTdfTranslator phenotypeAnnotationToTdfTranslator = new PhenotypeAnnotationToTdfTranslator(); + private PhenotypeAnnotationToTdfTranslator phenotypeTranslator = new PhenotypeAnnotationToTdfTranslator(); private final DiseaseAnnotationToTdfTranslator diseaseToTdfTranslator = new DiseaseAnnotationToTdfTranslator(); @Override @@ -106,25 +104,25 @@ public JsonResultResponse getAllelesPerSpecies(String species, Integer l } @Override - public JsonResultResponse getPhenotypePerAllele(String id, Integer limit, Integer page, String phenotype, String source, String reference, String sortBy) { + public JsonResultResponse getPhenotypePerAllele( + String id, + Integer limit, + Integer page, + String phenotype, + String source, + String reference, + String sortBy) { long startTime = System.currentTimeMillis(); Pagination pagination = new Pagination(page, limit, sortBy, null); - pagination.addFieldFilter(FieldFilter.PHENOTYPE, phenotype); - pagination.addFieldFilter(FieldFilter.SOURCE, source); - pagination.addFieldFilter(FieldFilter.FREFERENCE, reference); - if (pagination.hasErrors()) { - RestErrorMessage message = new RestErrorMessage(); - message.setErrors(pagination.getErrors()); - throw new RestErrorException(message); - } - + pagination.addFilterOption("phenotypeStatement", phenotype); + pagination.addFilterOption("pubmedPubModIDs", reference); try { - JsonResultResponse phenotypeAnnotation = alleleService.getPhenotype(id, pagination); - phenotypeAnnotation.setHttpServletRequest(null); - phenotypeAnnotation.calculateRequestDuration(startTime); - return phenotypeAnnotation; + JsonResultResponse phenotypes = phenotypeESService.getAllelePhenotypeAnnotations(id, pagination, false); + phenotypes.setHttpServletRequest(null); + phenotypes.calculateRequestDuration(startTime); + return phenotypes; } catch (Exception e) { - log.error("Error while retrieving phenotype info", e); + log.error("Error while retrieving phenotypes", e); RestErrorMessage error = new RestErrorMessage(); error.addErrorMessage(e.getMessage()); throw new RestErrorException(error); @@ -133,34 +131,37 @@ public JsonResultResponse getPhenotypePerAllele(String id, @Override public Response getPhenotypesPerAlleleDownload(String id, String phenotype, String source, String reference, String sortBy) { - JsonResultResponse response = getPhenotypePerAllele(id, - Integer.MAX_VALUE, - 1, - phenotype, - source, - reference, - sortBy); - Response.ResponseBuilder responseBuilder = Response.ok(phenotypeAnnotationToTdfTranslator.getAllRowsForAlleles(response.getResults())); + // retrieve all records + JsonResultResponse response = + getPhenotypePerAllele(id, + 250000, + 1, + phenotype, + source, + reference, + sortBy); + Response.ResponseBuilder responseBuilder = Response.ok(phenotypeTranslator.getAllRows(response.getResults())); APIServiceHelper.setDownloadHeader(id, EntityType.ALLELE, EntityType.PHENOTYPE, responseBuilder); return responseBuilder.build(); } @Override - public JsonResultResponse getDiseasePerAllele(String alleleID, - String filterOptions, - String filterReference, - String diseaseTerm, - String filterSource, - String geneticEntity, - String geneticEntityType, - String associationType, - String diseaseQualifier, - String evidenceCode, - Boolean debug, - Integer limit, - Integer page, - String sortBy, - String asc) { + public JsonResultResponse getDiseasePerAllele( + String alleleID, + String filterOptions, + String filterReference, + String diseaseTerm, + String filterSource, + String geneticEntity, + String geneticEntityType, + String associationType, + String diseaseQualifier, + String evidenceCode, + Boolean debug, + Integer limit, + Integer page, + String sortBy, + String asc) { LocalDateTime startDate = LocalDateTime.now(); Pagination pagination = new Pagination(page, limit, sortBy, asc); diff --git a/agr_api/src/main/java/org/alliancegenome/api/controller/GeneController.java b/agr_api/src/main/java/org/alliancegenome/api/controller/GeneController.java index 446fb9957..d68b4c9bf 100644 --- a/agr_api/src/main/java/org/alliancegenome/api/controller/GeneController.java +++ b/agr_api/src/main/java/org/alliancegenome/api/controller/GeneController.java @@ -1,26 +1,19 @@ package org.alliancegenome.api.controller; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.core.*; +import lombok.extern.slf4j.Slf4j; import org.alliancegenome.api.dto.ExpressionSummary; import org.alliancegenome.api.entity.AlleleVariantSequence; import org.alliancegenome.api.entity.DiseaseRibbonSummary; +import org.alliancegenome.api.entity.GenePhenotypeAnnotationDocument; import org.alliancegenome.api.entity.GeneGeneticInteractionDocument; import org.alliancegenome.api.entity.GeneMolecularInteractionDocument; import org.alliancegenome.api.entity.GeneToGeneParalogyDocument; import org.alliancegenome.api.rest.interfaces.GeneRESTInterface; -import org.alliancegenome.api.service.AlleleService; -import org.alliancegenome.api.service.DiseaseESService; -import org.alliancegenome.api.service.EntityType; -import org.alliancegenome.api.service.ExpressionService; -import org.alliancegenome.api.service.GeneService; -import org.alliancegenome.api.service.GeneToGeneParalogyESService; +import org.alliancegenome.api.service.*; import org.alliancegenome.api.service.helper.APIServiceHelper; import org.alliancegenome.api.translators.tdf.DiseaseAnnotationToTdfTranslator; import org.alliancegenome.cache.repository.ExpressionCacheRepository; @@ -39,7 +32,6 @@ import org.alliancegenome.neo4j.entity.DiseaseAnnotation; import org.alliancegenome.neo4j.entity.DiseaseSummary; import org.alliancegenome.neo4j.entity.EntitySummary; -import org.alliancegenome.neo4j.entity.PhenotypeAnnotation; import org.alliancegenome.neo4j.entity.PrimaryAnnotatedEntity; import org.alliancegenome.neo4j.entity.node.Allele; import org.alliancegenome.neo4j.entity.node.Gene; @@ -47,39 +39,41 @@ import org.alliancegenome.neo4j.view.OrthologyFilter; import org.apache.commons.collections.CollectionUtils; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.MultivaluedMap; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; -import lombok.extern.slf4j.Slf4j; +import java.util.*; +import java.util.stream.Collectors; @Slf4j @RequestScoped public class GeneController implements GeneRESTInterface { - @Inject GeneService geneService; + @Inject + GeneService geneService; - @Inject AlleleService alleleService; + @Inject + AlleleService alleleService; - @Inject ExpressionCacheRepository expressionCacheRepository; + @Inject + ExpressionCacheRepository expressionCacheRepository; - @Inject DiseaseService diseaseService; + @Inject + DiseaseService diseaseService; - @Inject OrthologyCacheRepository orthologyCacheService; + @Inject + OrthologyCacheRepository orthologyCacheService; //@Inject //private HttpRequest request; - @Inject ExpressionService service; + @Inject + ExpressionService service; @Inject DiseaseESService diseaseESService; @Inject GeneToGeneParalogyESService geneToGeneParalogyESService; + @Inject + PhenotypeESService phenotypeESService; private static final PhenotypeAnnotationToTdfTranslator translator = new PhenotypeAnnotationToTdfTranslator(); private static final AlleleToTdfTranslator alleleTranslator = new AlleleToTdfTranslator(); @@ -144,26 +138,27 @@ public JsonResultResponse getAllelesPerGene(String id, } @Override - public JsonResultResponse getAllelesVariantPerGene(String id, - Integer limit, - Integer page, - String sortBy, - String asc, - String symbol, - String associatedGeneSymbol, - String synonyms, - String hgvsgName, - String variantType, - String molecularConsequence, - String impact, - String sequenceFeatureType, - String sequenceFeature, - String variantPolyphen, - String variantSift, - String hasDisease, - String hasPhenotype, - String category, - String location) { + public JsonResultResponse getAllelesVariantPerGene( + String id, + Integer limit, + Integer page, + String sortBy, + String asc, + String symbol, + String associatedGeneSymbol, + String synonyms, + String hgvsgName, + String variantType, + String molecularConsequence, + String impact, + String sequenceFeatureType, + String sequenceFeature, + String variantPolyphen, + String variantSift, + String hasDisease, + String hasPhenotype, + String category, + String location) { long startTime = System.currentTimeMillis(); Pagination pagination = new Pagination(page, limit, sortBy, asc); pagination.addFieldFilter(FieldFilter.SYMBOL, symbol); @@ -204,42 +199,43 @@ public JsonResultResponse getAllelesVariantPerGene(String } @Override - public Response getAllelesVariantPerGeneDownload(String id, - String symbol, - String associatedGeneSymbol, - String synonyms, - String hgvsgName, - String variantType, - String molecularConsequence, - String impact, - String sequenceFeatureType, - String sequenceFeature, - String variantPolyphen, - String variantSift, - String hasDisease, - String hasPhenotype, - String category, - String location) { + public Response getAllelesVariantPerGeneDownload( + String id, + String symbol, + String associatedGeneSymbol, + String synonyms, + String hgvsgName, + String variantType, + String molecularConsequence, + String impact, + String sequenceFeatureType, + String sequenceFeature, + String variantPolyphen, + String variantSift, + String hasDisease, + String hasPhenotype, + String category, + String location) { JsonResultResponse alleles = getAllelesVariantPerGene(id, - Integer.MAX_VALUE, - 1, - null, - null, - symbol, - associatedGeneSymbol, - synonyms, - hgvsgName, - variantType, - molecularConsequence, - impact, - sequenceFeatureType, - sequenceFeature, - variantPolyphen, - variantSift, - hasDisease, - hasPhenotype, - category, - location); + Integer.MAX_VALUE, + 1, + null, + null, + symbol, + associatedGeneSymbol, + synonyms, + hgvsgName, + variantType, + molecularConsequence, + impact, + sequenceFeatureType, + sequenceFeature, + variantPolyphen, + variantSift, + hasDisease, + hasPhenotype, + category, + location); Response.ResponseBuilder responseBuilder = Response.ok(alleleTranslator.getAllAlleleVariantDetailRows(alleles.getResults())); APIServiceHelper.setDownloadHeader(id, EntityType.GENE, EntityType.ALLELESANDVARIANT, responseBuilder); @@ -247,16 +243,17 @@ public Response getAllelesVariantPerGeneDownload(String id, } @Override - public Response getAllelesPerGeneDownload(String id, - String sortBy, - String asc, - String symbol, - String synonym, - String variantType, - String molecularConsequence, - String phenotype, - String source, - String disease) { + public Response getAllelesPerGeneDownload( + String id, + String sortBy, + String asc, + String symbol, + String synonym, + String variantType, + String molecularConsequence, + String phenotype, + String source, + String disease) { Pagination pagination = new Pagination(1, Integer.MAX_VALUE, sortBy, asc); pagination.addFieldFilter(FieldFilter.SYMBOL, symbol); pagination.addFieldFilter(FieldFilter.SYNONYMS, synonym); @@ -447,10 +444,19 @@ public Response getMolecularInteractionsDownload(String id, String sortBy, Strin } @Override - public JsonResultResponse getPhenotypeAnnotations(String id, Integer limit, Integer page, String sortBy, String geneticEntity, String geneticEntityType, String phenotype, String reference, String asc) { + public JsonResultResponse getPhenotypeAnnotations( + String id, Integer limit, Integer page, String sortBy, + String geneticEntity, + String geneticEntityType, + String phenotype, + String reference, + String asc) { long startTime = System.currentTimeMillis(); + Pagination pagination = new Pagination(page, limit, sortBy, asc); + pagination.addFilterOption("phenotypeStatement", phenotype); + pagination.addFilterOption("pubmedPubModIDs", reference); try { - JsonResultResponse phenotypes = getPhenotypeAnnotationDocumentJsonResultResponse(id, limit, page, sortBy, geneticEntity, geneticEntityType, phenotype, reference, asc); + JsonResultResponse phenotypes = phenotypeESService.getGenePhenotypeAnnotations(id, pagination, false); phenotypes.setHttpServletRequest(null); phenotypes.calculateRequestDuration(startTime); return phenotypes; @@ -464,21 +470,21 @@ public JsonResultResponse getPhenotypeAnnotations(String id @Override public Response getPhenotypeAnnotationsDownloadFile( - String id, - String sortBy, - String geneticEntity, - String geneticEntityType, - String phenotype, - String reference, - String asc) { + String id, + String sortBy, + String geneticEntity, + String geneticEntityType, + String phenotype, + String reference, + String asc) { // retrieve all records - JsonResultResponse response = - getPhenotypeAnnotationDocumentJsonResultResponse(id, Integer.MAX_VALUE, 1, sortBy, - geneticEntity, - geneticEntityType, - phenotype, - reference, - asc); + JsonResultResponse response = + getPhenotypeAnnotations(id, 250000, 1, sortBy, + geneticEntity, + geneticEntityType, + phenotype, + reference, + asc); Response.ResponseBuilder responseBuilder = Response.ok(translator.getAllRows(response.getResults())); APIServiceHelper.setDownloadHeader(id, EntityType.GENE, EntityType.PHENOTYPE, responseBuilder); return responseBuilder.build(); @@ -503,21 +509,21 @@ public JsonResultResponse getDiseaseAnnotations(String id, In @Override public Response getDiseaseAnnotationsDownloadFile( - String id, - String sortBy, - String geneticEntity, - String geneticEntityType, - String disease, - String reference, - String asc) { + String id, + String sortBy, + String geneticEntity, + String geneticEntityType, + String disease, + String reference, + String asc) { // retrieve all records JsonResultResponse response = - getDiseaseAnnotationDocumentJsonResultResponse(id, Integer.MAX_VALUE, 1, sortBy, - geneticEntity, - geneticEntityType, - disease, - reference, - asc); + getDiseaseAnnotationDocumentJsonResultResponse(id, Integer.MAX_VALUE, 1, sortBy, + geneticEntity, + geneticEntityType, + disease, + reference, + asc); Response.ResponseBuilder responseBuilder = Response.ok(diseaseTranslator.getAllRowsForGenes(response.getResults())); APIServiceHelper.setDownloadHeader(id, EntityType.GENE, EntityType.DISEASE, responseBuilder); return responseBuilder.build(); @@ -560,20 +566,6 @@ public JsonResultResponse getPrimaryAnnotatedEntityForMo } } - private JsonResultResponse getPhenotypeAnnotationDocumentJsonResultResponse(String id, Integer limit, Integer page, String sortBy, String geneticEntity, String geneticEntityType, String phenotype, String reference, String asc) { - if (sortBy.isEmpty()) { - sortBy = FieldFilter.PHENOTYPE.getName(); - } - Pagination pagination = new Pagination(page, limit, sortBy, asc); - pagination.addFieldFilter(FieldFilter.GENETIC_ENTITY, geneticEntity); - pagination.addFieldFilter(FieldFilter.GENETIC_ENTITY_TYPE, geneticEntityType); - pagination.addFieldFilter(FieldFilter.PHENOTYPE, phenotype); - pagination.addFieldFilter(FieldFilter.FREFERENCE, reference); - JsonResultResponse phenotypeAnnotations = geneService.getPhenotypeAnnotations(id, pagination); - phenotypeAnnotations.addAnnotationSummarySupplementalData(getPhenotypeSummary(id)); - return phenotypeAnnotations; - } - private JsonResultResponse getDiseaseAnnotationDocumentJsonResultResponse(String id, Integer limit, Integer page, String sortBy, String geneticEntity, String geneticEntityType, String disease, String reference, String asc) { if (sortBy.isEmpty()) { sortBy = FieldFilter.DISEASE.getName(); @@ -611,9 +603,9 @@ private JsonResultResponse getEmpiricalDiseaseAnnotation(Stri pagination.addFieldFilter(FieldFilter.FREFERENCE, reference); MultivaluedMap parameterMap = ui.getQueryParameters(); List invalidFilterNames = parameterMap.entrySet().stream() - .filter(entry -> FieldFilter.hasFieldFilterPrefix(entry.getKey()) && !FieldFilter.isFieldFilterValue(entry.getKey())) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); + .filter(entry -> FieldFilter.hasFieldFilterPrefix(entry.getKey()) && !FieldFilter.isFieldFilterValue(entry.getKey())) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); pagination.setInvalidFilterList(invalidFilterNames); return diseaseService.getDiseaseAnnotations(id, pagination); } @@ -684,9 +676,9 @@ public JsonResultResponse getGeneOrthologyWithExpression(String id, orthologyFilter.setStart(1); JsonResultResponse orthologs = orthologyCacheService.getOrthologyGenes(geneList, orthologyFilter); List filteredList = orthologs.getResults().stream() - .filter(orthologView -> expressionCacheRepository.hasExpression(orthologView.getHomologGene().getPrimaryKey())) - .sorted(Comparator.comparing(orthologView -> orthologView.getHomologGene().getSymbol().toLowerCase())) - .collect(Collectors.toList()); + .filter(orthologView -> expressionCacheRepository.hasExpression(orthologView.getHomologGene().getPrimaryKey())) + .sorted(Comparator.comparing(orthologView -> orthologView.getHomologGene().getSymbol().toLowerCase())) + .collect(Collectors.toList()); orthologs.setResults(filteredList); orthologs.setTotal(filteredList.size()); orthologs.setHttpServletRequest(null); @@ -735,45 +727,46 @@ public JsonResultResponse getDiseaseByExperiment(String id, String asc, UriInfo ui) { return getEmpiricalDiseaseAnnotation(id, - limit, - page, - sortBy, - geneticEntity, - geneticEntityType, - disease, - associationType, - evidenceCode, - source, - reference, - asc, - ui); + limit, + page, + sortBy, + geneticEntity, + geneticEntityType, + disease, + associationType, + evidenceCode, + source, + reference, + asc, + ui); } @Override - public Response getDiseaseByExperimentDownload(String id, - String sortBy, - String geneticEntity, - String geneticEntityType, - String disease, - String associationType, - String evidenceCode, - String source, - String reference, - String asc, - UriInfo ui) { + public Response getDiseaseByExperimentDownload( + String id, + String sortBy, + String geneticEntity, + String geneticEntityType, + String disease, + String associationType, + String evidenceCode, + String source, + String reference, + String asc, + UriInfo ui) { JsonResultResponse response = getEmpiricalDiseaseAnnotation(id, - Integer.MAX_VALUE, - null, - sortBy, - geneticEntity, - geneticEntityType, - disease, - associationType, - evidenceCode, - source, - reference, - asc, - ui); + Integer.MAX_VALUE, + null, + sortBy, + geneticEntity, + geneticEntityType, + disease, + associationType, + evidenceCode, + source, + reference, + asc, + ui); Response.ResponseBuilder responseBuilder = Response.ok(diseaseTranslator.getEmpiricalDiseaseByGene(response.getResults())); responseBuilder.type(MediaType.TEXT_PLAIN_TYPE); responseBuilder.header("Content-Disposition", "attachment; filename=\"DiseaseAssociationsViaEmpiricalData-" + id.replace(":", "-") + ".tsv\""); @@ -792,19 +785,20 @@ public EntitySummary getPhenotypeSummary(String id) { } @Override - public JsonResultResponse getTransgenicAlleles(String geneID, - Integer limit, - Integer page, - String sortBy, - String alleleSymbol, - String constructSymbol, - String constructRegulatedGene, - String constructTargetedGene, - String constructExpressedGene, - String species, - String hasPhenotype, - String hasDisease, - UriInfo ui) { + public JsonResultResponse getTransgenicAlleles( + String geneID, + Integer limit, + Integer page, + String sortBy, + String alleleSymbol, + String constructSymbol, + String constructRegulatedGene, + String constructTargetedGene, + String constructExpressedGene, + String species, + String hasPhenotype, + String hasDisease, + UriInfo ui) { if (sortBy != null && sortBy.isBlank()) { sortBy = "transgenicAllele"; } @@ -848,18 +842,18 @@ public Response getTransgenicAllelesPerGeneDownload(String geneId, String hasDisease, UriInfo ui) { JsonResultResponse alleles = getTransgenicAlleles(geneId, - Integer.MAX_VALUE, - 1, - sortBy, - alleleSymbol, - constructSymbol, - constructRegulatedGene, - constructTargetedGene, - constructExpressedGene, - species, - hasPhenotype, - hasDisease, - ui); + Integer.MAX_VALUE, + 1, + sortBy, + alleleSymbol, + constructSymbol, + constructRegulatedGene, + constructTargetedGene, + constructExpressedGene, + species, + hasPhenotype, + hasDisease, + ui); Response.ResponseBuilder responseBuilder = Response.ok(alleleTranslator.getAllTransgenicAlleleRows(alleles.getResults())); APIServiceHelper.setDownloadHeader(geneId, EntityType.GENE, EntityType.TRANSGENICALLELE, responseBuilder); diff --git a/agr_api/src/main/java/org/alliancegenome/api/rest/interfaces/AlleleRESTInterface.java b/agr_api/src/main/java/org/alliancegenome/api/rest/interfaces/AlleleRESTInterface.java index 992c5965b..09873eb4f 100644 --- a/agr_api/src/main/java/org/alliancegenome/api/rest/interfaces/AlleleRESTInterface.java +++ b/agr_api/src/main/java/org/alliancegenome/api/rest/interfaces/AlleleRESTInterface.java @@ -1,6 +1,7 @@ package org.alliancegenome.api.rest.interfaces; import org.alliancegenome.api.entity.AlleleDiseaseAnnotationDocument; +import org.alliancegenome.api.entity.AllelePhenotypeAnnotationDocument; import org.alliancegenome.cache.repository.helper.JsonResultResponse; import org.alliancegenome.neo4j.entity.DiseaseAnnotation; import org.alliancegenome.neo4j.entity.PhenotypeAnnotation; @@ -84,13 +85,13 @@ JsonResultResponse getAllelesPerSpecies( @Operation(summary = "Retrieve all phenotypes of a given allele") @APIResponses(value = { @APIResponse(responseCode = "404", description = "Missing phenotypes", content = @Content(mediaType = "text/plain")), @APIResponse(responseCode = "200", description = "Phenotypes for a given Allele.", content = @Content(mediaType = "application/json", schema = @Schema(implementation = Null.class))) }) - @JsonView(value = { View.PhenotypeAPI.class }) - JsonResultResponse getPhenotypePerAllele(@Parameter(in = ParameterIn.PATH, name = "id", description = "Search for Phenotypes for a given Allele by ID", required = true, schema = @Schema(type = SchemaType.STRING)) @PathParam("id") String id, - @Parameter(in = ParameterIn.QUERY, name = "limit", description = "Number of rows returned", schema = @Schema(type = SchemaType.INTEGER)) @DefaultValue("20") @QueryParam("limit") Integer limit, - @Parameter(in = ParameterIn.QUERY, name = "page", description = "Page number", schema = @Schema(type = SchemaType.INTEGER)) @DefaultValue("1") @QueryParam("page") Integer page, - @Parameter(in = ParameterIn.QUERY, name = "filter.termName", description = "termName annotation") @QueryParam("filter.termName") String phenotype, @Parameter(in = ParameterIn.QUERY, name = "filter.source", description = "Source") @QueryParam("filter.source") String source, - @Parameter(in = ParameterIn.QUERY, name = "filter.reference", description = "Reference number: PUBMED or a Pub ID from the MOD") @QueryParam("filter.reference") String reference, - @Parameter(in = ParameterIn.QUERY, name = "sortBy", description = "Field name by which to sort", schema = @Schema(type = SchemaType.STRING)) @DefaultValue("symbol") @QueryParam("sortBy") String sortBy + JsonResultResponse getPhenotypePerAllele(@Parameter(in = ParameterIn.PATH, name = "id", description = "Search for Phenotypes for a given Allele by ID", required = true, schema = @Schema(type = SchemaType.STRING)) @PathParam("id") String id, + @Parameter(in = ParameterIn.QUERY, name = "limit", description = "Number of rows returned", schema = @Schema(type = SchemaType.INTEGER)) @DefaultValue("20") @QueryParam("limit") Integer limit, + @Parameter(in = ParameterIn.QUERY, name = "page", description = "Page number", schema = @Schema(type = SchemaType.INTEGER)) @DefaultValue("1") @QueryParam("page") Integer page, + @Parameter(in = ParameterIn.QUERY, name = "filter.termName", description = "termName annotation") @QueryParam("filter.termName") String phenotype, @Parameter(in = ParameterIn.QUERY, name = "filter.source", description = "Source") + @QueryParam("filter.source") String source, + @Parameter(in = ParameterIn.QUERY, name = "filter.reference", description = "Reference number: PUBMED or a Pub ID from the MOD") @QueryParam("filter.reference") String reference, + @Parameter(in = ParameterIn.QUERY, name = "sortBy", description = "Field name by which to sort", schema = @Schema(type = SchemaType.STRING)) @DefaultValue("symbol") @QueryParam("sortBy") String sortBy ); diff --git a/agr_api/src/main/java/org/alliancegenome/api/rest/interfaces/GeneRESTInterface.java b/agr_api/src/main/java/org/alliancegenome/api/rest/interfaces/GeneRESTInterface.java index c30b50324..5669ff4f4 100644 --- a/agr_api/src/main/java/org/alliancegenome/api/rest/interfaces/GeneRESTInterface.java +++ b/agr_api/src/main/java/org/alliancegenome/api/rest/interfaces/GeneRESTInterface.java @@ -9,6 +9,7 @@ import org.alliancegenome.api.entity.GeneGeneticInteractionDocument; import org.alliancegenome.api.entity.GeneMolecularInteractionDocument; import org.alliancegenome.api.entity.GeneToGeneParalogyDocument; +import org.alliancegenome.api.entity.GenePhenotypeAnnotationDocument; import org.alliancegenome.cache.repository.helper.JsonResultResponse; import org.alliancegenome.neo4j.entity.DiseaseAnnotation; import org.alliancegenome.neo4j.entity.DiseaseSummary; @@ -243,7 +244,6 @@ Response getAllelesPerGeneDownload( @GET @Path("/{id}/phenotypes") - @JsonView(value = {View.PhenotypeAPI.class}) @Operation(summary = "Retrieve phenotype term name annotations for a given gene") @APIResponses( value = { @@ -255,8 +255,8 @@ Response getAllelesPerGeneDownload( responseCode = "200", description = "Phenotype annotations for a gene.", content = @Content(mediaType = "application/json", - schema = @Schema(implementation = Null.class)))}) - JsonResultResponse getPhenotypeAnnotations( + schema = @Schema(implementation = PhenotypeAnnotation.class)))}) + JsonResultResponse getPhenotypeAnnotations( @Parameter(in = ParameterIn.PATH, name = "id", description = "Gene by ID: e.g. ZFIN:ZDB-GENE-990415-8", required = true, schema = @Schema(type = SchemaType.STRING)) @PathParam("id") String id, @Parameter(in = ParameterIn.QUERY, name = "limit", description = "Number of rows returned", schema = @Schema(type = SchemaType.INTEGER)) diff --git a/agr_api/src/main/java/org/alliancegenome/api/service/DiseaseESService.java b/agr_api/src/main/java/org/alliancegenome/api/service/DiseaseESService.java index b6d7bab7d..9d10a61af 100644 --- a/agr_api/src/main/java/org/alliancegenome/api/service/DiseaseESService.java +++ b/agr_api/src/main/java/org/alliancegenome/api/service/DiseaseESService.java @@ -1,35 +1,10 @@ package org.alliancegenome.api.service; -import static java.util.stream.Collectors.toList; -import static org.alliancegenome.cache.repository.helper.JsonResultResponse.DISTINCT_FIELD_VALUES; -import static org.elasticsearch.index.query.QueryBuilders.boolQuery; -import static org.elasticsearch.index.query.QueryBuilders.matchQuery; -import static org.elasticsearch.index.query.QueryBuilders.termQuery; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import org.alliancegenome.api.entity.AGMDiseaseAnnotationDocument; -import org.alliancegenome.api.entity.AlleleDiseaseAnnotationDocument; -import org.alliancegenome.api.entity.DiseaseEntitySubgroupSlim; -import org.alliancegenome.api.entity.DiseaseRibbonEntity; -import org.alliancegenome.api.entity.DiseaseRibbonSummary; -import org.alliancegenome.api.entity.GeneDiseaseAnnotationDocument; -import org.alliancegenome.api.service.helper.ElasticSearchHelper; -import org.alliancegenome.api.service.helper.GeneDiseaseSearchHelper; +import jakarta.enterprise.context.RequestScoped; +import org.alliancegenome.api.entity.*; import org.alliancegenome.cache.repository.helper.JsonResultResponse; import org.alliancegenome.core.api.service.DiseaseRibbonService; -import org.alliancegenome.es.index.site.dao.SearchDAO; import org.alliancegenome.es.model.query.Pagination; -import org.alliancegenome.neo4j.entity.SpeciesType; -import org.alliancegenome.neo4j.entity.node.DOTerm; import org.alliancegenome.neo4j.entity.node.Gene; import org.alliancegenome.neo4j.entity.node.SimpleTerm; import org.alliancegenome.neo4j.repository.DiseaseRepository; @@ -38,40 +13,25 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.MatchQueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.TermQueryBuilder; import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.aggregations.AggregationBuilder; -import org.elasticsearch.search.aggregations.AggregationBuilders; -import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation; -import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; -import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; -import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.SortOrder; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import java.util.*; +import java.util.stream.Collectors; -import io.quarkus.logging.Log; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; +import static java.util.stream.Collectors.toList; +import static org.alliancegenome.cache.repository.helper.JsonResultResponse.DISTINCT_FIELD_VALUES; +import static org.elasticsearch.index.query.QueryBuilders.boolQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchQuery; @RequestScoped -public class DiseaseESService { - - @Inject - ObjectMapper mapper; +public class DiseaseESService extends ESService { private static final GeneRepository geneRepository = new GeneRepository(); private static final DiseaseRepository diseaseRepository = new DiseaseRepository(); private static final DiseaseRibbonService diseaseRibbonService = new DiseaseRibbonService(diseaseRepository); - private static final SearchDAO searchDAO = new SearchDAO(); - private static final GeneDiseaseSearchHelper geneDiseaseSearchHelper = new GeneDiseaseSearchHelper(); - private static final ElasticSearchHelper elasticSearchHelper = new ElasticSearchHelper(); // termID may be used in the future when converting disease page to new ES stack. public JsonResultResponse getRibbonDiseaseAnnotations(String focusTaxonId, List geneIDs, String termID, Pagination pagination, boolean excludeNegated, boolean debug) { @@ -83,8 +43,8 @@ public JsonResultResponse getRibbonDiseaseAnnotat ret.setSupplementalData(getSupplementalData(focusTaxonId, true, debug, query)); // add table filter - elasticSearchHelper.addTableFilter(pagination, query); - SearchResponse searchResponse = elasticSearchHelper.getSearchResponse(query, pagination, getAnnotationSorts(focusTaxonId, debug), false); + addTableFilter(pagination, query); + SearchResponse searchResponse = getSearchResponse(query, pagination, getAnnotationSorts(focusTaxonId, debug), false); ret.setTotal((int) searchResponse.getHits().getTotalHits().value); List list = Arrays.stream(searchResponse.getHits().getHits()) @@ -116,39 +76,6 @@ private Map getSupplementalData(String focusTaxonId, boolean use return supplementalData; } - private BoolQueryBuilder getBaseQuery(List entityIDs, String termID, boolean excludeNegated, String recordType, boolean excludeViaOrthologyRecords) { - BoolQueryBuilder bool = boolQuery(); - BoolQueryBuilder bool2 = boolQuery(); - bool.must(bool2); - - bool.filter(termQuery("category", recordType)); - - if (CollectionUtils.isNotEmpty(entityIDs)) { - for (String geneId : entityIDs) { - setEntityIdMatcher(geneId, bool2); - } - } - if (excludeNegated) { - bool.must(matchQuery("primaryAnnotations.negated", false)); - } - if (excludeViaOrthologyRecords) { - bool.must(matchQuery("viaOrthologyOrder", 0)); - } - if (termID != null) { - BoolQueryBuilder bool3 = boolQuery(); - bool.must(bool3); - if (termID.equals(DiseaseRibbonSummary.DOID_OTHER)) { - BoolQueryBuilder orClause = boolQuery(); - DOTerm.getAllOtherDiseaseTerms().forEach(parentID -> orClause.should(QueryBuilders.termQuery("parentSlimIDs.keyword", parentID))); - bool3.should(orClause); - - } else { - bool3.should(new MatchQueryBuilder("parentSlimIDs.keyword", termID)); - } - } - return bool; - } - public JsonResultResponse getDiseaseAnnotations(String alleleID, Pagination pagination, boolean excludeNegated, boolean debug) { // unfiltered base query BoolQueryBuilder query = getBaseQuery(List.of(alleleID), null, excludeNegated, "allele_disease_annotation", true); @@ -157,8 +84,8 @@ public JsonResultResponse getDiseaseAnnotations ret.setSupplementalData(getSupplementalData(null, false, debug, query)); // add table filter - elasticSearchHelper.addTableFilter(pagination, query); - SearchResponse searchResponse = elasticSearchHelper.getSearchResponse(query, pagination, getAnnotationSorts(null, debug), false); + addTableFilter(pagination, query); + SearchResponse searchResponse = getSearchResponse(query, pagination, getAnnotationSorts(null, debug), false); ret.setTotal((int) searchResponse.getHits().getTotalHits().value); List list = Arrays.stream(searchResponse.getHits().getHits()) @@ -177,49 +104,6 @@ public JsonResultResponse getDiseaseAnnotations } - private Map> getAggregations(BoolQueryBuilder bool, Map aggregationFields, String focusTaxonId, boolean useSpeciesAggregation, boolean debug) { - List aggBuilders = new ArrayList<>(); - aggregationFields.forEach((field, colName) -> { - String fieldNameAgg = field + "_agg"; - TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms(fieldNameAgg); - aggregationBuilder.bucketCardinality(); - aggregationBuilder.field(field); - aggBuilders.add(aggregationBuilder); - }); - - SearchResponse searchResponseHistogram = searchDAO.performQuery( - bool, aggBuilders, null, geneDiseaseSearchHelper.getResponseFields(), - 0, 0, new HighlightBuilder(), useSpeciesAggregation ? getAnnotationSorts(focusTaxonId, debug) : null, debug); - - Map> distinctFieldValueMap = new HashMap<>(); - aggregationFields.forEach((field, colName) -> { - String fieldNameAgg = field + "_agg"; - List values = ((ParsedStringTerms) searchResponseHistogram.getAggregations().get(fieldNameAgg)).getBuckets().stream() - .map(MultiBucketsAggregation.Bucket::getKeyAsString).collect(Collectors.toList()); - distinctFieldValueMap.put(colName, values); - }); - return distinctFieldValueMap; - } - - private LinkedHashMap getAnnotationSorts(String focusTaxonId, boolean debug) { - SpeciesType type = SpeciesType.getTypeByID(focusTaxonId); - LinkedHashMap sorts = new LinkedHashMap<>(); - if (type != null) { - sorts.put("speciesOrder." + type.getTaxonIDPart(), SortOrder.ASC); - } else { - if (debug) { - Log.info("Species could not be found for: " + focusTaxonId); - } else { - Log.debug("Species could not be found for: " + focusTaxonId); - } - } - sorts.put("object.name.sort", SortOrder.ASC); - if (debug) { - Log.info(sorts); - } - return sorts; - } - public DiseaseRibbonSummary getDiseaseRibbonSummary(List geneIDs, Boolean includeNegation, boolean debug) { DiseaseRibbonSummary summary = diseaseRibbonService.getDiseaseRibbonSectionInfo(); Pagination pagination = new Pagination(); @@ -312,9 +196,9 @@ private JsonResultResponse getDiseaseAnnotationLi // create histogram of select columns of unfiltered query - elasticSearchHelper.addTableFilter(pagination, bool); + addTableFilter(pagination, bool); - SearchResponse searchResponse = elasticSearchHelper.getSearchResponse(bool, pagination, null, debug); + SearchResponse searchResponse = getSearchResponse(bool, pagination, null, debug); JsonResultResponse ret = new JsonResultResponse<>(); ret.setTotal((int) searchResponse.getHits().getTotalHits().value); @@ -334,12 +218,6 @@ private JsonResultResponse getDiseaseAnnotationLi return ret; } - private static void setEntityIdMatcher(String geneID, BoolQueryBuilder bool2) { - bool2.should(new MatchQueryBuilder("subject.curie.keyword", geneID)); - bool2.should(new MatchQueryBuilder("subject.primaryExternalId.keyword", geneID)); - bool2.should(new MatchQueryBuilder("subject.modInternalId.keyword", geneID)); - } - public JsonResultResponse getDiseaseAnnotationsWithGenes(String diseaseID, Pagination pagination, boolean excludeNegatedAnnotation, boolean debug) { BoolQueryBuilder bool = boolQuery(); BoolQueryBuilder bool2 = boolQuery(); @@ -352,7 +230,7 @@ public JsonResultResponse getDiseaseAnnotationsWi ret.setSupplementalData(getSupplementalData(null, true, debug, bool)); // create histogram of select columns of unfiltered query - elasticSearchHelper.addTableFilter(pagination, bool); + addTableFilter(pagination, bool); // Sorting sets for different names of the sorting selection box Map> sortingSetMap = new HashMap<>(); @@ -369,7 +247,7 @@ public JsonResultResponse getDiseaseAnnotationsWi } sortFields.forEach(sortField -> sortingMap.put(sortField, SortOrder.ASC)); - SearchResponse searchResponse = elasticSearchHelper.getSearchResponse(bool, pagination, sortingMap, debug); + SearchResponse searchResponse = getSearchResponse(bool, pagination, sortingMap, debug); ret.setTotal((int) searchResponse.getHits().getTotalHits().value); List list = new ArrayList<>(); @@ -399,7 +277,7 @@ public JsonResultResponse getDiseaseAnnotationsWit ret.setSupplementalData(getSupplementalData(null, true, debug, bool)); // create histogram of select columns of unfiltered query - elasticSearchHelper.addTableFilter(pagination, bool); + addTableFilter(pagination, bool); // Sorting sets for different names of the sorting selection box Map> sortingSetMap = new HashMap<>(); @@ -416,7 +294,7 @@ public JsonResultResponse getDiseaseAnnotationsWit } sortFields.forEach(sortField -> sortingMap.put(sortField, SortOrder.ASC)); - SearchResponse searchResponse = elasticSearchHelper.getSearchResponse(bool, pagination, sortingMap, debug); + SearchResponse searchResponse = getSearchResponse(bool, pagination, sortingMap, debug); ret.setTotal((int) searchResponse.getHits().getTotalHits().value); List list = new ArrayList<>(); @@ -447,7 +325,7 @@ public JsonResultResponse getDiseaseAnnotations ret.setSupplementalData(supData); // create histogram of select columns of unfiltered query - elasticSearchHelper.addTableFilter(pagination, bool); + addTableFilter(pagination, bool); // Sorting sets for different names of the sorting selection box Map> sortingSetMap = new HashMap<>(); @@ -464,7 +342,7 @@ public JsonResultResponse getDiseaseAnnotations } sortFields.forEach(sortField -> sortingMap.put(sortField, SortOrder.ASC)); - SearchResponse searchResponse = elasticSearchHelper.getSearchResponse(bool, pagination, sortingMap, false); + SearchResponse searchResponse = getSearchResponse(bool, pagination, sortingMap, false); ret.setTotal((int) searchResponse.getHits().getTotalHits().value); List list = new ArrayList<>(); diff --git a/agr_api/src/main/java/org/alliancegenome/api/service/ESService.java b/agr_api/src/main/java/org/alliancegenome/api/service/ESService.java new file mode 100644 index 000000000..a9086d92e --- /dev/null +++ b/agr_api/src/main/java/org/alliancegenome/api/service/ESService.java @@ -0,0 +1,186 @@ +package org.alliancegenome.api.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.quarkus.logging.Log; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import org.alliancegenome.api.entity.DiseaseRibbonSummary; +import org.alliancegenome.api.service.helper.GeneDiseaseSearchHelper; +import org.alliancegenome.es.index.site.dao.SearchDAO; +import org.alliancegenome.es.model.query.Pagination; +import org.alliancegenome.neo4j.entity.SpeciesType; +import org.alliancegenome.neo4j.entity.node.DOTerm; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.lucene.queryparser.classic.QueryParser; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.MatchQueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.aggregations.AggregationBuilder; +import org.elasticsearch.search.aggregations.AggregationBuilders; +import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; +import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; +import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; +import org.elasticsearch.search.sort.SortOrder; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.elasticsearch.index.query.QueryBuilders.*; + + +@RequestScoped +public class ESService { + + @Inject + ObjectMapper mapper; + + private static final SearchDAO searchDAO = new SearchDAO(); + private static final GeneDiseaseSearchHelper geneDiseaseSearchHelper = new GeneDiseaseSearchHelper(); + + + protected SearchResponse getSearchResponse(BoolQueryBuilder bool, Pagination pagination, LinkedHashMap focusTaxonId, boolean debug) { + List aggBuilders = new ArrayList<>(); + HighlightBuilder hlb = new HighlightBuilder(); + + return searchDAO.performQuery( + bool, aggBuilders, null, geneDiseaseSearchHelper.getResponseFields(), + pagination.getLimit(), pagination.getOffset(), hlb, focusTaxonId, debug); + } + + BoolQueryBuilder getBaseQuery(List entityIDs, String termID, boolean excludeNegated, String recordType, boolean excludeViaOrthologyRecords) { + BoolQueryBuilder bool = boolQuery(); + BoolQueryBuilder bool2 = boolQuery(); + bool.must(bool2); + + bool.filter(termQuery("category", recordType)); + + if (CollectionUtils.isNotEmpty(entityIDs)) { + for (String geneId : entityIDs) { + setEntityIdMatcher(geneId, bool2); + } + } + if (excludeNegated) { + bool.must(matchQuery("primaryAnnotations.negated", false)); + } + if (excludeViaOrthologyRecords) { + bool.must(matchQuery("viaOrthologyOrder", 0)); + } + if (termID != null) { + BoolQueryBuilder bool3 = boolQuery(); + bool.must(bool3); + if (termID.equals(DiseaseRibbonSummary.DOID_OTHER)) { + BoolQueryBuilder orClause = boolQuery(); + DOTerm.getAllOtherDiseaseTerms().forEach(parentID -> orClause.should(QueryBuilders.termQuery("parentSlimIDs.keyword", parentID))); + bool3.should(orClause); + + } else { + bool3.should(new MatchQueryBuilder("parentSlimIDs.keyword", termID)); + } + } + return bool; + } + + void addTableFilter(Pagination pagination, BoolQueryBuilder bool) { + HashMap filterOptionMap = pagination.getFilterOptionMap(); + if (MapUtils.isNotEmpty(filterOptionMap)) { + filterOptionMap.forEach((filterName, filterValue) -> generateFilter(bool, filterName, filterValue)); + } + } + + private void generateFilter(BoolQueryBuilder bool, String filterName, String filterValue) { + if (filterValue.contains("|")) { + //Log.info("Or Filter: " + filterName + " " + filterValue); + BoolQueryBuilder orClause = boolQuery(); + String[] elements = filterValue.split("\\|"); + Arrays.stream(elements).forEach(element -> orClause.should(QueryBuilders.termQuery(filterName, escapeValue(element)))); + bool.must(orClause); + } else { + //Log.info("Other Filter: " + filterName + " " + filterValue); + if (filterName.endsWith("keyword")) { + bool.must(QueryBuilders.termQuery(filterName, filterValue)); + } else { + if (filterName.contains("OR")) { + BoolQueryBuilder outerAndClause = boolQuery(); + String[] filterNames = filterName.split("OR"); + Arrays.stream(filterNames).forEach(indivFilterName -> { + BoolQueryBuilder orClause = getBooleanAndedQueryBuilder(indivFilterName.trim(), filterValue); + outerAndClause.should(orClause); + }); + bool.must(outerAndClause); + } else { + BoolQueryBuilder andClause = getBooleanAndedQueryBuilder(filterName, filterValue); + bool.must(andClause); + } + } + } + //Log.info(bool); + } + + /* + * split filter values by white spaces and create and ANDed boolean query + */ + private BoolQueryBuilder getBooleanAndedQueryBuilder(String filterName, String filterValue) { + BoolQueryBuilder andClause = boolQuery(); + String[] elements = escapeValue(filterValue).split(" "); + Arrays.stream(elements).forEach(element -> andClause.must(QueryBuilders.queryStringQuery("*" + element + "*").field(filterName))); + return andClause; + } + + private String escapeValue(String value) { + value = value.replaceAll("'", " "); + value = QueryParser.escape(value); + return value; + } + + protected Map> getAggregations(BoolQueryBuilder bool, Map aggregationFields, String focusTaxonId, boolean useSpeciesAggregation, boolean debug) { + List aggBuilders = new ArrayList<>(); + aggregationFields.forEach((field, colName) -> { + String fieldNameAgg = field + "_agg"; + TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms(fieldNameAgg); + aggregationBuilder.bucketCardinality(); + aggregationBuilder.field(field); + aggBuilders.add(aggregationBuilder); + }); + + SearchResponse searchResponseHistogram = searchDAO.performQuery( + bool, aggBuilders, null, geneDiseaseSearchHelper.getResponseFields(), + 0, 0, new HighlightBuilder(), useSpeciesAggregation ? getAnnotationSorts(focusTaxonId, debug) : null, debug); + + Map> distinctFieldValueMap = new HashMap<>(); + aggregationFields.forEach((field, colName) -> { + String fieldNameAgg = field + "_agg"; + List values = ((ParsedStringTerms) searchResponseHistogram.getAggregations().get(fieldNameAgg)).getBuckets().stream() + .map(MultiBucketsAggregation.Bucket::getKeyAsString).collect(Collectors.toList()); + distinctFieldValueMap.put(colName, values); + }); + return distinctFieldValueMap; + } + + protected LinkedHashMap getAnnotationSorts(String focusTaxonId, boolean debug) { + SpeciesType type = SpeciesType.getTypeByID(focusTaxonId); + LinkedHashMap sorts = new LinkedHashMap<>(); + if (type != null) { + sorts.put("speciesOrder." + type.getTaxonIDPart(), SortOrder.ASC); + } else { + if (debug) { + Log.info("Species could not be found for: " + focusTaxonId); + } else { + Log.debug("Species could not be found for: " + focusTaxonId); + } + } + sorts.put("object.name.sort", SortOrder.ASC); + if (debug) { + Log.info(sorts); + } + return sorts; + } + + protected void setEntityIdMatcher(String geneID, BoolQueryBuilder bool2) { + bool2.should(new MatchQueryBuilder("subject.curie.keyword", geneID)); + bool2.should(new MatchQueryBuilder("subject.primaryExternalId.keyword", geneID)); + bool2.should(new MatchQueryBuilder("subject.modInternalId.keyword", geneID)); + } +} diff --git a/agr_api/src/main/java/org/alliancegenome/api/service/GeneService.java b/agr_api/src/main/java/org/alliancegenome/api/service/GeneService.java index 8c8f46adc..a3fcb54d6 100644 --- a/agr_api/src/main/java/org/alliancegenome/api/service/GeneService.java +++ b/agr_api/src/main/java/org/alliancegenome/api/service/GeneService.java @@ -1,30 +1,20 @@ package org.alliancegenome.api.service; -import static org.alliancegenome.cache.repository.helper.JsonResultResponse.DISTINCT_FIELD_VALUES; -import static org.elasticsearch.index.query.QueryBuilders.boolQuery; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; import org.alliancegenome.api.entity.AlleleVariantSequence; import org.alliancegenome.api.entity.GeneGeneticInteractionDocument; import org.alliancegenome.api.entity.GeneMolecularInteractionDocument; +import org.alliancegenome.api.entity.GenePhenotypeAnnotationDocument; import org.alliancegenome.api.service.helper.ElasticSearchHelper; import org.alliancegenome.cache.repository.AlleleCacheRepository; -import org.alliancegenome.cache.repository.PhenotypeCacheRepository; +import org.alliancegenome.cache.repository.InteractionCacheRepository; import org.alliancegenome.cache.repository.helper.JsonResultResponse; -import org.alliancegenome.cache.repository.helper.PaginationResult; import org.alliancegenome.core.variant.service.AlleleVariantIndexService; import org.alliancegenome.es.index.site.dao.SearchDAO; import org.alliancegenome.es.model.query.Pagination; import org.alliancegenome.neo4j.entity.EntitySummary; -import org.alliancegenome.neo4j.entity.PhenotypeAnnotation; import org.alliancegenome.neo4j.entity.SpeciesType; import org.alliancegenome.neo4j.entity.node.Allele; import org.alliancegenome.neo4j.entity.node.BioEntityGeneExpressionJoin; @@ -45,26 +35,37 @@ import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.SortOrder; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; -import jakarta.enterprise.context.RequestScoped; -import jakarta.inject.Inject; +import static org.alliancegenome.cache.repository.helper.JsonResultResponse.DISTINCT_FIELD_VALUES; +import static org.elasticsearch.index.query.QueryBuilders.boolQuery; @RequestScoped public class GeneService { private static GeneRepository geneRepo = new GeneRepository(); private static PhenotypeRepository phenoRepo = new PhenotypeRepository(); + + @Inject + AlleleVariantIndexService alleleVariantIndexService; + + @Inject + AlleleCacheRepository alleleCacheRepository; + + @Inject + InteractionCacheRepository interCacheRepo; + + @Inject + PhenotypeESService phenotypeESService; + @Inject + ObjectMapper mapper; + + private static final ElasticSearchHelper elasticSearchHelper = new ElasticSearchHelper(); private static final SearchDAO searchDAO = new SearchDAO(); - - @Inject AlleleVariantIndexService alleleVariantIndexService; - - @Inject AlleleCacheRepository alleleCacheRepository; - @Inject PhenotypeCacheRepository phenoCacheRepo; - - @Inject ObjectMapper mapper; public Gene getById(String id) { Gene gene = geneRepo.getOneGene(id); @@ -74,7 +75,7 @@ public Gene getById(String id) { } return gene; } - + public List getExpressionAnnotationsByTaxon(String taxon, String termID, Pagination pagination) { return geneRepo.getExpressionAnnotationsByTaxon(taxon, termID, pagination); } @@ -93,12 +94,14 @@ public JsonResultResponse getAlleles(String geneId, Pagination paginatio public JsonResultResponse getAllelesAndVariantInfo(String geneId, Pagination pagination) { List allelesNVariants = alleleVariantIndexService.getAllelesNVariants(geneId, pagination); - if (allelesNVariants == null) { - return null; + if (CollectionUtils.isEmpty(allelesNVariants)) { + JsonResultResponse response = new JsonResultResponse<>(); + response.setResults(new ArrayList<>()); + return response; } return alleleCacheRepository.getAlleleAndVariantJsonResultResponse(pagination, allelesNVariants); } - + public JsonResultResponse getGeneticInteractions(String geneId, Pagination pagination) { BoolQueryBuilder query = boolQuery(); query.should(new MatchQueryBuilder("geneGeneticInteraction.geneAssociationSubject.curie.keyword", geneId)); @@ -110,12 +113,12 @@ public JsonResultResponse getGeneticInteractions // add table filter elasticSearchHelper.addTableFilter(pagination, query); - + LinkedHashMap sorts = new LinkedHashMap<>(); if (StringUtils.isNotBlank(pagination.getSortBy())) { sorts.put(pagination.getSortBy(), SortOrder.ASC); } - + List aggBuilders = new ArrayList<>(); HighlightBuilder hlb = new HighlightBuilder(); SearchResponse searchResponse = searchDAO.performQuery(query, aggBuilders, null, List.of("*"), pagination.getLimit(), pagination.getOffset(), hlb, sorts, false); @@ -135,7 +138,7 @@ public JsonResultResponse getGeneticInteractions return ret; } - + public JsonResultResponse getMolecularInteractions(String geneId, Pagination pagination) { BoolQueryBuilder query = boolQuery(); BoolQueryBuilder query2 = boolQuery(); @@ -150,12 +153,12 @@ public JsonResultResponse getMolecularInteract // add table filter elasticSearchHelper.addTableFilter(pagination, query); - + LinkedHashMap sorts = new LinkedHashMap<>(); if (StringUtils.isNotBlank(pagination.getSortBy())) { sorts.put(pagination.getSortBy(), SortOrder.ASC); } - + List aggBuilders = new ArrayList<>(); HighlightBuilder hlb = new HighlightBuilder(); SearchResponse searchResponse = searchDAO.performQuery(query, aggBuilders, null, List.of("*"), pagination.getLimit(), pagination.getOffset(), hlb, sorts, false); @@ -175,7 +178,7 @@ public JsonResultResponse getMolecularInteract return ret; } - + private Map getGeneticInteractionSupplementalData(BoolQueryBuilder unfilteredQuery) { Map aggregationFields = new HashMap<>(); aggregationFields.put("geneGeneticInteraction.interactorARole.name.keyword", "filter.role"); @@ -184,7 +187,7 @@ private Map getGeneticInteractionSupplementalData(BoolQueryBuild aggregationFields.put("geneGeneticInteraction.geneGeneAssociationObject.taxon.name.keyword", "filter.interactorSpecies"); return getInteractionSupplementalData(aggregationFields, unfilteredQuery); } - + private Map getMolecularInteractionSupplementalData(BoolQueryBuilder unfilteredQuery) { Map aggregationFields = new HashMap<>(); aggregationFields.put("geneMolecularInteraction.interactorBType.name.keyword", "filter.interactorMoleculeType"); @@ -193,7 +196,7 @@ private Map getMolecularInteractionSupplementalData(BoolQueryBui aggregationFields.put("geneMolecularInteraction.geneGeneAssociationObject.taxon.name.keyword", "filter.interactorSpecies"); return getInteractionSupplementalData(aggregationFields, unfilteredQuery); } - + private Map getInteractionSupplementalData(Map aggregationFields, BoolQueryBuilder unfilteredQuery) { Map> distinctFieldValueMap = getAggregations(unfilteredQuery, aggregationFields); Map supplementalData = new LinkedHashMap<>(); @@ -225,13 +228,10 @@ private Map> getAggregations(BoolQueryBuilder bool, Map getPhenotypeAnnotations(String geneID, Pagination pagination) { + public JsonResultResponse getPhenotypeAnnotations(String geneID, Pagination pagination) { LocalDateTime startDate = LocalDateTime.now(); - PaginationResult list = phenoCacheRepo.getPhenotypeAnnotationList(geneID, pagination); - JsonResultResponse response = new JsonResultResponse<>(); + JsonResultResponse response = phenotypeESService.getGenePhenotypeAnnotations(geneID, pagination, false); response.calculateRequestDuration(startDate); - response.setResults(list.getResult()); - response.setTotal(list.getTotalNumber()); return response; } @@ -248,15 +248,15 @@ public List getAllGenes(List species) { taxonIDs = SpeciesType.getAllTaxonIDList(); } else { taxonIDs = species.stream() - .map(SpeciesType::getTaxonId) - .collect(Collectors.toList()); + .map(SpeciesType::getTaxonId) + .collect(Collectors.toList()); } if (CollectionUtils.isEmpty(taxonIDs)) { return null; } List taxIDs = taxonIDs.stream() - .map(SpeciesType::getTaxonId) - .collect(Collectors.toList()); + .map(SpeciesType::getTaxonId) + .collect(Collectors.toList()); return geneRepo.getAllGenes(taxIDs); } diff --git a/agr_api/src/main/java/org/alliancegenome/api/service/PhenotypeESService.java b/agr_api/src/main/java/org/alliancegenome/api/service/PhenotypeESService.java new file mode 100644 index 000000000..dc0b4ab1c --- /dev/null +++ b/agr_api/src/main/java/org/alliancegenome/api/service/PhenotypeESService.java @@ -0,0 +1,101 @@ +package org.alliancegenome.api.service; + +import jakarta.enterprise.context.RequestScoped; +import org.alliancegenome.api.entity.AllelePhenotypeAnnotationDocument; +import org.alliancegenome.api.entity.GenePhenotypeAnnotationDocument; +import org.alliancegenome.cache.repository.helper.JsonResultResponse; +import org.alliancegenome.es.model.query.Pagination; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.search.sort.SortOrder; + +import java.util.*; + + +@RequestScoped +public class PhenotypeESService extends ESService { + + // termID may be used in the future when converting disease page to new ES stack. + public JsonResultResponse getGenePhenotypeAnnotations( + String geneId, + Pagination pagination, + boolean debug) { + + // unfiltered query + BoolQueryBuilder query = getBaseQuery(List.of(geneId), null, false, GenePhenotypeAnnotationDocument.GENE_PHENOTYPE_ANNOTATION, false); + + JsonResultResponse ret = new JsonResultResponse<>(); + + // add table filter + addTableFilter(pagination, query); + // Sorting sets for different names of the sorting selection box + Map> sortingSetMap = new HashMap<>(); + sortingSetMap.put("default", List.of("phenotypeStatement.sort")); + LinkedHashMap sortingMap = new LinkedHashMap<>(); + + List sortFields = sortingSetMap.get(pagination.getSortBy()); + if (sortFields == null) { + sortFields = sortingSetMap.get("default"); + } + sortFields.forEach(sortField -> sortingMap.put(sortField, SortOrder.ASC)); + + SearchResponse searchResponse = getSearchResponse(query, pagination, sortingMap, debug); + ret.setTotal((int) searchResponse.getHits().getTotalHits().value); + + List list = Arrays.stream(searchResponse.getHits().getHits()) + .map(searchHit -> { + try { + GenePhenotypeAnnotationDocument object = mapper.readValue(searchHit.getSourceAsString(), GenePhenotypeAnnotationDocument.class); + object.setUniqueId(searchHit.getId()); + return object; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + }).toList(); + ret.setResults(list); + return ret; + } + + public JsonResultResponse getAllelePhenotypeAnnotations( + String alleleId, + Pagination pagination, + boolean debug) { + + // unfiltered query + BoolQueryBuilder query = getBaseQuery(List.of(alleleId), null, false, AllelePhenotypeAnnotationDocument.ALLELE_PHENOTYPE_ANNOTATION, false); + + JsonResultResponse ret = new JsonResultResponse<>(); + + // add table filter + addTableFilter(pagination, query); + // Sorting sets for different names of the sorting selection box + Map> sortingSetMap = new HashMap<>(); + sortingSetMap.put("default", List.of("phenotypeStatement.sort")); + LinkedHashMap sortingMap = new LinkedHashMap<>(); + + List sortFields = sortingSetMap.get(pagination.getSortBy()); + if (sortFields == null) { + sortFields = sortingSetMap.get("default"); + } + sortFields.forEach(sortField -> sortingMap.put(sortField, SortOrder.ASC)); + + SearchResponse searchResponse = getSearchResponse(query, pagination, sortingMap, debug); + ret.setTotal((int) searchResponse.getHits().getTotalHits().value); + + List list = Arrays.stream(searchResponse.getHits().getHits()) + .map(searchHit -> { + try { + AllelePhenotypeAnnotationDocument object = mapper.readValue(searchHit.getSourceAsString(), AllelePhenotypeAnnotationDocument.class); + object.setUniqueId(searchHit.getId()); + return object; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + }).toList(); + ret.setResults(list); + return ret; + } + +} diff --git a/agr_api/src/test/java/org/alliancegenome/api/tests/integration/PhenotypeIT.java b/agr_api/src/test/java/org/alliancegenome/api/tests/integration/PhenotypeIT.java index d7ed07835..5ecdbbd25 100644 --- a/agr_api/src/test/java/org/alliancegenome/api/tests/integration/PhenotypeIT.java +++ b/agr_api/src/test/java/org/alliancegenome/api/tests/integration/PhenotypeIT.java @@ -14,15 +14,17 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.alliancegenome.api.entity.GenePhenotypeAnnotationDocument; import org.alliancegenome.api.service.GeneService; import org.alliancegenome.cache.repository.helper.JsonResultResponse; import org.alliancegenome.core.api.service.DiseaseService; import org.alliancegenome.core.config.ConfigHelper; import org.alliancegenome.core.translators.tdf.PhenotypeAnnotationToTdfTranslator; +import org.alliancegenome.curation_api.model.entities.PhenotypeAnnotation; +import org.alliancegenome.curation_api.model.entities.Reference; import org.alliancegenome.es.model.query.FieldFilter; import org.alliancegenome.es.model.query.Pagination; import org.alliancegenome.neo4j.entity.EntitySummary; -import org.alliancegenome.neo4j.entity.PhenotypeAnnotation; import org.alliancegenome.neo4j.entity.PrimaryAnnotatedEntity; import org.alliancegenome.neo4j.entity.node.GeneticEntity; import org.alliancegenome.neo4j.entity.node.Publication; @@ -81,7 +83,7 @@ public void checkPhenotypeByGeneWithoutPagination() { // mkks String geneID = "ZFIN:ZDB-GENE-040426-757"; - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 19, 19); @@ -99,7 +101,7 @@ public void checkPhenotypeByGeneWithPagination() { String geneID = "ZFIN:ZDB-GENE-040426-757"; Pagination pagination = new Pagination(1, 11, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 11, 19); // add containsFilterValue on phenotype @@ -151,12 +153,12 @@ public void checkPhenotypesWithReference() { Pagination pagination = new Pagination(1, 60, null, null); DiseaseService diseaseService = new DiseaseService(); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); - List pa = response.getResults().stream() - .filter(phenotypeAnnotation -> phenotypeAnnotation.getPhenotype().equals("cartilage development disrupted, abnormal")) + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + List pa = response.getResults().stream() + .filter(phenotypeAnnotation -> phenotypeAnnotation.getPhenotypeStatement().equals("cartilage development disrupted, abnormal")) .collect(Collectors.toList()); assertNotNull(pa); - String pmids = pa.get(0).getPublications().stream().map(Publication::getPubId).collect(Collectors.joining(",")); + String pmids = pa.get(0).getReferences().stream().map(Reference::getReferenceID).collect(Collectors.joining(",")); assertEquals("Pmid list", "PMID:12397114,PMID:18950725,PMID:9007254", pmids); } @@ -167,12 +169,12 @@ public void checkPhenotypesWithoutGenePopup() { String geneID = "FB:FBgn0030343"; Pagination pagination = new Pagination(1, 60, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); response.getResults() .stream() - .filter(phenotypeAnnotation -> phenotypeAnnotation.getPrimaryAnnotatedEntities() != null) - .forEach(phenotypeAnnotation -> phenotypeAnnotation.getPrimaryAnnotatedEntities().forEach(entity -> { - assertNotEquals("Direct Gene annotation found. Should be suppressed for: " + entity.getId(), entity.getType(), GeneticEntity.CrossReferenceType.GENE); + .filter(phenotypeAnnotation -> phenotypeAnnotation.getPrimaryAnnotations() != null) + .forEach(phenotypeAnnotation -> phenotypeAnnotation.getPrimaryAnnotations().forEach(entity -> { + assertNotEquals("Direct Gene annotation found. Should be suppressed for: " + entity.getId(), entity.getRelation().getName(), GeneticEntity.CrossReferenceType.GENE); })); } @@ -211,17 +213,19 @@ public void checkUrlForAllelesInPopup() { String geneID = "WB:WBGene00000834"; Pagination pagination = new Pagination(1, 10, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 1, 1); +/* response.getResults() .stream() - .filter(phenotypeAnnotation -> phenotypeAnnotation.getPrimaryAnnotatedEntities() != null) + .filter(phenotypeAnnotation -> phenotypeAnnotation.getPrimaryAnnotations() != null) .forEach(phenotypeAnnotation -> { - phenotypeAnnotation.getPrimaryAnnotatedEntities().forEach(entity -> { + phenotypeAnnotation.getPrimaryAnnotations().forEach(entity -> { assertNotNull("URL for AGM should not be null: " + entity.getId(), entity.getUrl()); }); }); +*/ } @Test @@ -270,12 +274,12 @@ public void checkPhenotypeReferenceNonDuplicated() { String geneID = "ZFIN:ZDB-GENE-041008-136"; Pagination pagination = new Pagination(1, 10, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 10, 10); response.getResults().forEach(phenotypeAnnotation -> { - int beforeSize = phenotypeAnnotation.getPublications().size(); - int afterSize = phenotypeAnnotation.getPublications().stream().distinct().collect(Collectors.toList()).size(); + int beforeSize = phenotypeAnnotation.getReferences().size(); + int afterSize = phenotypeAnnotation.getReferences().stream().distinct().toList().size(); assertEquals("No duplicated references", beforeSize, afterSize); }); } @@ -287,7 +291,7 @@ public void checkPhenotypeByGeneWithPaginationPax2a() { String geneID = "ZFIN:ZDB-GENE-990415-8"; Pagination pagination = new Pagination(1, 11, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); int resultSize = 11; int totalSize = 122; assertResponse(response, resultSize, totalSize); @@ -318,8 +322,9 @@ public void checkPhenotypeByGeneWithPaginationPax2a() { @Test public void checkPhenotypeDownload() { - JsonResultResponse response = geneService.getPhenotypeAnnotations("MGI:105043", new Pagination()); + JsonResultResponse response = geneService.getPhenotypeAnnotations("MGI:105043", new Pagination()); PhenotypeAnnotationToTdfTranslator translator = new PhenotypeAnnotationToTdfTranslator(); +/* String line = translator.getAllRows(response.getResults()); assertNotNull(line); String[] lines = line.split("\n"); @@ -333,6 +338,7 @@ public void checkPhenotypeDownload() { line = translator.getAllRows(response.getResults()); assertNotNull(line); assertThat(response.getTotal(), greaterThan(500)); +*/ } @Test @@ -341,7 +347,7 @@ public void checkPhenotypeByGeneWithPaginationPten() { String geneID = "MGI:109583"; Pagination pagination = new Pagination(1, 42, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 42, 515); @@ -358,13 +364,13 @@ public void checkPhenotypeByGeneFly() { String geneID = "FB:FBgn0267821"; Pagination pagination = new Pagination(1, 10, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 10, 50); - PhenotypeAnnotation annotation = response.getResults().get(0); - assertEquals(annotation.getPhenotype(), "corpus cardiacum primordium"); - final List primaryAnnotatedEntities = annotation.getPrimaryAnnotatedEntities(); + GenePhenotypeAnnotationDocument annotation = response.getResults().get(0); + assertEquals(annotation.getPhenotypeStatement(), "corpus cardiacum primordium"); + final List primaryAnnotatedEntities = annotation.getPrimaryAnnotations(); assertNotNull("Phenotype annotation has Allele as the inferred AGM but missing.", primaryAnnotatedEntities); - assertEquals("Phenotype annotation with Allele as an inferred AGM", primaryAnnotatedEntities.get(0).getType(), GeneticEntity.CrossReferenceType.ALLELE); + assertEquals("Phenotype annotation with Allele as an inferred AGM", primaryAnnotatedEntities.get(0).getRelation().getName(), GeneticEntity.CrossReferenceType.ALLELE); } @Test @@ -373,16 +379,16 @@ public void checkPhenotypeByGeneWorm() { String geneID = "WB:WBGene00002992"; Pagination pagination = new Pagination(1, 10, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 10, 17); final String ectopicExpressionTransgene = "ectopic expression transgene"; - Optional annotation = response.getResults().stream() - .filter(annot -> annot.getPhenotype().equals(ectopicExpressionTransgene)) + Optional annotation = response.getResults().stream() + .filter(annot -> annot.getPhenotypeStatement().equals(ectopicExpressionTransgene)) .findFirst(); assertTrue("Did not find a phenotype: " + ectopicExpressionTransgene, annotation.isPresent()); - final List primaryAnnotatedEntities = annotation.get().getPrimaryAnnotatedEntities(); + final List primaryAnnotatedEntities = annotation.get().getPrimaryAnnotations(); assertNotNull("Phenotype annotation has Allele as the inferred AGM but missing.", primaryAnnotatedEntities); - assertEquals("Phenotype annotation with Allele as an inferred AGM", primaryAnnotatedEntities.get(0).getType(), GeneticEntity.CrossReferenceType.ALLELE); + assertEquals("Phenotype annotation with Allele as an inferred AGM", primaryAnnotatedEntities.get(0).getRelation(), GeneticEntity.CrossReferenceType.ALLELE); } @Test @@ -390,9 +396,9 @@ public void checkPhenotypeByGeneWithPaginationCua_1() { String geneID = "WB:WBGene00000834"; Pagination pagination = new Pagination(1, 42, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 1, 1); - final List primaryAnnotatedEntities = response.getResults().get(0).getPrimaryAnnotatedEntities(); + final List primaryAnnotatedEntities = response.getResults().get(0).getPrimaryAnnotations(); assertNull("Allele phenotype annotation", primaryAnnotatedEntities); } @@ -401,7 +407,7 @@ public void checkPhenotypeOnWBGenes() { String geneID = "WB:WBGene00000898"; Pagination pagination = new Pagination(1, 10, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 1, 1); } @@ -410,12 +416,12 @@ public void checkPhenotypeOnZFINpax2a() { String geneID = "ZFIN:ZDB-GENE-990415-8"; Pagination pagination = new Pagination(1, 10, null, null); - JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); + JsonResultResponse response = geneService.getPhenotypeAnnotations(geneID, pagination); assertResponse(response, 1, 1); - assertThat(response.getResults().get(0).getPhenotype(), equalTo("anatomical system quality, abnormal")); - assertNotNull(response.getResults().get(0).getPrimaryAnnotatedEntities()); + assertThat(response.getResults().get(0).getPhenotypeStatement(), equalTo("anatomical system quality, abnormal")); + assertNotNull(response.getResults().get(0).getPrimaryAnnotations()); // more than 4 fish are found for primary entity annotations - assertThat(response.getResults().get(0).getPrimaryAnnotatedEntities().size(), greaterThanOrEqualTo(4)); + assertThat(response.getResults().get(0).getPrimaryAnnotations().size(), greaterThanOrEqualTo(4)); } @Test diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/config/IndexerConfig.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/config/IndexerConfig.java index bfbe8fb3e..f35f6f85b 100644 --- a/agr_indexer/src/main/java/org/alliancegenome/indexer/config/IndexerConfig.java +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/config/IndexerConfig.java @@ -11,28 +11,25 @@ import org.alliancegenome.indexer.indexers.curation.GeneGeneticInteractionCurationIndexer; import org.alliancegenome.indexer.indexers.curation.GeneMolecularInteractionCurationIndexer; import org.alliancegenome.indexer.indexers.curation.GeneToGeneParalogyIndexer; +import org.alliancegenome.indexer.indexers.curation.PhenotypeAnnotationCurationIndexer; public enum IndexerConfig { - - // These numbers target a 1MB document batch size - // Buffer size = 1MB / average size - // Bulk Action Size = Buffer Size - // Bulk Size = 1MB - // ConCurrent Reqests = Threads * 2 - // Document Stats as of 4/16/2021 ---- (doc count, min size, max size, average size) - GeneIndexer("gene", GeneIndexer.class, 4, 359, 359, 8, 1), // (280954, 616, 156692, 2785) - DatasetIndexer("dataset", DatasetIndexer.class, 4, 566, 566, 8, 1), // (8094, 358, 90542, 1765) - DiseaseIndexer("disease", DiseaseIndexer.class, 4, 680, 680, 8, 1), // (10751, 191, 330099, 1472) - AlleleIndexer("allele", AlleleIndexer.class, 4, 1517, 1517, 8, 1), // (407830, 334, 69968, 659) - GoIndexer("go", GoIndexer.class, 4, 914, 914, 8, 1), // (44087, 262, 460247, 1093) - ModelIndexer("model", ModelIndexer.class, 4, 1426, 1426, 8, 1), // (132447, 314, 18593, 701) - DiseaseAnnotationMlIndexer("diseaseAnnotation", DiseaseAnnotationCurationIndexer.class, 1, 1426, 1426, 2, 1), + + // Neo Indexers + GeneIndexer("gene", GeneIndexer.class, 4, 359, 359, 8, 1), + DatasetIndexer("dataset", DatasetIndexer.class, 4, 566, 566, 8, 1), + DiseaseIndexer("disease", DiseaseIndexer.class, 4, 680, 680, 8, 1), + AlleleIndexer("allele", AlleleIndexer.class, 4, 1517, 1517, 8, 1), + GoIndexer("go", GoIndexer.class, 4, 914, 914, 8, 1), + ModelIndexer("model", ModelIndexer.class, 4, 1426, 1426, 8, 1), + + // Curation Indexers + DiseaseAnnotationIndexer("diseaseAnnotation", DiseaseAnnotationCurationIndexer.class, 1, 1500, 1500, 2, 1), GeneExpressionAnnotationIndexer("geneExpressionAnnotation", GeneExpressionAnnotationIndexer.class, 4, 1500, 1500, 2, 1), GeneGeneticInteractionIndexers("geneGeneticInteraction", GeneGeneticInteractionCurationIndexer.class, 4, 1500, 1500, 2, 1), GeneMolecularInteractionIndexers("geneMolecularInteraction", GeneMolecularInteractionCurationIndexer.class, 4, 1500, 1500, 2, 1), - //PhenotypeAnnotationMlIndexer("phenotypeAnnotation", PhenotypeCurationIndexer.class, 1, 1426, 1426, 2, 1), - ParalogyIndexer("paralogy", GeneToGeneParalogyIndexer.class, 4, 5000, 5000, 8, 1), // (3918629, 735, 1514, 1065) - // still not implemented VariantIndexer("variant", VariantIndexer.class, 2, 3000, 400, 4, 4) + ParalogyIndexer("paralogy", GeneToGeneParalogyIndexer.class, 4, 5000, 5000, 8, 1), + PhenotypeAnnotationIndexer("phenotypeAnnotation", PhenotypeAnnotationCurationIndexer.class, 1, 1500, 1500, 2, 1), ; diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/DiseaseAnnotationCurationIndexer.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/DiseaseAnnotationCurationIndexer.java index a43dfc572..58d9dba6a 100644 --- a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/DiseaseAnnotationCurationIndexer.java +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/DiseaseAnnotationCurationIndexer.java @@ -256,7 +256,6 @@ private static int getPhylogeneticSortOrder(String taxonID) { return phylogeneticSortOrder; } - private String getPubmedPubModID(Reference singleReference) { if (singleReference == null || CollectionUtils.isEmpty(singleReference.getCrossReferences())) { return null; diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/PhenotypeAnnotationCurationIndexer.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/PhenotypeAnnotationCurationIndexer.java new file mode 100644 index 000000000..6438a9f0c --- /dev/null +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/PhenotypeAnnotationCurationIndexer.java @@ -0,0 +1,243 @@ +package org.alliancegenome.indexer.indexers.curation; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.alliancegenome.api.entity.AllelePhenotypeAnnotationDocument; +import org.alliancegenome.api.entity.GenePhenotypeAnnotationDocument; +import org.alliancegenome.api.entity.PhenotypeAnnotationDocument; +import org.alliancegenome.curation_api.model.entities.*; +import org.alliancegenome.es.util.ProcessDisplayHelper; +import org.alliancegenome.indexer.RestConfig; +import org.alliancegenome.indexer.config.IndexerConfig; +import org.alliancegenome.indexer.indexers.Indexer; +import org.alliancegenome.indexer.indexers.curation.service.AGMPhenotypeAnnotationService; +import org.alliancegenome.indexer.indexers.curation.service.AllelePhenotypeAnnotationService; +import org.alliancegenome.indexer.indexers.curation.service.GenePhenotypeAnnotationService; +import org.alliancegenome.indexer.indexers.curation.service.VocabularyService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.LinkedBlockingDeque; + +@Slf4j +public class PhenotypeAnnotationCurationIndexer extends Indexer { + + private GenePhenotypeAnnotationService geneService = new GenePhenotypeAnnotationService(); + private AllelePhenotypeAnnotationService alleleService = new AllelePhenotypeAnnotationService(); + private AGMPhenotypeAnnotationService agmService = new AGMPhenotypeAnnotationService(); + private VocabularyService vocabService = new VocabularyService(); + private Map>> geneMap = new HashMap<>(); + private Map>> alleleMap = new HashMap<>(); + private Map>> agmMap = new HashMap<>(); + + public PhenotypeAnnotationCurationIndexer(IndexerConfig indexerConfig) { + super(indexerConfig); + } + + @Override + protected ObjectMapper customizeObjectMapper(ObjectMapper objectMapper) { + return RestConfig.config.getJacksonObjectMapperFactory().createObjectMapper(); + } + + @Override + protected void startSingleThread(LinkedBlockingDeque queue) { + + } + + @Override + protected void index() { + + indexGenes(); + indexAlleles(); + indexAGMs(); + + List geneList = createGenePhenotypeAnnotationDocuments(); + log.info("Indexing " + String.format("%,d", geneList.size()) + " Gene PA documents"); + indexDocuments(geneList); + + List alleleList = createAllelePhenotypeAnnotationDocuments(); + log.info("Indexing " + alleleList.size() + " allele documents"); + indexDocuments(alleleList); + + log.info("Finished Indexing Phenotype Annotations"); + } + + private List createGenePhenotypeAnnotationDocuments() { + + List ret = new ArrayList<>(); + ProcessDisplayHelper ph = new ProcessDisplayHelper(10000); + ph.startProcess("Creating Gene Phenotype Annotations", geneMap.size()); + + final VocabularyTerm relationIsImplicatedIn = vocabService.getDiseaseRelationTerms().get("is_implicated_in"); + + for (Entry>> pairMap : geneMap.entrySet()) { + HashMap lookup = new HashMap<>(); + + for (PhenotypeAnnotation da : pairMap.getValue().getValue()) { + Gene gene = pairMap.getValue().getKey(); + VocabularyTerm relation = relationIsImplicatedIn; + + if (da instanceof GenePhenotypeAnnotation) { + relation = da.getRelation(); + } + + String key = getConsolidationKey(da); + GenePhenotypeAnnotationDocument gpad = lookup.computeIfAbsent(key, k -> new GenePhenotypeAnnotationDocument()); + if (gpad.getSubject() == null) { + gpad.setSubject(gene); + gpad.setRelation(relation); + gpad.setPhenotypeStatement(da.getPhenotypeAnnotationObject()); + } + populateBasePhenotypeAnnotationDocument(gene, da, gpad); + } + ph.progressProcess(); + ret.addAll(lookup.values()); + lookup.clear(); + } + ph.finishProcess(); + + return ret; + } + + private String getPubmedPubModID(Reference singleReference) { + List crossReferences = singleReference.getCrossReferences(); + if (CollectionUtils.isEmpty(crossReferences)) { + return null; + } + String[] prefixes = {"PMID", "MGI", "RGD", "ZFIN", "FB", "WB", "MGI"}; + for (String prefix : prefixes) { + Optional opt = crossReferences.stream().filter(reference -> reference.getReferencedCurie().startsWith(prefix + ":")).findFirst(); + if (opt.isPresent()) { + return opt.get().getReferencedCurie(); + } + } + return null; + } + + private void populateBasePhenotypeAnnotationDocument(BiologicalEntity biologicalEntity, PhenotypeAnnotation da, PhenotypeAnnotationDocument dad) { + dad.addReference(da.getSingleReference()); + dad.addPubMedPubModID(getPubmedPubModID(da.getSingleReference())); + dad.addPrimaryAnnotation(da); + } + + // Consolidated fields + // phenotype statement + private static String getConsolidationKey(PhenotypeAnnotation da) { + String key = da.getPhenotypeAnnotationObject(); + return key; + } + + private void indexGenes() { + List genePhenotypeAnnotations = geneService.getFiltered(); + addPhenotypeAnnotationsToLGlobalMap(genePhenotypeAnnotations); + } + + private void addPhenotypeAnnotationsToLGlobalMap(List genePhenotypeAnnotations) { + log.info("Filtered Gene PAs: " + String.format("%,d", genePhenotypeAnnotations.size())); + for (GenePhenotypeAnnotation da : genePhenotypeAnnotations) { + Gene gene = da.getPhenotypeAnnotationSubject(); + Pair> pair = geneMap.computeIfAbsent(gene.getIdentifier(), geneCurie -> Pair.of(gene, new ArrayList<>())); + pair.getRight().add(da); + } + } + + private void indexAlleles() { + + List allelePhenotypeAnnotations = alleleService.getFiltered(); + log.info("Filtered Alleles: " + allelePhenotypeAnnotations.size()); + for (AllelePhenotypeAnnotation da : allelePhenotypeAnnotations) { + Allele allele = da.getPhenotypeAnnotationSubject(); + Pair> allelePair = alleleMap.computeIfAbsent(allele.getIdentifier(), alleleCurie -> Pair.of(allele, new ArrayList<>())); + allelePair.getRight().add(da); + + Gene inferredGene = da.getInferredGene(); + extractGenePhenotypeAnnotations(da, inferredGene); + if (da.getAssertedGenes() != null) { + for (Gene gene : da.getAssertedGenes()) { + extractGenePhenotypeAnnotations(da, gene); + } + } + } + + } + + private void extractGenePhenotypeAnnotations(PhenotypeAnnotation da, Gene inferredGene) { + if (inferredGene != null && !inferredGene.getInternal()) { + Pair> pair = geneMap.computeIfAbsent(inferredGene.getIdentifier(), k -> Pair.of(inferredGene, new ArrayList<>())); + pair.getRight().add(da); + } + } + + private void indexAGMs() { + + List agmDiseaseAnnotations = agmService.getFiltered(); + log.info("Filtered AGM PAs: " + String.format("%,d", agmDiseaseAnnotations.size())); + + for (AGMPhenotypeAnnotation da : agmDiseaseAnnotations) { + AffectedGenomicModel genomicModel = da.getPhenotypeAnnotationSubject(); + Pair> allelePair = agmMap.computeIfAbsent(genomicModel.getIdentifier(), agmCurie -> Pair.of(genomicModel, new ArrayList<>())); + allelePair.getRight().add(da); + + Gene inferredGene = da.getInferredGene(); + extractGenePhenotypeAnnotations(da, inferredGene); + if (da.getAssertedGenes() != null) { + for (Gene gene : da.getAssertedGenes()) { + extractGenePhenotypeAnnotations(da, gene); + } + } + Allele inferredAllele = da.getInferredAllele(); + extractAlleleDiseaseAnnotations(da, inferredAllele); + if (da.getAssertedAllele() != null) { + extractAlleleDiseaseAnnotations(da, da.getAssertedAllele()); + } + } + } + + private void extractAlleleDiseaseAnnotations(PhenotypeAnnotation da, Allele inferredAllele) { + if (inferredAllele != null && !inferredAllele.getInternal()) { + Pair> pair = alleleMap.computeIfAbsent(inferredAllele.getIdentifier(), k -> Pair.of(inferredAllele, new ArrayList<>())); + pair.getRight().add(da); + } + } + + private List createAllelePhenotypeAnnotationDocuments() { + + List ret = new ArrayList<>(); + + ProcessDisplayHelper ph = new ProcessDisplayHelper(10000); + ph.startProcess("Creating Allele Disease Annotations", alleleMap.size()); + + VocabularyTerm relation = vocabService.getDiseaseRelationTerms().get("is_implicated_in"); + + for (Entry>> pairMap : alleleMap.entrySet()) { + HashMap lookup = new HashMap<>(); + + for (PhenotypeAnnotation pa : pairMap.getValue().getValue()) { + + // use this relation if inherited (inferred or asserted) from an AGM DA. + if (pa instanceof AllelePhenotypeAnnotation) { + relation = pa.getRelation(); + } + + String key = getConsolidationKey(pa); + AllelePhenotypeAnnotationDocument apad = lookup.computeIfAbsent(key, k -> new AllelePhenotypeAnnotationDocument()); + Allele allele = pairMap.getValue().getKey(); + if (apad.getSubject() == null) { + apad.setSubject(allele); + apad.setRelation(relation); + apad.setPhenotypeStatement(pa.getPhenotypeAnnotationObject()); + } + populateBasePhenotypeAnnotationDocument(allele, pa, apad); + } + ph.progressProcess(); + ret.addAll(lookup.values()); + lookup.clear(); + } + ph.finishProcess(); + return ret; + } + + +} diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/interfaces/AGMPhenotypeAnnotationInterface.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/interfaces/AGMPhenotypeAnnotationInterface.java new file mode 100644 index 000000000..3a1070c1b --- /dev/null +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/interfaces/AGMPhenotypeAnnotationInterface.java @@ -0,0 +1,22 @@ +package org.alliancegenome.indexer.indexers.curation.interfaces; + +import com.fasterxml.jackson.annotation.JsonView; +import jakarta.ws.rs.*; +import org.alliancegenome.curation_api.interfaces.base.BaseIdCrudInterface; +import org.alliancegenome.curation_api.model.entities.AGMPhenotypeAnnotation; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.view.View; + +import java.util.HashMap; + +@Path("/agm-phenotype-annotation") +@Produces({"application/json"}) +@Consumes({"application/json"}) +public interface AGMPhenotypeAnnotationInterface extends BaseIdCrudInterface { + + @POST + @Path("/findForPublic") + @JsonView({View.PhenotypeAnnotationView.class}) + SearchResponse findForPublic(@DefaultValue("0") @QueryParam("page") Integer page, @DefaultValue("10") @QueryParam("limit") Integer limit, HashMap params); + +} diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/interfaces/AllelePhenotypeAnnotationInterface.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/interfaces/AllelePhenotypeAnnotationInterface.java new file mode 100644 index 000000000..dd2de4cbe --- /dev/null +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/interfaces/AllelePhenotypeAnnotationInterface.java @@ -0,0 +1,22 @@ +package org.alliancegenome.indexer.indexers.curation.interfaces; + +import com.fasterxml.jackson.annotation.JsonView; +import jakarta.ws.rs.*; +import org.alliancegenome.curation_api.interfaces.base.BaseIdCrudInterface; +import org.alliancegenome.curation_api.model.entities.AllelePhenotypeAnnotation; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.view.View; + +import java.util.HashMap; + +@Path("/allele-phenotype-annotation") +@Produces({"application/json"}) +@Consumes({"application/json"}) +public interface AllelePhenotypeAnnotationInterface extends BaseIdCrudInterface { + + @POST + @Path("/findForPublic") + @JsonView({View.PhenotypeAnnotationView.class}) + SearchResponse findForPublic(@DefaultValue("0") @QueryParam("page") Integer page, @DefaultValue("10") @QueryParam("limit") Integer limit, HashMap params); + +} diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/interfaces/GenePhenotypeAnnotationInterface.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/interfaces/GenePhenotypeAnnotationInterface.java new file mode 100644 index 000000000..7cef74d04 --- /dev/null +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/interfaces/GenePhenotypeAnnotationInterface.java @@ -0,0 +1,22 @@ +package org.alliancegenome.indexer.indexers.curation.interfaces; + +import com.fasterxml.jackson.annotation.JsonView; +import jakarta.ws.rs.*; +import org.alliancegenome.curation_api.interfaces.base.BaseIdCrudInterface; +import org.alliancegenome.curation_api.model.entities.GenePhenotypeAnnotation; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.curation_api.view.View; + +import java.util.HashMap; + +@Path("/gene-phenotype-annotation") +@Produces({"application/json"}) +@Consumes({"application/json"}) +public interface GenePhenotypeAnnotationInterface extends BaseIdCrudInterface { + + @POST + @Path("/findForPublic") + @JsonView({View.PhenotypeAnnotationView.class}) + SearchResponse findForPublic(@DefaultValue("0") @QueryParam("page") Integer page, @DefaultValue("10") @QueryParam("limit") Integer limit, HashMap params); + +} diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AGMPhenotypeAnnotationService.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AGMPhenotypeAnnotationService.java new file mode 100644 index 000000000..5b22ff38b --- /dev/null +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AGMPhenotypeAnnotationService.java @@ -0,0 +1,63 @@ +package org.alliancegenome.indexer.indexers.curation.service; + +import lombok.extern.log4j.Log4j2; +import org.alliancegenome.core.config.ConfigHelper; +import org.alliancegenome.curation_api.model.entities.AGMPhenotypeAnnotation; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.es.util.ProcessDisplayHelper; +import org.alliancegenome.indexer.RestConfig; +import org.alliancegenome.indexer.indexers.curation.interfaces.AGMPhenotypeAnnotationInterface; +import si.mazi.rescu.RestProxyFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +@Log4j2 +public class AGMPhenotypeAnnotationService extends BaseDiseaseAnnotationService { + + private final AGMPhenotypeAnnotationInterface agmApi = RestProxyFactory.createProxy(AGMPhenotypeAnnotationInterface.class, ConfigHelper.getCurationApiUrl(), RestConfig.config); + private final String cacheFileName = "agm_phenotype_annotation.json.gz"; + + public List getFiltered() { + List ret = readFromCache(cacheFileName, List.class); + if (ret != null && ret.size() > 0) { + return ret; + } else { + ret = new ArrayList<>(); + } + ProcessDisplayHelper display = new ProcessDisplayHelper(2000); + + int batchSize = 1000; + int page = 0; + int pages; + + HashMap params = new HashMap<>(); + params.put("internal", false); + params.put("obsolete", false); + //params.put("phenotypeAnnotationSubject.primaryExternalId", "ZFIN:ZDB-FISH-210325-47"); + //params.put("phenotypeAnnotationSubject.modEntityId", "MGI:4829791"); + + do { + SearchResponse response = agmApi.findForPublic(page, batchSize, params); + for (AGMPhenotypeAnnotation da : response.getResults()) { + if (isValidNeoEntity(allNeoModelIDs, da.getPhenotypeAnnotationSubject().getIdentifier())) { + ret.add(da); + } + } + + if (page == 0) { + display.startProcess("Pulling AGM PA's from curation", response.getTotalResults()); + } + display.progressProcess(response.getReturnedRecords().longValue()); + pages = (int) (response.getTotalResults() / batchSize); + page++; + } while (page <= pages); + display.finishProcess(); + + writeToCache(cacheFileName, ret); + + return ret; + } + +} diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AlleleDiseaseAnnotationService.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AlleleDiseaseAnnotationService.java index 6f4fe5ee9..635c09d9f 100644 --- a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AlleleDiseaseAnnotationService.java +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AlleleDiseaseAnnotationService.java @@ -23,7 +23,6 @@ public class AlleleDiseaseAnnotationService extends BaseDiseaseAnnotationService public List getFiltered() { List ret = readFromCache(cacheFileName, List.class); - if (ret != null && ret.size() > 0) { return ret; } else { diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AllelePhenotypeAnnotationService.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AllelePhenotypeAnnotationService.java new file mode 100644 index 000000000..c7c442234 --- /dev/null +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/AllelePhenotypeAnnotationService.java @@ -0,0 +1,61 @@ +package org.alliancegenome.indexer.indexers.curation.service; + +import lombok.extern.log4j.Log4j2; +import org.alliancegenome.core.config.ConfigHelper; +import org.alliancegenome.curation_api.model.entities.AllelePhenotypeAnnotation; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.es.util.ProcessDisplayHelper; +import org.alliancegenome.indexer.RestConfig; +import org.alliancegenome.indexer.indexers.curation.interfaces.AllelePhenotypeAnnotationInterface; +import si.mazi.rescu.RestProxyFactory; + +import java.util.HashMap; +import java.util.List; + +@Log4j2 +public class AllelePhenotypeAnnotationService extends BaseDiseaseAnnotationService { + + private final AllelePhenotypeAnnotationInterface alleleApi = RestProxyFactory.createProxy(AllelePhenotypeAnnotationInterface.class, ConfigHelper.getCurationApiUrl(), RestConfig.config); + + private final String cacheFileName = "allele_phenotype_annotation.json.gz"; + + public List getFiltered() { + List ret = readFromCache(cacheFileName, List.class); + if (ret != null && ret.size() > 0) { + return ret; + } + ProcessDisplayHelper display = new ProcessDisplayHelper(2000); + + int batchSize = 1000; + int page = 0; + int pages; + + HashMap params = new HashMap<>(); + params.put("internal", false); + params.put("obsolete", false); + //params.put("phenotypeAnnotationSubject.primaryExternalId", "SGD:S000286812"); + //params.put("phenotypeAnnotationSubject.modEntityId", "MGI:4829791"); + + do { + SearchResponse response = alleleApi.findForPublic(page, batchSize, params); + for (AllelePhenotypeAnnotation da : response.getResults()) { + if (isValidNeoEntity(allNeoAlleleIDs, da.getPhenotypeAnnotationSubject().getIdentifier())) { + ret.add(da); + } + } + + if (page == 0) { + display.startProcess("Pulling Allele PA's from curation", response.getTotalResults()); + } + display.progressProcess(response.getReturnedRecords().longValue()); + pages = (int) (response.getTotalResults() / batchSize); + page++; + } while (page <= pages); + display.finishProcess(); + + writeToCache(cacheFileName, ret); + + return ret; + } + +} diff --git a/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/GenePhenotypeAnnotationService.java b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/GenePhenotypeAnnotationService.java new file mode 100644 index 000000000..1b50b3fa1 --- /dev/null +++ b/agr_indexer/src/main/java/org/alliancegenome/indexer/indexers/curation/service/GenePhenotypeAnnotationService.java @@ -0,0 +1,62 @@ +package org.alliancegenome.indexer.indexers.curation.service; + +import lombok.extern.log4j.Log4j2; +import org.alliancegenome.core.config.ConfigHelper; +import org.alliancegenome.curation_api.model.entities.GenePhenotypeAnnotation; +import org.alliancegenome.curation_api.response.SearchResponse; +import org.alliancegenome.es.util.ProcessDisplayHelper; +import org.alliancegenome.indexer.RestConfig; +import org.alliancegenome.indexer.indexers.curation.interfaces.GenePhenotypeAnnotationInterface; +import si.mazi.rescu.RestProxyFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +@Log4j2 +public class GenePhenotypeAnnotationService extends BaseDiseaseAnnotationService { + + private final GenePhenotypeAnnotationInterface geneApi = RestProxyFactory.createProxy(GenePhenotypeAnnotationInterface.class, ConfigHelper.getCurationApiUrl(), RestConfig.config); + private final String cacheFileName = "gene_phenotype_annotation.json.gz"; + + public List getFiltered() { + List ret = readFromCache(cacheFileName, List.class); + if (ret != null && ret.size() > 0) { + return ret; + } else { + ret = new ArrayList<>(); + } + + ProcessDisplayHelper display = new ProcessDisplayHelper(2000); + + int batchSize = 1000; + int page = 0; + int pages; + + HashMap params = new HashMap<>(); + params.put("internal", false); + params.put("obsolete", false); + //params.put("phenotypeAnnotationSubject.primaryExternalId", "SGD:S000001240"); + do { + SearchResponse response = geneApi.findForPublic(page, batchSize, params); + for (GenePhenotypeAnnotation pa : response.getResults()) { + if (isValidNeoEntity(allNeoGeneIDs, pa.getPhenotypeAnnotationSubject().getIdentifier())) { + ret.add(pa); + } + } + + if (page == 0) { + display.startProcess("Pulling Gene PA's from curation", response.getTotalResults()); + } + display.progressProcess(response.getReturnedRecords().longValue()); + pages = (int) (response.getTotalResults() / batchSize); + page++; + } while (page <= pages); + display.finishProcess(); + + writeToCache(cacheFileName, ret); + + return ret; + } + +} diff --git a/agr_java_core/src/main/java/org/alliancegenome/api/entity/AGMPhenotypeAnnotationDocument.java b/agr_java_core/src/main/java/org/alliancegenome/api/entity/AGMPhenotypeAnnotationDocument.java new file mode 100644 index 000000000..df676b88c --- /dev/null +++ b/agr_java_core/src/main/java/org/alliancegenome/api/entity/AGMPhenotypeAnnotationDocument.java @@ -0,0 +1,23 @@ +package org.alliancegenome.api.entity; + +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonView; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.alliancegenome.curation_api.model.entities.AffectedGenomicModel; +import org.alliancegenome.neo4j.view.View; + +@Data +@EqualsAndHashCode(callSuper = true) +@JsonPropertyOrder({"subject", "gene", "relation", "object", "primaryAnnotations"}) +@JsonView({View.DiseaseAnnotationAll.class}) +public class AGMPhenotypeAnnotationDocument extends PhenotypeAnnotationDocument { + + public static final String AGM_PHENOTYPE_ANNOTATION = "agm_phenotype_annotation"; + private AffectedGenomicModel subject; + + public AGMPhenotypeAnnotationDocument() { + setCategory(AGM_PHENOTYPE_ANNOTATION); + } + +} diff --git a/agr_java_core/src/main/java/org/alliancegenome/api/entity/AllelePhenotypeAnnotationDocument.java b/agr_java_core/src/main/java/org/alliancegenome/api/entity/AllelePhenotypeAnnotationDocument.java new file mode 100644 index 000000000..1dda976f6 --- /dev/null +++ b/agr_java_core/src/main/java/org/alliancegenome/api/entity/AllelePhenotypeAnnotationDocument.java @@ -0,0 +1,23 @@ +package org.alliancegenome.api.entity; + +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonView; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.alliancegenome.curation_api.model.entities.Allele; +import org.alliancegenome.neo4j.view.View; + +@Data +@EqualsAndHashCode(callSuper = true) +@JsonPropertyOrder({"subject", "gene", "relation", "object", "primaryAnnotations"}) +@JsonView({View.DiseaseAnnotationAll.class}) +public class AllelePhenotypeAnnotationDocument extends PhenotypeAnnotationDocument { + + public static final String ALLELE_PHENOTYPE_ANNOTATION = "allele_phenotype_annotation"; + private Allele subject; + + public AllelePhenotypeAnnotationDocument() { + setCategory(ALLELE_PHENOTYPE_ANNOTATION); + } + +} diff --git a/agr_java_core/src/main/java/org/alliancegenome/api/entity/GenePhenotypeAnnotationDocument.java b/agr_java_core/src/main/java/org/alliancegenome/api/entity/GenePhenotypeAnnotationDocument.java new file mode 100644 index 000000000..534b0ab3b --- /dev/null +++ b/agr_java_core/src/main/java/org/alliancegenome/api/entity/GenePhenotypeAnnotationDocument.java @@ -0,0 +1,23 @@ +package org.alliancegenome.api.entity; + +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonView; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.alliancegenome.curation_api.model.entities.Gene; +import org.alliancegenome.neo4j.view.View; + +@Data +@EqualsAndHashCode(callSuper = true) +@JsonPropertyOrder({"subject", "gene", "relation", "object", "primaryAnnotations"}) +@JsonView({View.PhenotypeAnnotationAll.class}) +public class GenePhenotypeAnnotationDocument extends PhenotypeAnnotationDocument { + + public static final String GENE_PHENOTYPE_ANNOTATION = "gene_phenotype_annotation"; + private Gene subject; + + public GenePhenotypeAnnotationDocument() { + setCategory(GENE_PHENOTYPE_ANNOTATION); + } + +} diff --git a/agr_java_core/src/main/java/org/alliancegenome/api/entity/PhenotypeAnnotationDocument.java b/agr_java_core/src/main/java/org/alliancegenome/api/entity/PhenotypeAnnotationDocument.java new file mode 100644 index 000000000..7147894c0 --- /dev/null +++ b/agr_java_core/src/main/java/org/alliancegenome/api/entity/PhenotypeAnnotationDocument.java @@ -0,0 +1,73 @@ +package org.alliancegenome.api.entity; + + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.alliancegenome.curation_api.model.entities.*; +import org.alliancegenome.curation_api.model.entities.ontology.ECOTerm; +import org.alliancegenome.es.index.ESDocument; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Data +@EqualsAndHashCode(callSuper = true) +public class PhenotypeAnnotationDocument extends ESDocument { + + private String category; + private String uniqueId; + private VocabularyTerm relation; + private String phenotypeStatement; + private List evidenceCodes; + private Reference singleReference; + private Set references; + + private String generatedRelationString; + private Set diseaseQualifiers; + private Set pubmedPubModIDs; + private List primaryAnnotations; + private List conditionModifierList; + private List geneticModifierList; + private VocabularyTerm geneticModifierRelation; + private String conditionModifierAggregated; + private String geneticModifierAggregated; + private List experimentalConditionList; + private String experimentalConditionsAggregated; + // 1 true + // 0 false + + public PhenotypeAnnotationDocument() { + primaryAnnotations = new ArrayList<>(); + } + + public void addReference(Reference singleReference) { + if (references == null) { + references = new HashSet<>(); + } + references.add(singleReference); + } + + public void addPubMedPubModID(String id) { + if (pubmedPubModIDs == null) { + pubmedPubModIDs = new HashSet<>(); + } + pubmedPubModIDs.add(id); + } + + public void addPrimaryAnnotation(PhenotypeAnnotation da) { + if (primaryAnnotations == null) { + primaryAnnotations = new ArrayList<>(); + } + primaryAnnotations.add(da); + } + + + @Override + @JsonIgnore + public String getType() { + return "phenotype_annotation"; + } +} diff --git a/agr_java_core/src/main/java/org/alliancegenome/cache/repository/PhenotypeCacheRepository.java b/agr_java_core/src/main/java/org/alliancegenome/cache/repository/PhenotypeCacheRepository.java index bbde83226..b6c64c216 100644 --- a/agr_java_core/src/main/java/org/alliancegenome/cache/repository/PhenotypeCacheRepository.java +++ b/agr_java_core/src/main/java/org/alliancegenome/cache/repository/PhenotypeCacheRepository.java @@ -27,23 +27,6 @@ public class PhenotypeCacheRepository { @Inject CacheService cacheService; - public PaginationResult getPhenotypeAnnotationList(String geneID, Pagination pagination) { - - List fullPhenotypeAnnotationList = getPhenotypeAnnotationList(geneID); - - // remove GENE annotations from PAE list - // filtering - PaginationResult result = new PaginationResult<>(); - FilterService filterService = new FilterService<>(new PhenotypeAnnotationFiltering()); - if (CollectionUtils.isNotEmpty(fullPhenotypeAnnotationList)) { - List filteredAnnotations = filterService.filterAnnotations(fullPhenotypeAnnotationList, pagination.getFieldFilterValueMap()); - filterService.getSortedAndPaginatedAnnotations(pagination, filteredAnnotations, new PhenotypeAnnotationSorting()); - result.setTotalNumber(filteredAnnotations.size()); - result.setResult(filterService.getPaginatedAnnotations(pagination, filteredAnnotations)); - } - return result; - } - private List getSortedAndPaginatedDiseaseAnnotations(Pagination pagination, List fullDiseaseAnnotationList) { // sorting SortingField sortingField = null; diff --git a/agr_java_core/src/main/java/org/alliancegenome/core/translators/tdf/PhenotypeAnnotationToTdfTranslator.java b/agr_java_core/src/main/java/org/alliancegenome/core/translators/tdf/PhenotypeAnnotationToTdfTranslator.java index 0c7a7c162..e378e3250 100644 --- a/agr_java_core/src/main/java/org/alliancegenome/core/translators/tdf/PhenotypeAnnotationToTdfTranslator.java +++ b/agr_java_core/src/main/java/org/alliancegenome/core/translators/tdf/PhenotypeAnnotationToTdfTranslator.java @@ -1,156 +1,58 @@ package org.alliancegenome.core.translators.tdf; +import org.alliancegenome.api.entity.PhenotypeAnnotationDocument; +import org.alliancegenome.curation_api.model.entities.AGMPhenotypeAnnotation; +import org.alliancegenome.curation_api.model.entities.PhenotypeAnnotation; +import org.apache.commons.collections.CollectionUtils; + import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -import org.alliancegenome.neo4j.entity.PhenotypeAnnotation; -import org.alliancegenome.neo4j.entity.PrimaryAnnotatedEntity; -import org.alliancegenome.neo4j.entity.node.Gene; -import org.alliancegenome.neo4j.entity.node.GeneticEntity; -import org.alliancegenome.neo4j.entity.node.PublicationJoin; -import org.apache.commons.collections.CollectionUtils; - public class PhenotypeAnnotationToTdfTranslator { - public String getAllRows(List annotations) { - denormalizeAnnotations(annotations); - + public String getAllRows(List annotations) { // convert collection of PhenotypeAnnotation records to PhenotypeDownloadRow records List list = getDownloadRowsFromAnnotations(annotations); List headers = List.of( - new DownloadHeader<>("Phenotype", PhenotypeDownloadRow::getPhenotype), - new DownloadHeader<>("Genetic Entity ID", PhenotypeDownloadRow::getGeneticEntityID), - new DownloadHeader<>("Genetic Entity Name", PhenotypeDownloadRow::getGeneticEntityName), - new DownloadHeader<>("Genetic Entity Type", PhenotypeDownloadRow::getGeneticEntityType), - new DownloadHeader<>("Source", PhenotypeDownloadRow::getSource), - new DownloadHeader<>("Reference", PhenotypeDownloadRow::getReference) - ); - - return DownloadHeader.getDownloadOutput(list, headers); - } - - - public String getAllRowsForAlleles(List annotations) { - denormalizeAnnotations(annotations); - - // convert collection of PhenotypeAnnotation records to PhenotypeDownloadRow records - List list = annotations.stream() - .map(annotation -> annotation.getPrimaryAnnotatedEntities().stream() - .map(entity -> entity.getPublicationEvidenceCodes().stream() - .map(join -> { - PhenotypeDownloadRow row = getBaseDownloadRow(annotation, join, null); - //set entities - row.setMainEntityID(annotation.getAllele().getPrimaryKey()); - row.setMainEntitySymbol(annotation.getAllele().getSymbolText()); - if (!entity.getType().equals(GeneticEntity.CrossReferenceType.GENE)) { - row.setGeneticEntityID(entity.getId()); - row.setGeneticEntityName(entity.getDisplayName()); - row.setGeneticEntityType(entity.getType()); - } - - return row; - }) - .collect(Collectors.toList())) - .flatMap(Collection::stream) - .collect(Collectors.toList())) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - List headers = List.of( - new DownloadHeader<>("Phenotype", PhenotypeDownloadRow::getPhenotype), - new DownloadHeader<>("Genetic Entity ID", PhenotypeDownloadRow::getGeneticEntityID), - new DownloadHeader<>("Genetic Entity Name", PhenotypeDownloadRow::getGeneticEntityName), - new DownloadHeader<>("Genetic Entity Type", PhenotypeDownloadRow::getGeneticEntityType), - new DownloadHeader<>("Reference", PhenotypeDownloadRow::getReference), - new DownloadHeader<>("Source", PhenotypeDownloadRow::getSource) + new DownloadHeader<>("Phenotype", PhenotypeDownloadRow::getPhenotype), + new DownloadHeader<>("Genetic Entity ID", PhenotypeDownloadRow::getGeneticEntityID), + new DownloadHeader<>("Genetic Entity Name", PhenotypeDownloadRow::getGeneticEntityName), + new DownloadHeader<>("Genetic Entity Type", PhenotypeDownloadRow::getGeneticEntityType), + new DownloadHeader<>("Source", PhenotypeDownloadRow::getSource), + new DownloadHeader<>("Reference", PhenotypeDownloadRow::getReference) ); - return DownloadHeader.getDownloadOutput(list, headers); } - - private void denormalizeAnnotations(List phenotypeAnnotation) { - // add genetic entity info for annotations with pure genes - - - - phenotypeAnnotation.stream() - .filter(annotation -> CollectionUtils.isEmpty(annotation.getPrimaryAnnotatedEntities())) - .forEach(annotation -> { - PrimaryAnnotatedEntity entity = createNewPrimaryAnnotatedEntity(annotation, null); - annotation.addPrimaryAnnotatedEntity(entity); - List joins = annotation.getPublications().stream() - .map(publication -> { - PublicationJoin join = new PublicationJoin(); - join.setPublication(publication); - return join; - }) - .collect(Collectors.toList()); - entity.addPublicationEvidenceCode(joins); - }); - - - } - - private PrimaryAnnotatedEntity createNewPrimaryAnnotatedEntity(PhenotypeAnnotation annotation, PublicationJoin join) { - PrimaryAnnotatedEntity entity = new PrimaryAnnotatedEntity(); - if (annotation.getGene() != null) { - entity.setId(annotation.getGene().getPrimaryKey()); - entity.setName(annotation.getGene().getSymbol()); - entity.setType(GeneticEntity.CrossReferenceType.GENE.getDisplayName()); - } else { - entity.setId(annotation.getAllele().getPrimaryKey()); - entity.setName(annotation.getAllele().getSymbolText()); - entity.setType(GeneticEntity.CrossReferenceType.ALLELE.getDisplayName()); - } - - return entity; - } - - - public List getDownloadRowsFromAnnotations(List phenotypeAnnotations) { - denormalizeAnnotations(phenotypeAnnotations); + public List getDownloadRowsFromAnnotations(List phenotypeAnnotations) { return phenotypeAnnotations.stream() - .filter(annotation -> annotation.getPrimaryAnnotatedEntities() != null) - .filter(annotation -> !CollectionUtils.isEmpty(annotation.getPrimaryAnnotatedEntities())) - .map(annotation -> annotation.getPrimaryAnnotatedEntities().stream() - .map(entity -> entity.getPublicationEvidenceCodes().stream() - .map(join -> { - - return List.of(getPhenotypeDownloadRow(annotation, entity, join, null)); - }) - .flatMap(Collection::stream) - .collect(Collectors.toList())) - .flatMap(Collection::stream) - .collect(Collectors.toList())) - .flatMap(Collection::stream) - .collect(Collectors.toList()); + .filter(annotation -> CollectionUtils.isNotEmpty(annotation.getPrimaryAnnotations())) + .map(annotation -> annotation.getPrimaryAnnotations().stream() + .map(this::getPhenotypeDownloadRow).toList()).flatMap(Collection::stream).collect(Collectors.toList()); } - private PhenotypeDownloadRow getPhenotypeDownloadRow(PhenotypeAnnotation annotation, PrimaryAnnotatedEntity entity, PublicationJoin join, Gene homologousGene) { - PhenotypeDownloadRow row = getBaseDownloadRow(annotation, join, homologousGene); - - row.setPhenotype(annotation.getPhenotype()); - row.setReference(join.getPublication().getPubId()); - if (entity != null) { - row.setGeneticEntityID(entity.getId()); - row.setGeneticEntityName(entity.getDisplayName()); - row.setGeneticEntityType(entity.getType()); + private PhenotypeDownloadRow getPhenotypeDownloadRow(PhenotypeAnnotation annotation) { + PhenotypeDownloadRow row = getBaseDownloadRow(annotation); + row.setPhenotype(annotation.getPhenotypeAnnotationObject()); + if (annotation instanceof AGMPhenotypeAnnotation annot) { + row.setGeneticEntityID(annot.getPhenotypeAnnotationSubject().getPrimaryExternalId()); + row.setGeneticEntityName(annot.getPhenotypeAnnotationSubject().getName()); + row.setGeneticEntityType(annot.getPhenotypeAnnotationSubject().getSubtype().getName()); } return row; } - private PhenotypeDownloadRow getBaseDownloadRow(PhenotypeAnnotation annotation, PublicationJoin join, Gene homologousGene) { + private PhenotypeDownloadRow getBaseDownloadRow(PhenotypeAnnotation annotation) { PhenotypeDownloadRow row = new PhenotypeDownloadRow(); - row.setPhenotype(annotation.getPhenotype()); + row.setPhenotype(annotation.getPhenotypeAnnotationObject()); - row.setReference(join.getPublication().getPubId()); - if (annotation.getSource() != null) { - row.setSource(annotation.getSource().getName()); + row.setReference(annotation.getSingleReference().getReferenceID()); + if (annotation.getDataProviderString() != null) { + row.setSource(annotation.getDataProviderString()); } else { row.setSource(""); } diff --git a/agr_java_core/src/main/java/org/alliancegenome/es/index/site/schema/Mapping.java b/agr_java_core/src/main/java/org/alliancegenome/es/index/site/schema/Mapping.java index 3c723ff30..553e8b9ca 100644 --- a/agr_java_core/src/main/java/org/alliancegenome/es/index/site/schema/Mapping.java +++ b/agr_java_core/src/main/java/org/alliancegenome/es/index/site/schema/Mapping.java @@ -92,6 +92,8 @@ protected void buildSharedSearchableDocumentMappings() throws IOException { new FieldBuilder(builder, "subject.geneSymbol.displayText", "text").keyword().sort().build(); new FieldBuilder(builder, "subject.name", "text").keyword().sort().build(); new FieldBuilder(builder, "subject.primaryExternalId", "text").keyword().sort().build(); + new FieldBuilder(builder, "subject.modEntityId", "text").keyword().sort().build(); + new FieldBuilder(builder, "phenotypeStatement", "text").keyword().sort().build(); new FieldBuilder(builder, "phenotypeStatements", "text") .keyword() .build(); diff --git a/agr_java_core/src/main/java/org/alliancegenome/neo4j/view/View.java b/agr_java_core/src/main/java/org/alliancegenome/neo4j/view/View.java index 106761406..5242b15c4 100644 --- a/agr_java_core/src/main/java/org/alliancegenome/neo4j/view/View.java +++ b/agr_java_core/src/main/java/org/alliancegenome/neo4j/view/View.java @@ -14,6 +14,12 @@ public static class DetailView { public static class SimpleView { } + public static class PhenotypeAnnotation extends API { + } + + public static class PhenotypeAnnotationAll extends PhenotypeAnnotation { + } + public static class API extends Default { } @@ -91,5 +97,5 @@ public static class OntologyFileMetadata extends API { public static class AlleleVariantSequenceConverterForES { } // This needs to NOT extend Default as this controls specifically what gets - // serialized and what doesn't. + // serialized and what doesn't. }