From d4f1e7c20c1ecfb6a67ff97c75c943b9abc1644c Mon Sep 17 00:00:00 2001 From: nkumar2 Date: Tue, 10 Sep 2024 11:58:26 +0100 Subject: [PATCH] review comments --- .../ac/ebi/eva/server/ws/RegionWSServer.java | 3 +- .../server/ws/ga4gh/GA4GHBeaconWSServer.java | 11 + .../server/ws/ga4gh/GA4GHVariantWSServer.java | 16 +- .../contigalias/ContigAliasServiceTest.java | 189 ++++++++++++++++++ 4 files changed, 214 insertions(+), 5 deletions(-) create mode 100644 eva-server/src/test/java/uk/ac/ebi/eva/server/contigalias/ContigAliasServiceTest.java diff --git a/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/RegionWSServer.java b/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/RegionWSServer.java index 70f4f356b..a9347ed4b 100644 --- a/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/RegionWSServer.java +++ b/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/RegionWSServer.java @@ -192,8 +192,7 @@ public QueryResponse getChromosomes(@RequestParam(name = "species") String speci MultiMongoDbFactory.setDatabaseNameForCurrentThread(DBAdaptorConnector.getDBName(species)); List chromosomeList = new ArrayList<>(service.findDistinctChromosomes()); - if (contigNamingConvention != null && !contigNamingConvention.equals(ContigNamingConvention.NO_REPLACEMENT) - && !contigNamingConvention.equals(ContigNamingConvention.INSDC)) { + if (contigAliasService.skipContigTranslation(contigNamingConvention)) { chromosomeList = chromosomeList.stream().map(chromosome -> { String translatedChromosome = contigAliasService.translateContigFromInsdc(chromosome, contigNamingConvention); if (translatedChromosome.equals("")) { diff --git a/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/ga4gh/GA4GHBeaconWSServer.java b/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/ga4gh/GA4GHBeaconWSServer.java index f3e074988..f6e4099e0 100644 --- a/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/ga4gh/GA4GHBeaconWSServer.java +++ b/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/ga4gh/GA4GHBeaconWSServer.java @@ -28,12 +28,14 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import uk.ac.ebi.eva.commons.core.models.VariantType; +import uk.ac.ebi.eva.commons.core.models.contigalias.ContigNamingConvention; import uk.ac.ebi.eva.commons.core.models.ws.VariantWithSamplesAndAnnotation; import uk.ac.ebi.eva.commons.mongodb.services.AnnotationMetadataNotFoundException; import uk.ac.ebi.eva.commons.mongodb.services.VariantWithSamplesAndAnnotationsService; import uk.ac.ebi.eva.lib.eva_utils.DBAdaptorConnector; import uk.ac.ebi.eva.lib.eva_utils.MultiMongoDbFactory; import uk.ac.ebi.eva.server.ws.EvaWSServer; +import uk.ac.ebi.eva.server.ws.contigalias.ContigAliasService; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -47,6 +49,9 @@ public class GA4GHBeaconWSServer extends EvaWSServer { @Autowired private VariantWithSamplesAndAnnotationsService service; + @Autowired + private ContigAliasService contigAliasService; + protected static Logger logger = LoggerFactory.getLogger(GA4GHBeaconWSServer.class); public GA4GHBeaconWSServer() { } @@ -56,6 +61,8 @@ public GA4GHBeaconResponse beacon(@RequestParam("referenceName") String chromoso @RequestParam("start") long start, @RequestParam("allele") String allele, @RequestParam("datasetIds") List studies, + @RequestParam(name = "contigNamingConvention", required = false) + ContigNamingConvention contigNamingConvention, HttpServletResponse response) throws IOException, AnnotationMetadataNotFoundException { initializeQuery(); @@ -76,6 +83,10 @@ public GA4GHBeaconResponse beacon(@RequestParam("referenceName") String chromoso variantEntities = service.findByChromosomeAndStartAndAltAndStudyIn(chromosome, start, allele, studies, null); } + String translatedContig = contigAliasService.translateContigFromInsdc(chromosome, contigNamingConvention); + if (translatedContig != null && !translatedContig.isEmpty()) { + chromosome = translatedContig; + } return new GA4GHBeaconResponse(chromosome, start, allele, String.join(",", studies), variantEntities.size() > 0); } diff --git a/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/ga4gh/GA4GHVariantWSServer.java b/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/ga4gh/GA4GHVariantWSServer.java index c22a1723c..51002d870 100644 --- a/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/ga4gh/GA4GHVariantWSServer.java +++ b/eva-server/src/main/java/uk/ac/ebi/eva/server/ws/ga4gh/GA4GHVariantWSServer.java @@ -30,6 +30,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import uk.ac.ebi.eva.commons.core.models.Region; +import uk.ac.ebi.eva.commons.core.models.contigalias.ContigNamingConvention; import uk.ac.ebi.eva.commons.core.models.ws.VariantWithSamplesAndAnnotation; import uk.ac.ebi.eva.commons.mongodb.filter.FilterBuilder; import uk.ac.ebi.eva.commons.mongodb.filter.VariantRepositoryFilter; @@ -43,6 +44,7 @@ import uk.ac.ebi.eva.lib.eva_utils.MultiMongoDbFactory; import uk.ac.ebi.eva.server.Utils; import uk.ac.ebi.eva.server.ws.EvaWSServer; +import uk.ac.ebi.eva.server.ws.contigalias.ContigAliasService; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -59,6 +61,9 @@ public class GA4GHVariantWSServer extends EvaWSServer { @Autowired private VariantWithSamplesAndAnnotationsService service; + @Autowired + private ContigAliasService contigAliasService; + protected static Logger logger = LoggerFactory.getLogger(GA4GHVariantWSServer.class); public GA4GHVariantWSServer() { @@ -76,6 +81,8 @@ public GASearchVariantsResponse getVariantsByRegion(@RequestParam("referenceName // @RequestParam("variantName") String id, @RequestParam(name = "variantSetIds", required = false) List files, // @RequestParam(name = "callSetIds", required = false) String samples, + @RequestParam(name = "contigNamingConvention", required = false) + ContigNamingConvention contigNamingConvention, @RequestParam(name = "pageToken", required = false) String pageToken, @RequestParam(name = "pageSize", defaultValue = "10") int limit) throws UnknownHostException, IOException, AnnotationMetadataNotFoundException { @@ -97,7 +104,8 @@ public GASearchVariantsResponse getVariantsByRegion(@RequestParam("referenceName List variantEntities = service.findByRegionsAndComplexFilters(regions, filters, null, null, pageRequest); - List variants = Collections.unmodifiableList(variantEntities); + List variants = Collections.unmodifiableList( + contigAliasService.getVariantsWithTranslatedContig(variantEntities, contigNamingConvention)); Long numTotalResults = service.countByRegionsAndComplexFilters(regions, filters); @@ -111,11 +119,13 @@ public GASearchVariantsResponse getVariantsByRegion(@RequestParam("referenceName } @RequestMapping(value = "/search", method = RequestMethod.POST, consumes = "application/json") - public GASearchVariantsResponse getVariantsByRegion(GASearchVariantRequest request) + public GASearchVariantsResponse getVariantsByRegion(GASearchVariantRequest request, + @RequestParam(name = "contigNamingConvention", required = false) + ContigNamingConvention contigNamingConvention) throws UnknownHostException, IOException, AnnotationMetadataNotFoundException { request.validate(); return getVariantsByRegion(request.getReferenceName(), request.getStart(), request.getEnd(), - request.getVariantSetIds(), request.getPageToken(), request.getPageSize()); + request.getVariantSetIds(), contigNamingConvention, request.getPageToken(), request.getPageSize()); } @ExceptionHandler(IllegalArgumentException.class) diff --git a/eva-server/src/test/java/uk/ac/ebi/eva/server/contigalias/ContigAliasServiceTest.java b/eva-server/src/test/java/uk/ac/ebi/eva/server/contigalias/ContigAliasServiceTest.java new file mode 100644 index 000000000..4adf538b6 --- /dev/null +++ b/eva-server/src/test/java/uk/ac/ebi/eva/server/contigalias/ContigAliasServiceTest.java @@ -0,0 +1,189 @@ +package uk.ac.ebi.eva.server.contigalias; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.web.client.RestTemplate; +import uk.ac.ebi.eva.commons.core.models.Annotation; +import uk.ac.ebi.eva.commons.core.models.FeatureCoordinates; +import uk.ac.ebi.eva.commons.core.models.contigalias.ContigAliasChromosome; +import uk.ac.ebi.eva.commons.core.models.contigalias.ContigAliasEmbedded; +import uk.ac.ebi.eva.commons.core.models.contigalias.ContigAliasResponse; +import uk.ac.ebi.eva.commons.core.models.contigalias.ContigNamingConvention; +import uk.ac.ebi.eva.commons.core.models.ws.VariantWithSamplesAndAnnotation; +import uk.ac.ebi.eva.server.ws.contigalias.ContigAliasService; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.when; + +public class ContigAliasServiceTest { + + @Mock + private RestTemplate restTemplate; + + @InjectMocks + private ContigAliasService contigAliasService; + + private final String contigAliasUrl = "http://example.com"; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + contigAliasService = new ContigAliasService(restTemplate, contigAliasUrl); + } + + @Test + public void testSkipContigTranslation() { + assertTrue(contigAliasService.skipContigTranslation(null)); + assertTrue(contigAliasService.skipContigTranslation(ContigNamingConvention.INSDC)); + assertTrue(contigAliasService.skipContigTranslation(ContigNamingConvention.NO_REPLACEMENT)); + assertFalse(contigAliasService.skipContigTranslation(ContigNamingConvention.UCSC)); + assertFalse(contigAliasService.skipContigTranslation(ContigNamingConvention.ENA_SEQUENCE_NAME)); + assertFalse(contigAliasService.skipContigTranslation(ContigNamingConvention.REFSEQ)); + } + + + @Test + public void testGetVariantsWithTranslatedContig() { + List variantsList = Arrays.asList(new VariantWithSamplesAndAnnotation("1", 1000, 1005, + "A", "T", "rs1")); + + // skip translation + List result = contigAliasService + .getVariantsWithTranslatedContig(variantsList, ContigNamingConvention.INSDC); + assertEquals("1", result.get(0).getChromosome()); + + // no translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))) + .thenReturn(new ContigAliasResponse()); + result = contigAliasService + .getVariantsWithTranslatedContig(variantsList, ContigNamingConvention.ENA_SEQUENCE_NAME); + assertEquals("1", result.get(0).getChromosome()); + + // with translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))) + .thenReturn(getContigAliasResponse(ContigNamingConvention.ENA_SEQUENCE_NAME, "chr1")); + result = contigAliasService + .getVariantsWithTranslatedContig(variantsList, ContigNamingConvention.ENA_SEQUENCE_NAME); + assertEquals("chr1", result.get(0).getChromosome()); + } + + @Test + public void testGetFeatureCoordinatesWithTranslatedContig() { + List featureCoordinatesList = Arrays.asList(new FeatureCoordinates("id", "fbx02", "feature", "1", 0, 1)); + + // skip translation + List result = contigAliasService + .getFeatureCoordinatesWithTranslatedContig(featureCoordinatesList, ContigNamingConvention.INSDC); + assertEquals("1", result.get(0).getChromosome()); + + // no translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))).thenReturn(new ContigAliasResponse()); + result = contigAliasService.getFeatureCoordinatesWithTranslatedContig(featureCoordinatesList, ContigNamingConvention.ENA_SEQUENCE_NAME); + assertEquals("1", result.get(0).getChromosome()); + + // with translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))) + .thenReturn(getContigAliasResponse(ContigNamingConvention.ENA_SEQUENCE_NAME, "chr1")); + result = contigAliasService.getFeatureCoordinatesWithTranslatedContig(featureCoordinatesList, ContigNamingConvention.ENA_SEQUENCE_NAME); + assertEquals("chr1", result.get(0).getChromosome()); + } + + @Test + public void testGetAnnotationWithTranslatedContig() { + Annotation annotation = new Annotation("1", 0, 0, null, null, null, null); + + // skip translation + Annotation result = contigAliasService + .getAnnotationWithTranslatedContig(annotation, ContigNamingConvention.INSDC); + assertEquals("1", result.getChromosome()); + + // no translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))).thenReturn(new ContigAliasResponse()); + result = contigAliasService.getAnnotationWithTranslatedContig(annotation, ContigNamingConvention.ENA_SEQUENCE_NAME); + assertEquals("1", result.getChromosome()); + + // with translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))) + .thenReturn(getContigAliasResponse(ContigNamingConvention.ENA_SEQUENCE_NAME, "chr1")); + result = contigAliasService.getAnnotationWithTranslatedContig(annotation, ContigNamingConvention.ENA_SEQUENCE_NAME); + assertEquals("chr1", result.getChromosome()); + } + + @Test + public void testTranslateContigFromInsdc() { + // no translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))).thenReturn(new ContigAliasResponse()); + String translatedContig = contigAliasService.translateContigFromInsdc("1", ContigNamingConvention.ENA_SEQUENCE_NAME); + assertEquals("", translatedContig); + + // with translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))) + .thenReturn(getContigAliasResponse(ContigNamingConvention.ENA_SEQUENCE_NAME, "chr1")); + translatedContig = contigAliasService.translateContigFromInsdc("1", ContigNamingConvention.ENA_SEQUENCE_NAME); + assertEquals("chr1", translatedContig); + + } + + @Test + public void testTranslateContigToInsdc() { + // no translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))).thenReturn(new ContigAliasResponse()); + String translatedContig = contigAliasService.translateContigToInsdc("1", "asm1", null); + assertEquals("1", translatedContig); + + // with refseq translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))) + .thenReturn(getContigAliasResponse(ContigNamingConvention.INSDC, "chr1")); + translatedContig = contigAliasService.translateContigToInsdc("1", "asm1", ContigNamingConvention.REFSEQ); + assertEquals("chr1", translatedContig); + + // with ena_seq_name translation + when(restTemplate.getForObject(anyString(), eq(ContigAliasResponse.class))) + .thenReturn(getContigAliasResponse(ContigNamingConvention.INSDC, "chr1")); + translatedContig = contigAliasService.translateContigToInsdc("1", "asm1", ContigNamingConvention.ENA_SEQUENCE_NAME); + assertEquals("chr1", translatedContig); + + } + + + private ContigAliasResponse getContigAliasResponse(ContigNamingConvention contigNamingConvention, String chromosome) { + ContigAliasChromosome contigAliasChromosome = new ContigAliasChromosome(); + switch (contigNamingConvention) { + case GENBANK_SEQUENCE_NAME: + contigAliasChromosome.setGenbankSequenceName(chromosome); + break; + case REFSEQ: + contigAliasChromosome.setRefseq(chromosome); + break; + case UCSC: + contigAliasChromosome.setUcscName(chromosome); + break; + case ENA_SEQUENCE_NAME: + contigAliasChromosome.setEnaSequenceName(chromosome); + break; + case INSDC: + contigAliasChromosome.setInsdcAccession(chromosome); + break; + } + + ContigAliasEmbedded contigAliasEmbedded = new ContigAliasEmbedded(); + contigAliasEmbedded.setContigAliasChromosomes(Arrays.asList(contigAliasChromosome)); + + ContigAliasResponse contigAliasResponse = new ContigAliasResponse(); + contigAliasResponse.setEmbedded(contigAliasEmbedded); + + return contigAliasResponse; + } + + +}