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 f3b3f463ed38de817bab82431aeaf074b9c4995e..3e0dcf48faf902e4611e9f6184de6f39e13ace14 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/ModelAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/ModelAnnotator.java @@ -27,6 +27,7 @@ import lcsb.mapviewer.annotation.services.annotators.GoAnnotator; 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.TairAnnotator; import lcsb.mapviewer.annotation.services.annotators.UniprotAnnotator; import lcsb.mapviewer.common.IProgressUpdater; @@ -140,6 +141,12 @@ public class ModelAnnotator { @Autowired private EnsemblAnnotator ensemblAnnotator; + /** + * STITCH annotator. + */ + @Autowired + private StitchAnnotator stitchAnnotator; + /** * TAIR annotator. */ @@ -177,6 +184,7 @@ public class ModelAnnotator { addAnnotator(reconAnnotator); addAnnotator(entrezAnnotator); addAnnotator(ensemblAnnotator); + addAnnotator(stitchAnnotator); addAnnotator(tairAnnotator); } diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StitchAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StitchAnnotator.java new file mode 100644 index 0000000000000000000000000000000000000000..37a36f9a530e5d3a739aa6820ac8a205fe6a9b7d --- /dev/null +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StitchAnnotator.java @@ -0,0 +1,120 @@ +package lcsb.mapviewer.annotation.services.annotators; + + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; + +import lcsb.mapviewer.annotation.cache.SourceNotAvailable; +import lcsb.mapviewer.annotation.cache.WebPageDownloader; +import lcsb.mapviewer.annotation.data.Chebi; +import lcsb.mapviewer.annotation.services.ExternalServiceStatus; +import lcsb.mapviewer.annotation.services.IExternalService; +import lcsb.mapviewer.model.map.BioEntity; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.species.SimpleMolecule; + +/** + * This is a class that implements STITCH annotation which is derived from existing ChEBI annotation. + * + * @author David Hoksza + * + */ +public class StitchAnnotator extends ElementAnnotator implements IExternalService { + + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(StitchAnnotator.class); + + /** + * Service used for annotation of entities using {@link MiriamType#STITCH STITCH}. + */ + @Autowired + private ChebiAnnotator chebiAnnotator; + + /** + * Default constructor. + */ + public StitchAnnotator() { + super(StitchAnnotator.class, new Class[] { SimpleMolecule.class }, false); + } + + @Override + public ExternalServiceStatus getServiceStatus() { + return chebiAnnotator.getServiceStatus(); + } + + /** + * Returns main layer of the InchKey, * i.e. everything + * before first hyphen: WBYWAXJHAXSJNI-VOTSOKGWSA-N -> WBYWAXJHAXSJNI + * @param inchiKey Full inchiKey + * @return Main layer of the InchiKey + */ + private String inchiKeyExtractMainLayer(String inchiKey){ + return inchiKey.replaceFirst("-.*", ""); + } + + @Override + public void annotateElement(BioEntity object) throws AnnotatorException { + if (isAnnotatable(object)) { + + MiriamData mdChebi = null; + + for (MiriamData md : object.getMiriamData()) { + if (md.getDataType().equals(MiriamType.CHEBI)) { + mdChebi = md; + } + else if (md.getDataType().equals(MiriamType.STITCH)) { + return; + } + } + + if (mdChebi == null) { + return; + } + + try { + + Chebi chebi = chebiAnnotator.getChebiElementForChebiId(mdChebi); + if (chebi == null) { + return; + } + String inchiKey = chebi.getInchiKey(); + if (inchiKey == null) { + return; + } + + object.addMiriamData(new MiriamData(MiriamType.STITCH, inchiKeyExtractMainLayer(inchiKey))); + } catch(ChebiSearchException exception) { + logger.warn("No ChEBI element retrieved fro ChEBI ID: " + mdChebi.getResource()); + } + } + } + + @Override + public Object refreshCacheQuery(Object query) throws SourceNotAvailable { + return chebiAnnotator.refreshCacheQuery(query); + } + + + @Override + public String getCommonName() { + return MiriamType.STITCH.getCommonName(); + } + + @Override + public String getUrl() { + return MiriamType.STITCH.getDbHomepage(); + } + + @Override + protected WebPageDownloader getWebPageDownloader() { + return super.getWebPageDownloader(); + } + + @Override + protected void setWebPageDownloader(WebPageDownloader webPageDownloader) { + super.setWebPageDownloader(webPageDownloader); + } +} diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java index eda127b27e4d6ea31f1e3296c50379f2bec8749b..0388293b12b091d15b0bf127e63d69e47bb6bf46 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java @@ -123,7 +123,7 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService Matcher m = tairToUniprot.matcher(pageContent); if (m.find()) { result.add(new MiriamData(MiriamType.UNIPROT, m.group(1))); - } + } return result; } diff --git a/annotation/src/main/resources/applicationContext-annotation.xml b/annotation/src/main/resources/applicationContext-annotation.xml index ee83e7e98773f7e9960b279350a44fc68b347db4..c7deed22f76b818d87aaba6db44bba30885af859 100644 --- a/annotation/src/main/resources/applicationContext-annotation.xml +++ b/annotation/src/main/resources/applicationContext-annotation.xml @@ -23,6 +23,7 @@ <bean id="HgncAnnotator" class="lcsb.mapviewer.annotation.services.annotators.HgncAnnotator"/> <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="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 8325d7f57cb8d375914e660bbc7d11a942988730..84f29bbdce07283272d7431bcf2163fc5860f3f0 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 @@ -17,6 +17,7 @@ import org.junit.runners.Suite.SuiteClasses; HgncAnnotatorTest.class, // PdbAnnotatorTest.class, // ReconAnnotatorTest.class, // + StitchAnnotatorTest.class, // TairAnnotatorTest.class, // UniprotAnnotatorTest.class, // }) diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/BrendaAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/BrendaAnnotatorTest.java index 87711ddccc6d814c6baa43a1c955cdcf5f4c430b..963bc74fa59afa47bedd9e34a6df59dac490d5c4 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/BrendaAnnotatorTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/BrendaAnnotatorTest.java @@ -40,7 +40,7 @@ public class BrendaAnnotatorTest extends AnnotationTestFunctions { } @Test - public void testUniprotToCazy() throws Exception { + public void testUniprotToBrenda() throws Exception { try { Collection<MiriamData> mds = brendaAnnotator.uniprotToBrenda(new MiriamData(MiriamType.UNIPROT, "P12345")); assertEquals(mds.size(), 2); 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 new file mode 100644 index 0000000000000000000000000000000000000000..4a20dea77209b369a6210a2bbf99211283f6c598 --- /dev/null +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StitchAnnotatorTest.java @@ -0,0 +1,112 @@ +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; +import lcsb.mapviewer.model.map.species.Species; + +public class StitchAnnotatorTest extends AnnotationTestFunctions { + + @Autowired + StitchAnnotator testedAnnotator; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testAnnotate() throws Exception { + try { + + Species bioEntity = new SimpleMolecule("id"); + bioEntity.addMiriamData(new MiriamData(MiriamType.CHEBI, "CHEBI:35697")); + + testedAnnotator.annotateElement(bioEntity); + + MiriamData mdStitch = null; + + for (MiriamData md : bioEntity.getMiriamData()) { + if (md.getDataType().equals(MiriamType.STITCH)) { + mdStitch = md; //there should be only one EC number for that TAIR<->UNIPROT record + } + } + + assertTrue("No STITCH annotation extracted from STITCH annotator", mdStitch != null); + assertTrue("Wrong number of annotations extract from STITCH annotator", bioEntity.getMiriamData().size() == 2); + assertTrue("Invalid STITCH annotation extracted from STITCH annotator based on CHEBI ID", mdStitch.getResource().equalsIgnoreCase("WBYWAXJHAXSJNI") ); + + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testExtractInchiMainLayer() throws Exception { + try { + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testAnnotateInvalidEmpty() throws Exception { + try { + Species bioEntity = new SimpleMolecule("id"); + testedAnnotator.annotateElement(bioEntity); + + assertEquals(0, bioEntity.getMiriamData().size()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testAnnotateInvalidChebi() throws Exception { + try { + Species bioEntity = new SimpleMolecule("id"); + bioEntity.addMiriamData(new MiriamData(MiriamType.CHEBI, "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 STTICH annotator + //internally calls ChEBI 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 831ca861b81f656702683e6610727763b62db808..f3526282a58ffb6d252381973bd6d6f02f95c559 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/MiriamType.java @@ -365,6 +365,14 @@ public enum MiriamType { "http://www.yeastgenome.org/", // "urn:miriam:sgd", // new Class<?>[] {}, "MIR:00000023"), + + /** + * STITCH: http://stitch.embl.de/. + */ + STITCH("STITCH", // + "http://stitch.embl.de/", // + "urn:miriam:stitch", // + new Class<?>[] {}, "MIR:00100343"), /** * 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 771e3f42a9a340dd5f6c0def1693ce7e87f443f3..fdf19e1303b661764dd4b56cb1eb9fb84d1a6063 100644 --- a/persist/src/db/11.1.1/fix_db_20171114.sql +++ b/persist/src/db/11.1.1/fix_db_20171114.sql @@ -6,3 +6,7 @@ INSERT INTO cache_type(validity, classname) VALUES (365, 'lcsb.mapviewer.annotat DELETE FROM cache_type WHERE classname = 'lcsb.mapviewer.annotation.services.annotators.BrendaAnnotator'; INSERT INTO cache_type(validity, classname) VALUES (365, 'lcsb.mapviewer.annotation.services.annotators.BrendaAnnotator'); + +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'); +