Commit 357ad008 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch 'devel_12.1.x'

parents 5c9ba672 876c26db
minerva (12.0.0~beta.3) unstable; urgency=medium
* Feature: There is alternativa OpenLayers map engine available
* Feature: database connection configuration (login, password, host, etc)
can be modified using /etc/minerva/db.properties file
* Small improvement: multiple x-frame domains are allowed
* Small improvement: No duration of the text notification in overlay tab
* Bug fix: clicking on help button opened new window with every click
(that had to be closed separately)
* Bug fix: Legend doesn't disappear if image is wrong
* Bug fix: Resolution of exported .png in submaps
* Bug fix: Molstar tool in submaps
-- Piotr Gawron <piotr.gawron@uni.lu> Thu, 24 May 2018 13:00:00 +0200
minerva (12.0.0~beta.2) unstable; urgency=medium
* Bug fix: issues that appeared in 12.0.0~beta.1
......
......@@ -4,6 +4,8 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
......@@ -142,7 +144,7 @@ public final class Configuration {
/**
* Address that should be allowed to use x-frame.
*/
private static String xFrametDomain = null;
private static List<String> xFrametDomain = new ArrayList<>();
/**
* Directory where tomcat webapp folder is located. Default value is "." because
......@@ -360,17 +362,17 @@ public final class Configuration {
* @return the xFrametDomain
* @see #xFrametDomain
*/
public static String getxFrameDomain() {
public static List<String> getxFrameDomain() {
return xFrametDomain;
}
/**
* @param xFrametDomain
* @param xFrametDomains
* the xFrametDomain to set
* @see #xFrametDomain
*/
public static void setxFrameDomain(String xFrametDomain) {
Configuration.xFrametDomain = xFrametDomain;
public static void setxFrameDomain(List<String> xFrametDomains) {
Configuration.xFrametDomain = xFrametDomains;
}
/**
......
......@@ -6,6 +6,8 @@ import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.junit.After;
......@@ -66,7 +68,8 @@ public class ConfigurationTest extends CommonTestFunctions{
@Test
public void testXGetSystemVersion() {
String frame = "test";
List<String> frame = new ArrayList<>();
frame.add("test");
Configuration.setxFrameDomain(frame);
assertEquals(frame, Configuration.getxFrameDomain());
}
......
package lcsb.mapviewer.run;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.springframework.beans.factory.annotation.Autowired;
import lcsb.mapviewer.annotation.services.PubmedParser;
import lcsb.mapviewer.common.IProgressUpdater;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.converter.ConverterParams;
import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
import lcsb.mapviewer.model.map.model.Model;
import lcsb.mapviewer.model.map.reaction.Reaction;
import lcsb.mapviewer.persist.ApplicationContextLoader;
import lcsb.mapviewer.reactome.model.ReactomeDatabaseObject;
import lcsb.mapviewer.reactome.model.ReactomeLiteratureReference;
import lcsb.mapviewer.reactome.model.ReactomePublication;
import lcsb.mapviewer.reactome.model.ReactomeReactionlikeEvent;
import lcsb.mapviewer.reactome.model.ReactomeURL;
import lcsb.mapviewer.reactome.utils.DataSourceUpdater;
import lcsb.mapviewer.reactome.utils.PredictionResult;
import lcsb.mapviewer.reactome.utils.PredictionResult.PredictionStatus;
import lcsb.mapviewer.reactome.utils.ReactionComparator;
import lcsb.mapviewer.reactome.utils.ReactomeQueryUtil;
/**
* This class create a raport about data that might be added to PD-map based on
* reactome data and some text mining information.
*
* @author Piotr Gawron
*
*/
public class ReactomePrediction {
/**
* How many nodes in the reaction must match on both sides (reactome and ours)
* to consider reaction similar.
*/
private static final int PREDICTION_THRESHOLD = 3;
/**
* Number of nanoseconds in the second.
*/
private static final double NANOSECONDS_IN_SECOND = 1000000000.0;
/**
* Model used for generating raport.
*/
private Model model;
/**
* Local backend to the pubmed data.
*/
@Autowired
private PubmedParser pubmedParser;
/**
* Default class logger.
*/
private static Logger logger = Logger.getLogger(ReactomePrediction.class);
/**
* Comparator of reactions between our model and reactome.
*/
@Autowired
private ReactionComparator reactionComparator;
/**
* Class used for accessing reactome data.
*/
@Autowired
private DataSourceUpdater rc;
/**
* Util class used for manipulating information in reactome objects.
*/
@Autowired
private ReactomeQueryUtil rcu;
/**
* Static main method used to run this stand alone code.
*
* @param args
* command line arguments
*/
public static void main(String[] args) {
long startTime = System.nanoTime();
PropertyConfigurator.configure("src/main/webapp/WEB-INF/resources/log4j.properties");
ReactomePrediction main = new ReactomePrediction();
ApplicationContextLoader.loadApplicationContext("consoleApplicationContext.xml");
ApplicationContextLoader.injectDependencies(main);
main.run();
long endTime = System.nanoTime();
long duration = endTime - startTime;
double sec = duration / NANOSECONDS_IN_SECOND;
System.out.println("Duration: " + new DecimalFormat("#.###").format(sec) + "s");
}
/**
* Generates prediction report.
*/
public void run() {
try {
model = new CellDesignerXmlParser().createModel(new ConverterParams().filename(PdMapAnnotations.getLastPdFilename()));
Set<ReactomeReactionlikeEvent> reactions = new HashSet<ReactomeReactionlikeEvent>();
// problematic reaction with complex of complex of molecule
for (Reaction reaction : model.getReactions()) {
for (String stableIdentifier : rcu.getReactomeIdentifiersForReaction(reaction)) {
ReactomeDatabaseObject obj = rc.getFullObjectForStableIdentifier(stableIdentifier);
if (obj != null) {
if (obj instanceof ReactomeReactionlikeEvent) {
reactions.add((ReactomeReactionlikeEvent) obj);
}
}
}
}
List<String> pubmedIds = loadPubmedIds("testFiles/data_mining/pd_pmids.txt");
List<PredictionResult> newReaction = new ArrayList<PredictionResult>();
logger.debug("Structure analysis");
newReaction.addAll(rcu.getExtendedReactionsForKnownReactions(reactions, PREDICTION_THRESHOLD));
logger.debug("Data mining analysis");
newReaction.addAll(rcu.getExtendedReactionsForPubmedPublicationsWithTabuReaction(pubmedIds, reactions));
Collections.sort(newReaction, PredictionResult.SCORE_COMPARATOR);
printHeader();
for (PredictionResult prediction : newReaction) {
printResult(prediction);
}
printFooter(newReaction);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
/**
* Load pubmed identifiers from a file.
*
* @param fileName
* file with pubmed ids
* @return list of pubmed ids
* @throws IOException
* thrown when there are problems with a file
*/
private List<String> loadPubmedIds(String fileName) throws IOException {
List<String> result = new ArrayList<String>();
BufferedReader br = new BufferedReader(new FileReader(fileName));
try {
String line;
while ((line = br.readLine()) != null) {
result.add(line);
}
} finally {
br.close();
}
return result;
}
/**
* Prints report footer.
*
* @param results
* results used for generating report
*/
private void printFooter(Collection<PredictionResult> results) {
writer.println("</table>");
writer.println("Suggested reactions: " + results.size());
writer.println("</body></html>");
writer.close();
}
/**
* Object used for writing the report.
*/
private PrintWriter writer;
/**
* Creates stream for report output and prints report header.
*
* @throws FileNotFoundException
* thrown when file with the report cannot be found
* @throws UnsupportedEncodingException
* when there are problesm with encoding
*/
private void printHeader() throws FileNotFoundException, UnsupportedEncodingException {
writer = new PrintWriter("out/report/report-prediction.html", "UTF-8");
writer.println("<html><head></head><body>");
writer.println("<table cellspacing=\"0\">");
String resultString = "<tr>";
resultString += "<td" + style + ">Reaction</td>";
resultString += "<td" + style + ">REACTOME ID</td>";
resultString += "<td" + style + ">Status</td>";
resultString += "<td" + style + ">Score</td>";
resultString += "<td" + style + ">References:</td>";
resultString += "</tr>";
writer.println(resultString);
}
/**
* Formater used for decimals.
*/
private DecimalFormat df = new DecimalFormat("#.##");
/**
* Style used for result cell.
*/
private String style = " style=\"border-width:1;border-style:solid;border-color:#000000;\" ";
/**
* Prints one prediction row of the result.
*
* @param result
* prediction result
* @throws Exception
* thrown when there is a problem with printing
*/
private void printResult(PredictionResult result) throws Exception {
String color = "#FFFFFF";
String status = "";
if (PredictionStatus.STRUCTURE.equals(result.getStatus())) {
color = "#A2E037";
status = "STRUCTURE";
} else if (PredictionStatus.DATA_MINIG.equals(result.getStatus())) {
color = "#DDDDDD";
status = "DATA MINING";
} else {
logger.warn("Unknown type: " + result.getStatus());
}
String resultString = "<tr bgcolor = \"" + color + "\">";
resultString += "<td" + style + ">" + result.getReaction().getDisplayName() + "</td>";
String reactomId = result.getReaction().getStableIdentifier().getIdentifier() + "." + result.getReaction().getStableIdentifier().getIdentifierVersion();
resultString += "<td" + style + "><a target=\"_blank\" href=\"" + rcu.getReactomeUrlForStableIdentifier(reactomId) + "\">" + reactomId + "</a></td>";
resultString += "<td" + style + ">" + status + "</td>";
resultString += "<td" + style + ">" + df.format(result.getScore() * IProgressUpdater.MAX_PROGRESS) + "%</td>";
resultString += "<td" + style + ">";
for (ReactomePublication reference : result.getReaction().getLiteratureReferences()) {
if (reference instanceof ReactomeLiteratureReference) {
resultString += pubmedParser.getHtmlFullLinkForId(((ReactomeLiteratureReference) reference).getPubMedIdentifier());
} else if (reference instanceof ReactomeURL) {
resultString += reference.getTitle() + "; " + ((ReactomeURL) reference).getUniformResourceLocator();
} else {
throw new InvalidArgumentException("Unknown clas type: " + reference.getClass());
}
}
resultString += "</td>";
resultString += "</tr>";
writer.println(resultString);
System.out.println(resultString);
}
/**
* @return the pubmedParser
*/
public PubmedParser getPubmedParser() {
return pubmedParser;
}
/**
* @param pubmedParser
* the pubmedParser to set
*/
public void setPubmedParser(PubmedParser pubmedParser) {
this.pubmedParser = pubmedParser;
}
/**
* @return the reactionComparator
*/
public ReactionComparator getReactionComparator() {
return reactionComparator;
}
/**
* @param reactionComparator
* the reactionComparator to set
*/
public void setReactionComparator(ReactionComparator reactionComparator) {
this.reactionComparator = reactionComparator;
}
/**
* @return the rc
* @see #rc
*/
public DataSourceUpdater getRc() {
return rc;
}
/**
* @param rc
* the rc to set
* @see #rc
*/
public void setRc(DataSourceUpdater rc) {
this.rc = rc;
}
/**
* @return the rcu
* @see #rcu
*/
public ReactomeQueryUtil getRcu() {
return rcu;
}
/**
* @param rcu
* the rcu to set
* @see #rcu
*/
public void setRcu(ReactomeQueryUtil rcu) {
this.rcu = rcu;
}
}
......@@ -23,13 +23,11 @@ import org.apache.log4j.Logger;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.common.exception.InvalidClassException;
import lcsb.mapviewer.common.exception.NotImplementedException;
import lcsb.mapviewer.converter.zip.DataMiningZipEntryFile;
import lcsb.mapviewer.converter.zip.ImageZipEntryFile;
import lcsb.mapviewer.converter.zip.LayoutZipEntryFile;
import lcsb.mapviewer.converter.zip.ModelZipEntryFile;
import lcsb.mapviewer.converter.zip.ZipEntryFile;
import lcsb.mapviewer.model.cache.UploadedFileEntry;
import lcsb.mapviewer.model.map.graph.DataMiningSet;
import lcsb.mapviewer.model.map.layout.Layout;
import lcsb.mapviewer.model.map.model.ElementSubmodelConnection;
import lcsb.mapviewer.model.map.model.Model;
......@@ -110,7 +108,6 @@ public class ComplexZipConverter {
Model result = null;
int overlayOrder = 1;
List<Layout> layouts = new ArrayList<>();
List<DataMiningSet> dataMiningSets = new ArrayList<>();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
......@@ -132,16 +129,12 @@ public class ComplexZipConverter {
} else if (zef instanceof ImageZipEntryFile) {
continue;
// imageEntries.add((ImageZipEntryFile) zef);
} else if (zef instanceof DataMiningZipEntryFile) {
dataMiningSets.add(dataMiningZipEntryToDataMiningSet(zipFile, entry, (DataMiningZipEntryFile) zef));
} else if (!isIgnoredFile(entry.getName())) {
throw new NotImplementedException("Unknwon entry type: " + zef.getClass());
}
}
}
result.addDataMiningSets(dataMiningSets);
for (Entry<String, Model> entry : filenameModelMap.entrySet()) {
String filename = entry.getKey();
Model model = entry.getValue();
......@@ -330,30 +323,6 @@ public class ComplexZipConverter {
return mapping;
}
/**
* Transforms {@link DataMiningZipEntryFile} into {@link DataMiningSet}.
*
* @param zipFile
* original {@link ZipFile}
* @param entry
* entry in a zip file
* @param dmEntry
* {@link DataMiningZipEntryFile} to transform
* @return {@link DataMiningSet} for a given {@link DataMiningZipEntryFile}
* @throws IOException
* thrown when there is a problem with accessing {@link ZipFile}
*/
protected DataMiningSet dataMiningZipEntryToDataMiningSet(ZipFile zipFile, ZipEntry entry,
DataMiningZipEntryFile dmEntry) throws IOException {
DataMiningSet dmSet = new DataMiningSet();
dmSet.setName(dmEntry.getName());
dmSet.setInputData(IOUtils.toByteArray(zipFile.getInputStream(entry)));
dmSet.setDescription(dmEntry.getDescription());
dmSet.setSource(dmEntry.getSource());
dmSet.setType(dmEntry.getType());
return dmSet;
}
/**
* Transforms {@link LayoutZipEntryFile} into {@link Layout}.
*
......
package lcsb.mapviewer.converter.zip;
import java.io.Serializable;
import lcsb.mapviewer.model.map.graph.DataMiningType;
/**
* Structure used to describe a file in zip archive about
* {@link lcsb.mapviewer.model.map.graph.DataMiningSet} files.
*
* @author Piotr Gawron
*
*/
public class DataMiningZipEntryFile extends ZipEntryFile implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Link to the source page.
*/
private String source;
/**
* Name of the data set.
*/
private String name;
/**
* Description of the data set.
*/
private String description;
/**
* Type of the data set.
*/
private DataMiningType type;
/**
* Default constructor.
*/
public DataMiningZipEntryFile() {
}
/**
* Default constructor.
*
* @param filename
* name of the file
*/
public DataMiningZipEntryFile(String filename) {
super(filename);
}
/**
* @return the description
* @see #description
*/
public String getDescription() {
return description;
}
/**
* @param description
* the description to set
* @see #description
*/
public void setDescription(String description) {
this.description = description;
}
/**
* @return the type
* @see #type
*/
public DataMiningType getType() {
return type;
}
/**
* @param type
* the type to set
* @see #type
*/
public void setType(DataMiningType type) {
this.type = type;
}
/**
* @return the source
* @see #source
*/
public String getSource() {
return source;
}
/**
* @param source
* the source to set
* @see #source