Skip to content
Snippets Groups Projects
Commit 20efc52f authored by David Hoksza's avatar David Hoksza
Browse files

CAZy annotator including unit tests.

parent 7039d87a
No related branches found
No related tags found
1 merge request!201Cellwall annotations
Pipeline #
...@@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import lcsb.mapviewer.annotation.services.annotators.AnnotatorException; import lcsb.mapviewer.annotation.services.annotators.AnnotatorException;
import lcsb.mapviewer.annotation.services.annotators.BiocompendiumAnnotator; import lcsb.mapviewer.annotation.services.annotators.BiocompendiumAnnotator;
import lcsb.mapviewer.annotation.services.annotators.CazyAnnotator;
import lcsb.mapviewer.annotation.services.annotators.ChebiAnnotator; import lcsb.mapviewer.annotation.services.annotators.ChebiAnnotator;
import lcsb.mapviewer.annotation.services.annotators.ElementAnnotator; import lcsb.mapviewer.annotation.services.annotators.ElementAnnotator;
import lcsb.mapviewer.annotation.services.annotators.EnsemblAnnotator; import lcsb.mapviewer.annotation.services.annotators.EnsemblAnnotator;
...@@ -75,6 +76,12 @@ public class ModelAnnotator { ...@@ -75,6 +76,12 @@ public class ModelAnnotator {
*/ */
@Autowired @Autowired
private BiocompendiumAnnotator biocompendiumAnnotator; private BiocompendiumAnnotator biocompendiumAnnotator;
/**
* CAZy annotator.
*/
@Autowired
private CazyAnnotator cazyAnnotator;
/** /**
* Backend to the chebi database. * Backend to the chebi database.
...@@ -153,6 +160,7 @@ public class ModelAnnotator { ...@@ -153,6 +160,7 @@ public class ModelAnnotator {
defaultAnnotators = new ArrayList<>(); defaultAnnotators = new ArrayList<>();
addAnnotator(biocompendiumAnnotator); addAnnotator(biocompendiumAnnotator);
addAnnotator(cazyAnnotator);
addAnnotator(chebiBackend); addAnnotator(chebiBackend);
addAnnotator(uniprotAnnotator); addAnnotator(uniprotAnnotator);
addAnnotator(goAnnotator); addAnnotator(goAnnotator);
......
package lcsb.mapviewer.annotation.services.annotators;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import lcsb.mapviewer.annotation.cache.GeneralCacheInterface;
import lcsb.mapviewer.annotation.cache.SourceNotAvailable;
import lcsb.mapviewer.annotation.cache.WebPageDownloader;
import lcsb.mapviewer.annotation.services.ExternalServiceStatus;
import lcsb.mapviewer.annotation.services.ExternalServiceStatusType;
import lcsb.mapviewer.annotation.services.IExternalService;
import lcsb.mapviewer.annotation.services.WrongResponseCodeIOException;
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 backend to CAZy.
*
* @author David Hoksza
*
*/
public class CazyAnnotator extends ElementAnnotator implements IExternalService {
/**
* Default class logger.
*/
private static Logger logger = Logger.getLogger(CazyAnnotator.class);
/**
* Service used for annotation of entities using {@link MiriamType#TAIR_LOCUS
* tair}.
*/
@Autowired
private TairAnnotator tairAnnotator;
/**
* Pattern used for finding UniProt symbol from TAIR info page .
*/
private Pattern cazyIdMatcher = Pattern.compile("\\/((GT|GH|PL|CE|CBM)\\d+(\\_\\d+)?)\\.html");
/**
* Default constructor.
*/
public CazyAnnotator() {
super(CazyAnnotator.class, new Class[] { Protein.class, Gene.class, Rna.class }, false);
}
@Override
public ExternalServiceStatus getServiceStatus() { //TODO
ExternalServiceStatus status = new ExternalServiceStatus(getCommonName(), getUrl());
GeneralCacheInterface cacheCopy = getCache();
this.setCache(null);
try {
MiriamData md = uniprotToCazy(new MiriamData(MiriamType.UNIPROT, "Q9SG95"));
status.setStatus(ExternalServiceStatusType.OK);
if (md == null || !md.getResource().equalsIgnoreCase("GH5_7")) {
status.setStatus(ExternalServiceStatusType.CHANGED);
}
} catch (Exception e) {
logger.error(status.getName() + " is down", e);
status.setStatus(ExternalServiceStatusType.DOWN);
}
this.setCache(cacheCopy);
return status;
}
@Override
public void annotateElement(BioEntity object) throws AnnotatorException {
if (isAnnotatable(object)) {
MiriamData mdTair = null;
MiriamData mdCazy = null;
for (MiriamData md : object.getMiriamData()) {
if (md.getDataType().equals(MiriamType.CAZY)) {
mdCazy = md;
}
else if (md.getDataType().equals(MiriamType.TAIR_LOCUS)) {
mdTair = md;
}
}
if (mdCazy != null) {
return;
}
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> cazyIds = new ArrayList<String>();
for (MiriamData mdUniprot: mdUniprots) {
mdCazy = uniprotToCazy(mdUniprot);
if (mdCazy != null && cazyIds.indexOf(mdCazy.getResource()) == -1) {
cazyIds.add(mdCazy.getResource());
object.addMiriamData(mdCazy);
}
}
}
}
/**
* Returns URL to TAIR page about TAIR entry.
*
* @param uniProtId
* UniProt identifier
* @return URL to CAZY UniProt accession search result page
*/
private String getCazyUrl(String uniProtId) {
return "http://www.cazy.org/search?page=recherche&recherche=" + uniProtId + "&tag=10";
}
/**
* Parse CAZy webpage to find information about
* {@link MiriamType#CAZY} and returns them.
*
* @param pageContent
* CAZy info page
* @return CAZy family identifier found on the page
*/
private Collection<MiriamData> parseCazy(String pageContent) {
Collection<MiriamData> result = new HashSet<MiriamData>();
Matcher m = cazyIdMatcher.matcher(pageContent);
if (m.find()) {
result.add(new MiriamData(MiriamType.CAZY, m.group(1)));
}
return result;
}
@Override
public Object refreshCacheQuery(Object query) throws SourceNotAvailable {
String name;
String result = null;
if (query instanceof String) {
name = (String) query;
if (name.startsWith("http")) {
try {
result = getWebPageContent(name);
} catch (IOException e) {
throw new SourceNotAvailable(e);
}
} else {
throw new InvalidArgumentException("Don't know what to do with query: " + query);
}
} else {
throw new InvalidArgumentException("Don't know what to do with class: " + query.getClass());
}
return result;
}
/**
* Transform UniProt identifier to CAZy identifier.
*
* @param UniProt
* {@link MiriamData} with UniProt identifier
* @return {@link MiriamData} with CAZy identifier
* @throws AnnotatorException
* thrown when there is a problem with accessing external database
*/
public MiriamData uniprotToCazy(MiriamData uniprot) throws AnnotatorException {
if (uniprot == null) {
return null;
}
if (!MiriamType.UNIPROT.equals(uniprot.getDataType())) {
throw new InvalidArgumentException(MiriamType.UNIPROT + " expected.");
}
String accessUrl = getCazyUrl(uniprot.getResource());
try {
String pageContent = getWebPageContent(accessUrl);
Collection<MiriamData> collection = parseCazy(pageContent);
if (collection.size() > 0) {
return collection.iterator().next();
} else {
logger.warn("Cannot find CAZy data for UniProt id: " + uniprot.getResource());
return null;
}
} catch (WrongResponseCodeIOException exception) {
logger.warn("Wrong response code when retrieving CAZy data for UniProt id: " + uniprot.getResource());
return null;
} catch (IOException exception) {
throw new AnnotatorException(exception);
}
}
@Override
public String getCommonName() {
return MiriamType.CAZY.getCommonName();
}
@Override
public String getUrl() {
return MiriamType.CAZY.getDbHomepage();
}
@Override
protected WebPageDownloader getWebPageDownloader() {
return super.getWebPageDownloader();
}
@Override
protected void setWebPageDownloader(WebPageDownloader webPageDownloader) {
super.setWebPageDownloader(webPageDownloader);
}
}
...@@ -154,7 +154,7 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService ...@@ -154,7 +154,7 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService
* @param tair * @param tair
* {@link MiriamData} with TAIR identifier * {@link MiriamData} with TAIR identifier
* @return {@link MiriamData} with UniProt identifier * @return {@link MiriamData} with UniProt identifier
* @throws UniprotSearchException * @throws AnnotatorException
* thrown when there is a problem with accessing external database * thrown when there is a problem with accessing external database
*/ */
public MiriamData tairToUniprot(MiriamData tair) throws AnnotatorException { public MiriamData tairToUniprot(MiriamData tair) throws AnnotatorException {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
<!-- Annotators --> <!-- Annotators -->
<bean id="BiocompendiumAnnotator" class="lcsb.mapviewer.annotation.services.annotators.BiocompendiumAnnotator"/> <bean id="BiocompendiumAnnotator" class="lcsb.mapviewer.annotation.services.annotators.BiocompendiumAnnotator"/>
<bean id="CazyAnnotator" class="lcsb.mapviewer.annotation.services.annotators.CazyAnnotator"/>
<bean id="ChebiAnnotator" class="lcsb.mapviewer.annotation.services.annotators.ChebiAnnotator"/> <bean id="ChebiAnnotator" class="lcsb.mapviewer.annotation.services.annotators.ChebiAnnotator"/>
<bean id="EnsemblAnnotator" class="lcsb.mapviewer.annotation.services.annotators.EnsemblAnnotator"/> <bean id="EnsemblAnnotator" class="lcsb.mapviewer.annotation.services.annotators.EnsemblAnnotator"/>
<bean id="EntrezAnnotator" class="lcsb.mapviewer.annotation.services.annotators.EntrezAnnotator"/> <bean id="EntrezAnnotator" class="lcsb.mapviewer.annotation.services.annotators.EntrezAnnotator"/>
......
...@@ -7,6 +7,7 @@ import org.junit.runners.Suite.SuiteClasses; ...@@ -7,6 +7,7 @@ import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class) @RunWith(Suite.class)
@SuiteClasses({ AnnotatorExceptionTest.class, // @SuiteClasses({ AnnotatorExceptionTest.class, //
BiocompendiumAnnotatorTest.class, // BiocompendiumAnnotatorTest.class, //
CazyAnnotatorTest.class, //
ChebiAnnotatorTest.class, // ChebiAnnotatorTest.class, //
ElementAnnotatorTest.class, // ElementAnnotatorTest.class, //
EnsemblAnnotatorTest.class, // EnsemblAnnotatorTest.class, //
......
package lcsb.mapviewer.annotation.services.annotators;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
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.GenericProtein;
import lcsb.mapviewer.model.map.species.Species;
public class CazyAnnotatorTest extends AnnotationTestFunctions {
@Autowired
CazyAnnotator cazyAnnotator;
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testUniprotToCazy() throws Exception {
try {
assertEquals(new MiriamData(MiriamType.CAZY, "GH5_7"),
cazyAnnotator.uniprotToCazy(new MiriamData(MiriamType.UNIPROT, "Q9SG95")));
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testAnnotateFromUniprot() throws Exception {
try {
Species protein = new GenericProtein("id");
protein.setName("bla");
protein.addMiriamData(new MiriamData(MiriamType.UNIPROT, "Q9SG95"));
cazyAnnotator.annotateElement(protein);
MiriamData mdCazy = null;
for (MiriamData md : protein.getMiriamData()) {
if (md.getDataType().equals(MiriamType.CAZY)) {
mdCazy = md;
}
}
assertTrue("No UNIPROT annotation extracted from TAIR annotator", mdCazy != null);
assertTrue("Invalid UNIPROT annotation extracted from TAIR annotator", mdCazy.getResource().equalsIgnoreCase("GH5_7") );
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testAnnotateFromTair() throws Exception {
try {
Species protein = new GenericProtein("id");
protein.setName("bla");
protein.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "AT3G53010"));
cazyAnnotator.annotateElement(protein);
MiriamData mdCazy = null;
for (MiriamData md : protein.getMiriamData()) {
if (md.getDataType().equals(MiriamType.CAZY)) {
mdCazy = md;
}
}
assertTrue("No CAZy annotation extracted from CAZy annotator", mdCazy != null);
assertTrue("Invalid CAZy annotation extracted from CAZy annotator", mdCazy.getResource().equalsIgnoreCase("CE6") );
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testAnnotateMultipleUniprots() throws Exception {
try {
Species protein = new GenericProtein("id");
protein.setName("bla");
protein.addMiriamData(new MiriamData(MiriamType.UNIPROT, "Q9SG95"));
protein.addMiriamData(new MiriamData(MiriamType.UNIPROT, "Q12540"));
cazyAnnotator.annotateElement(protein);
int cntMDs = 0;
for (MiriamData md : protein.getMiriamData()) {
if (md.getDataType().equals(MiriamType.CAZY)) {
cntMDs++;
}
}
assertTrue("Wrong number of CAZy identifiers extracted from CAZy annotator", cntMDs == 2 );
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testAnnotateInvalidEmpty() throws Exception {
try {
Species protein = new GenericProtein("id");
protein.setName("bla");
cazyAnnotator.annotateElement(protein);
assertEquals(0, protein.getMiriamData().size());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testAnnotateInvalidUniprot() throws Exception {
try {
Species protein = new GenericProtein("id");
protein.addMiriamData(new MiriamData(MiriamType.UNIPROT, "bla"));
cazyAnnotator.annotateElement(protein);
assertEquals(1, protein.getMiriamData().size());
assertEquals(1, getWarnings().size());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testAnnotateInvalidTair() throws Exception {
try {
Species protein = new GenericProtein("id");
protein.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "bla"));
cazyAnnotator.annotateElement(protein);
assertEquals(1, protein.getMiriamData().size());
assertEquals(1, getWarnings().size());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testInvalidUniprotToCazyNull() throws Exception {
try {
assertNull(cazyAnnotator.uniprotToCazy(null));
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testInvalidUniprotToCazyWrongMd() throws Exception {
try {
cazyAnnotator.uniprotToCazy(new MiriamData(MiriamType.WIKIPEDIA, "bla"));
fail("Exception expected");
} catch (InvalidArgumentException e) {
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testRefreshInvalidCacheQuery() throws Exception {
try {
cazyAnnotator.refreshCacheQuery("invalid_query");
fail("Exception expected");
} catch (InvalidArgumentException e) {
assertTrue(e.getMessage().contains("Don't know what to do"));
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testRefreshInvalidCacheQuery2() throws Exception {
try {
cazyAnnotator.refreshCacheQuery(new Object());
fail("Exception expected");
} catch (InvalidArgumentException e) {
assertTrue(e.getMessage().contains("Don't know what to do"));
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testRefreshCacheQuery() throws Exception {
try {
Object res = cazyAnnotator.refreshCacheQuery("http://google.cz/");
assertNotNull(res);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testStatus() throws Exception {
try {
assertEquals(ExternalServiceStatusType.OK, cazyAnnotator.getServiceStatus().getStatus());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testSimulateDownStatus() throws Exception {
WebPageDownloader downloader = cazyAnnotator.getWebPageDownloader();
try {
WebPageDownloader mockDownloader = Mockito.mock(WebPageDownloader.class);
when(mockDownloader.getFromNetwork(anyString(), anyString(), anyString())).thenThrow(new IOException());
cazyAnnotator.setWebPageDownloader(mockDownloader);
assertEquals(ExternalServiceStatusType.DOWN, cazyAnnotator.getServiceStatus().getStatus());
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
cazyAnnotator.setWebPageDownloader(downloader);
}
}
@Test
public void testSimulateChangedStatus() throws Exception {
WebPageDownloader downloader = cazyAnnotator.getWebPageDownloader();
try {
WebPageDownloader mockDownloader = Mockito.mock(WebPageDownloader.class);
when(mockDownloader.getFromNetwork(anyString(), anyString(), anyString())).thenReturn("GN Name=ACSS2; Synonyms=ACAS2;");
cazyAnnotator.setWebPageDownloader(mockDownloader);
assertEquals(ExternalServiceStatusType.CHANGED, cazyAnnotator.getServiceStatus().getStatus());
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
cazyAnnotator.setWebPageDownloader(downloader);
}
}
}
...@@ -29,6 +29,14 @@ public enum MiriamType { ...@@ -29,6 +29,14 @@ public enum MiriamType {
"http://commonchemistry.org", // "http://commonchemistry.org", //
new String[] { "urn:miriam:cas" }, // new String[] { "urn:miriam:cas" }, //
new Class<?>[] {}, "MIR:00000237"), // new Class<?>[] {}, "MIR:00000237"), //
/**
* The Carbohydrate-Active Enzyme (CAZy) database: http://www.cazy.org/.
*/
CAZY("Carbohydrate-Active enzYmes", //
"http://commonchemistry.org", //
new String[] { "urn:miriam:cazy" }, //
new Class<?>[] {}, "MIR:00000195"), //
/** /**
* Consensus CDS: http://identifiers.org/ccds/. * Consensus CDS: http://identifiers.org/ccds/.
......
DELETE FROM cache_type WHERE classname = 'lcsb.mapviewer.annotation.services.annotators.TairAnnotator'; DELETE FROM cache_type WHERE classname = 'lcsb.mapviewer.annotation.services.annotators.TairAnnotator';
INSERT INTO cache_type(validity, classname) VALUES (365, 'lcsb.mapviewer.annotation.services.annotators.TairAnnotator'); INSERT INTO cache_type(validity, classname) VALUES (365, 'lcsb.mapviewer.annotation.services.annotators.TairAnnotator');
\ No newline at end of file
DELETE FROM cache_type WHERE classname = 'lcsb.mapviewer.annotation.services.annotators.CazyAnnotator';
INSERT INTO cache_type(validity, classname) VALUES (365, 'lcsb.mapviewer.annotation.services.annotators.CazyAnnotator');
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment