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

Passing annotator parameters from client to server

parent dd7c78a0
No related branches found
No related tags found
1 merge request!201Cellwall annotations
......@@ -363,9 +363,7 @@ public class ModelAnnotator {
for (ElementAnnotator elementAnnotator : list) {
try {
List<UserAnnotatorsParam> params = annotatorsParams.get(elementAnnotator.getClass());
logger.debug("params");
logger.debug(params);
List<UserAnnotatorsParam> params = annotatorsParams.get(elementAnnotator.getClass());
if (params != null) {
elementAnnotator.annotateElement(element, params);
} else {
......
......@@ -4,6 +4,7 @@ package lcsb.mapviewer.annotation.services.annotators;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
......@@ -27,6 +28,7 @@ import lcsb.mapviewer.model.map.species.GenericProtein;
import lcsb.mapviewer.model.map.species.Protein;
import lcsb.mapviewer.model.map.species.Rna;
import lcsb.mapviewer.model.map.species.Species;
import lcsb.mapviewer.model.user.UserAnnotatorsParam;
/**
* This is a class that implements KEGG annotator which extract from KEGG
......@@ -48,6 +50,11 @@ public class KeggAnnotator extends ElementAnnotator implements IExternalService
*/
private Pattern pubmedMatcher = Pattern.compile("\\[PMID:(\\d+)\\]");
/**
* Pattern used for finding ATH orghologs in KEGG GENE sectionpage.
*/
private Pattern athOrthologMatcher = Pattern.compile(" *ATH: (.*)");
/**
* Service used for annotation of entities using {@link MiriamType#TAIR_LOCUS TAIR}.
......@@ -73,14 +80,6 @@ public class KeggAnnotator extends ElementAnnotator implements IExternalService
+ " (GENE section in the KEGG enzyme record) should be imported."
+ " Currently ATH (Arabidopsis Thaliana) is supported.");
this.addParameterDefinition(paramDef);
this.addParameterDefinition(new AnnotatorParamDefinition("test string1", String.class, "test string1 comment"));
this.addParameterDefinition(new AnnotatorParamDefinition("test int1", Integer.class, "int1 comment"));
this.addParameterDefinition(new AnnotatorParamDefinition("test bool1", Boolean.class, "boolean comment"));
this.addParameterDefinition(new AnnotatorParamDefinition("test bool2", Boolean.class, "boolean comment 2"));
this.addParameterDefinition(new AnnotatorParamDefinition("test int2", Integer.class, "int2 comment"));
this.addParameterDefinition(new AnnotatorParamDefinition("test int3", Integer.class, "int3 comment"));
this.addParameterDefinition(new AnnotatorParamDefinition("test string2", String.class, "test string2 comment"));
}
@Override
......@@ -122,61 +121,66 @@ public class KeggAnnotator extends ElementAnnotator implements IExternalService
@Override
public void annotateElement(BioEntity object) throws AnnotatorException {
if (isAnnotatable(object)) {
public void annotateElement(BioEntity object, List<UserAnnotatorsParam> params) throws AnnotatorException {
if (!isAnnotatable(object)) { return; }
MiriamData mdTair = null;
for (MiriamData md : object.getMiriamData()) {
Class<?> annotator = md.getAnnotator();
if (annotator == this.getClass()) {
//this annotator was already used
return;
}
else if (md.getDataType().equals(MiriamType.TAIR_LOCUS) &&
(annotator == null ) ) {
mdTair = md;
}
MiriamData mdTair = null;
for (MiriamData md : object.getMiriamData()) {
Class<?> annotator = md.getAnnotator();
if (annotator == this.getClass()) {
//this annotator was already used
return;
}
if (mdTair != null) tairAnnotator.annotateElement(object);
MiriamData mdUniprot = null;
for (MiriamData md : object.getMiriamData()) {
if (md.getDataType().equals(MiriamType.UNIPROT) ) {
mdUniprot = md;
}
else if (md.getDataType().equals(MiriamType.TAIR_LOCUS) &&
(annotator == null ) ) {
mdTair = md;
}
}
if (mdTair != null) tairAnnotator.annotateElement(object);
MiriamData mdUniprot = null;
for (MiriamData md : object.getMiriamData()) {
if (md.getDataType().equals(MiriamType.UNIPROT) ) {
mdUniprot = md;
}
if (mdUniprot != null) uniprotAnnotator.annotateElement(object);
Set<String> ecs = new HashSet<String>();
for (MiriamData md : object.getMiriamData()) {
if (md.getDataType().equals(MiriamType.EC)) {
ecs.add(md.getResource());
}
}
if (mdUniprot != null) uniprotAnnotator.annotateElement(object);
Set<String> ecs = new HashSet<String>();
for (MiriamData md : object.getMiriamData()) {
if (md.getDataType().equals(MiriamType.EC)) {
ecs.add(md.getResource());
}
}
if (ecs.size() == 0) {
return;
}
//annotate from KEGG
Set<MiriamData> annotations = new HashSet<MiriamData>();
for (String ec: ecs) {
if (ecs.size() == 0) {
return;
}
//annotate from KEGG
Set<MiriamData> annotations = new HashSet<MiriamData>();
for (String ec: ecs) {
String accessUrl = getKeggUrl(ec);
try {
String pageContent = getWebPageContent(accessUrl);
annotations.addAll(parseKegg(pageContent));
} catch (WrongResponseCodeIOException exception) {
logger.warn("Cannot find kegg data for id: " + ec);
} catch (IOException exception) {
throw new AnnotatorException(exception);
}
String accessUrl = getKeggUrl(ec);
try {
String pageContent = getWebPageContent(accessUrl);
annotations.addAll(parseKegg(pageContent, params));
} catch (WrongResponseCodeIOException exception) {
logger.warn("Cannot find kegg data for id: " + ec);
} catch (IOException exception) {
throw new AnnotatorException(exception);
}
object.addMiriamData(annotations);
}
}
object.addMiriamData(annotations);
}
@Override
public void annotateElement(BioEntity object) throws AnnotatorException {
this.annotateElement(object, null);
}
/**
......@@ -196,9 +200,16 @@ public class KeggAnnotator extends ElementAnnotator implements IExternalService
*
* @param pageContent
* Kegg page
* @return {@link MiriamType#PUBMED}s found on the page
* @param params
* List of {@link UserAnnotatorsParam} to be used
* for parameterization. Should contain only at most
* one record with space separated KEGG organisms names.
* If the value has not been set by the user,
* null will be passed.
* @return
* {@link MiriamType#PUBMED}s found on the page
*/
private Collection<MiriamData> parseKegg(String pageContent) {
private Collection<MiriamData> parseKegg(String pageContent, List<UserAnnotatorsParam> params) {
//Retrieve Pubmeds
Collection<MiriamData> result = new HashSet<MiriamData>();
......@@ -208,6 +219,23 @@ public class KeggAnnotator extends ElementAnnotator implements IExternalService
}
//Retrieve homologous organisms based on parameterization
if (params != null) {
String[] keggOrgnismCodes = params.get(0).getParamValue().trim().split(" +");
for (String code: keggOrgnismCodes) {
if (code.toUpperCase() != "ATH") {
logger.warn("KEGG annotator currently supports only ATH");
} else {
m = athOrthologMatcher.matcher(pageContent);
if (m.find()) {
String[] tairCodes = m.group(1).trim().split(" ");
for (String tairCode: tairCodes) {
tairCode = tairCode.split("\\(")[0]; //some codes are in the form AT1G08510(FATB)
result.add(createMiriamData(MiriamType.TAIR_LOCUS, tairCode));
}
}
}
}
}
return result;
}
......
......@@ -2,23 +2,15 @@ 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.util.Collection;
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;
......
......@@ -11,6 +11,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.After;
......@@ -27,6 +28,7 @@ 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;
import lcsb.mapviewer.model.user.UserAnnotatorsParam;
public class KeggAnnotatorTest extends AnnotationTestFunctions {
......@@ -71,7 +73,7 @@ public class KeggAnnotatorTest extends AnnotationTestFunctions {
@Test
public void testAnnotateFromUniprot() throws Exception {
public void testAnnotateFromUniprotWithoutParams() throws Exception {
try {
Species protein = new GenericProtein("id");
......@@ -89,6 +91,82 @@ public class KeggAnnotatorTest extends AnnotationTestFunctions {
}
}
@Test
public void testAnnotateFromUniprotWithParams() throws Exception {
try {
Species protein = new GenericProtein("id");
protein.setName("bla");
protein.addMiriamData(new MiriamData(MiriamType.UNIPROT, "Q42561"));
UserAnnotatorsParam ap = new UserAnnotatorsParam(String.class, "KEGG organism identifier", "ATH");
List<UserAnnotatorsParam> aps = new ArrayList<>();
aps.add(ap);
keggAnnotator.annotateElement(protein, aps);
int cntTairs = 0;
for (MiriamData md : protein.getMiriamData()) {
if (md.getDataType().equals(MiriamType.TAIR_LOCUS)) {
cntTairs++;
}
}
assertTrue("Invalid number of TAIR annotators from KEGG", cntTairs == 3);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testAnnotateFromUniprotWithWrongParams1() throws Exception {
try {
Species protein = new GenericProtein("id");
protein.setName("bla");
protein.addMiriamData(new MiriamData(MiriamType.UNIPROT, "Q42561"));
UserAnnotatorsParam ap = new UserAnnotatorsParam(String.class, "XXX", "XXX");
List<UserAnnotatorsParam> aps = new ArrayList<>();
aps.add(ap);
keggAnnotator.annotateElement(protein, aps);
assertEquals("There should be warning about unsupported parameter", 1, getWarnings().size());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testAnnotateFromUniprotWithWrongParams2() throws Exception {
try {
Species protein = new GenericProtein("id");
protein.setName("bla");
protein.addMiriamData(new MiriamData(MiriamType.UNIPROT, "Q42561"));
List<UserAnnotatorsParam> aps = new ArrayList<>();
aps.add(new UserAnnotatorsParam(String.class, "KEGG organism identifier", "ATH XXX"));
keggAnnotator.annotateElement(protein, aps);
int cntTairs = 0;
for (MiriamData md : protein.getMiriamData()) {
if (md.getDataType().equals(MiriamType.TAIR_LOCUS)) {
cntTairs++;
}
}
assertTrue("Invalid number of TAIR annotators from KEGG", cntTairs == 3);
assertEquals("There should be warning about unsupported parameter", 1, getWarnings().size());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testAnnotateFromEc() throws Exception {
try {
......@@ -101,7 +179,6 @@ public class KeggAnnotatorTest extends AnnotationTestFunctions {
Evaluate_3_1_2_14(protein);
} catch (Exception e) {
e.printStackTrace();
throw e;
......
......@@ -65,7 +65,8 @@ function onChangeParameterValue(element, user){
var annotatorsParams = {};
annotatorsParams[annotatorClassName] = {};
annotatorsParams[annotatorClassName][name] = element.value;
if (element.type == 'checkbox') annotatorsParams[annotatorClassName][name] = element.checked.toString();
else annotatorsParams[annotatorClassName][name] = element.value;
data.setAnnotatorsParameters(annotatorsParams);
return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert);
......@@ -95,6 +96,7 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) {
var selectedAnnotators = user.getPreferences().getElementAnnotators(elementType.className);
var existingAnnotatorsParameters = user.getPreferences().getAnnotatorsParameters();
for (var i = 0; i < annotators.length; i++) {
var annotator = annotators[i];
var selected = false;
......@@ -157,12 +159,14 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) {
inputType: "number",
onchange: function(){return onChangeParameterValue(this, user);}
});
if (existingParamValue) paramValue.value = existingParamValue;
} else if (param.type.indexOf("Boolean") >= 0) {
paramValue = Functions.createElement({
type: "input",
inputType: "checkbox",
onchange: function(){return onChangeParameterValue(this, user);}
});
paramValue.checked = (existingParamValue && existingParamValue === 'true');
} else {
throw new InvalidAlgorithmError("Unknown annotator parameter type");
}
......
......@@ -248,17 +248,12 @@ public class UserAnnotationSchema implements Serializable {
if (params.getAnnotatorClassName().equals(ap.getAnnotatorClassName()) &&
params.getParamName().equals(ap.getParamName())) {
this.annotatorsParams.get(i).setParamValue(ap.getParamValue());
} else {
ap.setAnnotationSchema(this);
this.annotatorsParams.add(ap);
return;
}
}
if (this.annotatorsParams.size() == 0) {
ap.setAnnotationSchema(this);
this.annotatorsParams.add(ap);
}
ap.setAnnotationSchema(this);
this.annotatorsParams.add(ap);
}
/**
......
......@@ -1469,7 +1469,16 @@ public class ProjectService implements IProjectService {
dbUser.setAnnotationSchema(annotationSchema);
}
return annotationSchema.getAnnotatorsParams();
/*
* Hibernate lazy loads collections so each element needs to be accessed
* to be loaded now or otherwise the data might not be available
* when accessed because the session might not be available at that time.
*/
List<UserAnnotatorsParam> aps = new ArrayList<>();
for (UserAnnotatorsParam ap: annotationSchema.getAnnotatorsParams()){
aps.add(ap);
}
return aps;
}
/**
......
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