From 21763fe012e9d0fb62a6920e03eff6a9b2c42774 Mon Sep 17 00:00:00 2001 From: David Hoksza <david.hoksza@uni.lu> Date: Thu, 23 Nov 2017 14:56:38 +0100 Subject: [PATCH] STRING annotator including unit tests. --- .../annotation/services/ModelAnnotator.java | 8 ++ .../services/annotators/StringAnnotator.java | 110 ++++++++++++++++ .../applicationContext-annotation.xml | 1 + .../annotators/AllAnnotatorTests.java | 1 + .../annotators/StitchAnnotatorTest.java | 10 -- .../annotators/StringAnnotatorTest.java | 119 ++++++++++++++++++ .../lcsb/mapviewer/model/map/MiriamType.java | 8 ++ persist/src/db/11.1.1/fix_db_20171114.sql | 3 + 8 files changed, 250 insertions(+), 10 deletions(-) create mode 100644 annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotator.java create mode 100644 annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotatorTest.java diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/ModelAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/ModelAnnotator.java index 3e0dcf48fa..60ece88325 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/ModelAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/ModelAnnotator.java @@ -28,6 +28,7 @@ import lcsb.mapviewer.annotation.services.annotators.HgncAnnotator; import lcsb.mapviewer.annotation.services.annotators.PdbAnnotator; import lcsb.mapviewer.annotation.services.annotators.ReconAnnotator; import lcsb.mapviewer.annotation.services.annotators.StitchAnnotator; +import lcsb.mapviewer.annotation.services.annotators.StringAnnotator; import lcsb.mapviewer.annotation.services.annotators.TairAnnotator; import lcsb.mapviewer.annotation.services.annotators.UniprotAnnotator; import lcsb.mapviewer.common.IProgressUpdater; @@ -147,6 +148,12 @@ public class ModelAnnotator { @Autowired private StitchAnnotator stitchAnnotator; + /** + * STRING annotator. + */ + @Autowired + private StringAnnotator stringAnnotator; + /** * TAIR annotator. */ @@ -185,6 +192,7 @@ public class ModelAnnotator { addAnnotator(entrezAnnotator); addAnnotator(ensemblAnnotator); addAnnotator(stitchAnnotator); + addAnnotator(stringAnnotator); addAnnotator(tairAnnotator); } diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotator.java new file mode 100644 index 0000000000..70e9d34d2a --- /dev/null +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotator.java @@ -0,0 +1,110 @@ +package lcsb.mapviewer.annotation.services.annotators; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; + +import lcsb.mapviewer.annotation.services.ExternalServiceStatus; +import lcsb.mapviewer.annotation.services.IExternalService; +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.model.map.BioEntity; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.species.Gene; +import lcsb.mapviewer.model.map.species.Protein; +import lcsb.mapviewer.model.map.species.Rna; + +/** + * This is a class that implements a mapping to STRING database. + * + * @author David Hoksza + * + */ +public class StringAnnotator extends ElementAnnotator implements IExternalService { + + /** + * Service used for annotation of entities using {@link MiriamType#TAIR_LOCUS + * TAIR}. + */ + @Autowired + private TairAnnotator tairAnnotator; + + /** + * Default constructor. + */ + public StringAnnotator() { + super(StringAnnotator.class, new Class[] { Protein.class, Gene.class, Rna.class }, false); + } + + @Override + public ExternalServiceStatus getServiceStatus() { + return tairAnnotator.getServiceStatus(); + } + + @Override + public void annotateElement(BioEntity object) throws AnnotatorException { + if (isAnnotatable(object)) { + + MiriamData mdTair = null; + for (MiriamData md : object.getMiriamData()) { + if (md.getDataType().equals(MiriamType.STRING)) { + return; + } + if (md.getDataType().equals(MiriamType.TAIR_LOCUS)) { + mdTair = md; + } + } + if (mdTair != null) { + tairAnnotator.annotateElement(object); + } + + List<MiriamData> mdUniprots = new ArrayList<MiriamData>(); + for (MiriamData md : object.getMiriamData()) { + if (md.getDataType().equals(MiriamType.UNIPROT)) { + mdUniprots.add(md); + } + } + + List<String> stringIds = new ArrayList<String>(); + for (MiriamData mdUniprot: mdUniprots) { + MiriamData mdString = uniprotToString(mdUniprot); + if (mdString != null && stringIds.indexOf(mdString.getResource()) < 0) { + stringIds.add(mdString.getResource()); + object.addMiriamData(mdString); + } + } + } + } + + /** + * Transform UniProt {@link MiriamData} data to STRING {@link MiriamData}. + * + * @param UniProt + * {@link MiriamData} with UniProt identifier + * @return {@link MiriamData} with STRING identifier + * @throws AnnotatorException + * thrown when there is a problem with accessing external database + */ + public MiriamData uniprotToString(MiriamData uniprot) throws AnnotatorException { + if (uniprot == null) { + return null; + } + + if (!MiriamType.UNIPROT.equals(uniprot.getDataType())) { + throw new InvalidArgumentException(MiriamType.UNIPROT + " expected."); + } + + return new MiriamData(MiriamType.STRING, uniprot.getResource()); + } + + @Override + public String getCommonName() { + return MiriamType.STRING.getCommonName(); + } + + @Override + public String getUrl() { + return MiriamType.STRING.getDbHomepage(); + } +} diff --git a/annotation/src/main/resources/applicationContext-annotation.xml b/annotation/src/main/resources/applicationContext-annotation.xml index c7deed22f7..15b0210a0f 100644 --- a/annotation/src/main/resources/applicationContext-annotation.xml +++ b/annotation/src/main/resources/applicationContext-annotation.xml @@ -24,6 +24,7 @@ <bean id="ReconAnnotator" class="lcsb.mapviewer.annotation.services.annotators.ReconAnnotator"/> <bean id="PdbAnnotator" class="lcsb.mapviewer.annotation.services.annotators.PdbAnnotator"/> <bean id="StitchAnnotator" class="lcsb.mapviewer.annotation.services.annotators.StitchAnnotator"/> + <bean id="StringAnnotator" class="lcsb.mapviewer.annotation.services.annotators.StringAnnotator"/> <bean id="TairAnnotator" class="lcsb.mapviewer.annotation.services.annotators.TairAnnotator"/> <bean id="UniprotAnnotator" class="lcsb.mapviewer.annotation.services.annotators.UniprotAnnotator"/> diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/AllAnnotatorTests.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/AllAnnotatorTests.java index 84f29bbdce..0bd9c6f3f8 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/AllAnnotatorTests.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/AllAnnotatorTests.java @@ -18,6 +18,7 @@ import org.junit.runners.Suite.SuiteClasses; PdbAnnotatorTest.class, // ReconAnnotatorTest.class, // StitchAnnotatorTest.class, // + StringAnnotatorTest.class, // TairAnnotatorTest.class, // UniprotAnnotatorTest.class, // }) diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StitchAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StitchAnnotatorTest.java index 4a20dea772..2016f4875e 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StitchAnnotatorTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StitchAnnotatorTest.java @@ -1,24 +1,14 @@ package lcsb.mapviewer.annotation.services.annotators; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.when; - -import java.io.IOException; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import lcsb.mapviewer.annotation.AnnotationTestFunctions; -import lcsb.mapviewer.annotation.cache.WebPageDownloader; -import lcsb.mapviewer.annotation.services.ExternalServiceStatusType; -import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.model.map.MiriamData; import lcsb.mapviewer.model.map.MiriamType; import lcsb.mapviewer.model.map.species.SimpleMolecule; diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotatorTest.java new file mode 100644 index 0000000000..1264c71c81 --- /dev/null +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotatorTest.java @@ -0,0 +1,119 @@ +package lcsb.mapviewer.annotation.services.annotators; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import lcsb.mapviewer.annotation.AnnotationTestFunctions; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.species.GenericProtein; +import lcsb.mapviewer.model.map.species.Species; + +public class StringAnnotatorTest extends AnnotationTestFunctions { + + @Autowired + StringAnnotator testedAnnotator; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAnnotateUniprot() throws Exception { + try { + + Species bioEntity = new GenericProtein("id"); + bioEntity.addMiriamData(new MiriamData(MiriamType.UNIPROT, "P53350")); + + testedAnnotator.annotateElement(bioEntity); + + MiriamData mdString = null; + + for (MiriamData md : bioEntity.getMiriamData()) { + if (md.getDataType().equals(MiriamType.STRING)) { + mdString = md; //there should be only one EC number for that TAIR<->UNIPROT record + } + } + + assertTrue("No STRING annotation extracted from STRING annotator", mdString != null); + assertTrue("Wrong number of annotations extract from STRING annotator", bioEntity.getMiriamData().size() == 2); + assertTrue("Invalid STRING annotation extracted from STRING annotator based on the UniProt annotation", mdString.getResource().equalsIgnoreCase("P53350") ); + + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testAnnotateTair() throws Exception { + try { + + Species bioEntity = new GenericProtein("id"); + bioEntity.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "AT1G01030")); + + testedAnnotator.annotateElement(bioEntity); + + MiriamData mdString = null; + + for (MiriamData md : bioEntity.getMiriamData()) { + if (md.getDataType().equals(MiriamType.STRING)) { + mdString = md; //there should be only one EC number for that TAIR<->UNIPROT record + } + } + + assertTrue("No STRING annotation extracted from STRING annotator", mdString != null); + assertTrue("Wrong number of annotations extract from STRING annotator", bioEntity.getMiriamData().size() == 3); + + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + + + @Test + public void testAnnotateInvalidEmpty() throws Exception { + try { + Species bioEntity = new GenericProtein("id"); + testedAnnotator.annotateElement(bioEntity); + + assertEquals(0, bioEntity.getMiriamData().size()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testAnnotateInvalidTair() throws Exception { + try { + Species bioEntity = new GenericProtein("id"); + bioEntity.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "bla")); + testedAnnotator.annotateElement(bioEntity); + + assertEquals(1, bioEntity.getMiriamData().size()); + + assertEquals(1, getWarnings().size()); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + //All the service status tests are not necessary, since STRING annotator + //internally calls TAIR annotator which has it own set of tests +} diff --git a/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java b/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java index 9b9740197b..155ec768e4 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java @@ -364,6 +364,14 @@ public enum MiriamType { "http://stitch.embl.de/", // "urn:miriam:stitch", // new Class<?>[] {}, "MIR:00100343"), + + /** + * STRING: http://string-db.org/. + */ + STRING("STRING", // + "http://string-db.org/", // + "urn:miriam:string", // + new Class<?>[] {}, "MIR:00000265"), /** * The Arabidopsis Information Resource (TAIR) maintains a database of genetic diff --git a/persist/src/db/11.1.1/fix_db_20171114.sql b/persist/src/db/11.1.1/fix_db_20171114.sql index fdf19e1303..c5481fe2fd 100644 --- a/persist/src/db/11.1.1/fix_db_20171114.sql +++ b/persist/src/db/11.1.1/fix_db_20171114.sql @@ -10,3 +10,6 @@ INSERT INTO cache_type(validity, classname) VALUES (365, 'lcsb.mapviewer.annotat DELETE FROM cache_type WHERE classname = 'lcsb.mapviewer.annotation.services.annotators.StitchAnnotator'; INSERT INTO cache_type(validity, classname) VALUES (365, 'lcsb.mapviewer.annotation.services.annotators.StitchAnnotator'); +DELETE FROM cache_type WHERE classname = 'lcsb.mapviewer.annotation.services.annotators.StringAnnotator'; +INSERT INTO cache_type(validity, classname) VALUES (365, 'lcsb.mapviewer.annotation.services.annotators.StringAnnotator'); + -- GitLab