Skip to content
Snippets Groups Projects
Commit 3ae8a0a3 authored by Philipp Spohr's avatar Philipp Spohr
Browse files

-Improved Meta-Graph performance

-Fixed bug using ILP when selecting heuristic mode
-Fixed bug with discarding solution sometimes not removing subgraphs/metagraph
-Fixed bug with infinite gap values being formatted incorrectly
-Enabled highlighting of clusters in meta-graph
-Enabled returning to original network view upon result destruction
-Fixed bugs with cluster-view sometimes using incorrect styles/layout
-Reworked concurrency / synchronization
-Various smaller performance issues
parent 740d75e6
Branches
Tags
No related merge requests found
Showing
with 260 additions and 136 deletions
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
<groupId>de.hhu.ba</groupId> <groupId>de.hhu.ba</groupId>
<artifactId>yoshikoWrapper</artifactId> <artifactId>yoshikoWrapper</artifactId>
<version>0.1.2</version> <version>0.1.3</version>
<name>YoshikoWrapper</name> <name>YoshikoWrapper</name>
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
******************************************************************************/ ******************************************************************************/
package de.hhu.ba.yoshikoWrapper.core; package de.hhu.ba.yoshikoWrapper.core;
import java.util.concurrent.CountDownLatch;
import org.cytoscape.application.CyApplicationManager; import org.cytoscape.application.CyApplicationManager;
import org.cytoscape.application.swing.CySwingApplication; import org.cytoscape.application.swing.CySwingApplication;
import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNetwork;
...@@ -36,6 +38,10 @@ import org.cytoscape.view.presentation.RenderingEngineFactory; ...@@ -36,6 +38,10 @@ import org.cytoscape.view.presentation.RenderingEngineFactory;
import org.cytoscape.view.vizmap.VisualMappingFunctionFactory; import org.cytoscape.view.vizmap.VisualMappingFunctionFactory;
import org.cytoscape.view.vizmap.VisualMappingManager; import org.cytoscape.view.vizmap.VisualMappingManager;
import org.cytoscape.view.vizmap.VisualStyleFactory; import org.cytoscape.view.vizmap.VisualStyleFactory;
import org.cytoscape.work.FinishStatus;
import org.cytoscape.work.ObservableTask;
import org.cytoscape.work.TaskIterator;
import org.cytoscape.work.TaskObserver;
import org.cytoscape.work.swing.DialogTaskManager; import org.cytoscape.work.swing.DialogTaskManager;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
...@@ -68,4 +74,25 @@ public class CyCore { ...@@ -68,4 +74,25 @@ public class CyCore {
public static String getConfig(String key) { public static String getConfig(String key) {
return cm.getProperties().getProperty(key); return cm.getProperties().getProperty(key);
} }
/**
* Convenience function that runs all tasks in a task iterator but blocks until all tasks are finished
* @param taskIterator
* @throws InterruptedException
*/
public static synchronized void runAndWait(TaskIterator taskIterator) throws InterruptedException {
CountDownLatch blockLatch = new CountDownLatch(1);
dialogTaskManager.execute(taskIterator,new TaskObserver() {
@Override
public void taskFinished(ObservableTask task) {}
@Override
public void allFinished(FinishStatus finishStatus) {
blockLatch.countDown();
}
});
blockLatch.await();
}
} }
...@@ -44,9 +44,11 @@ public class StatusInformer extends CplexInformer { ...@@ -44,9 +44,11 @@ public class StatusInformer extends CplexInformer {
@Override @Override
public void updateStatus(YoshikoState state, double value) { public void updateStatus(YoshikoState state, double value) {
if (state == YoshikoState.SOLVING_ILP){ if (state == YoshikoState.SOLVING_ILP){
if (value <= 1.0) {
taskMonitor.setStatusMessage(LocalizationManager.get("currentGap")+": "+SwingUtil.twoDecimals.format(value)+"%"); taskMonitor.setStatusMessage(LocalizationManager.get("currentGap")+": "+SwingUtil.twoDecimals.format(value)+"%");
} }
} }
}
@Override @Override
public void updateStatus(YoshikoState state) { public void updateStatus(YoshikoState state) {
......
package de.hhu.ba.yoshikoWrapper.core; package de.hhu.ba.yoshikoWrapper.core;
import org.osgi.framework.Version; import org.osgi.framework.Version;
public class YoshUtil { public class YoshUtil {
......
...@@ -28,7 +28,6 @@ import java.util.List; ...@@ -28,7 +28,6 @@ import java.util.List;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import org.cytoscape.model.CyEdge; import org.cytoscape.model.CyEdge;
import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNetwork;
...@@ -39,9 +38,10 @@ import org.cytoscape.model.subnetwork.CySubNetwork; ...@@ -39,9 +38,10 @@ import org.cytoscape.model.subnetwork.CySubNetwork;
import org.cytoscape.view.layout.CyLayoutAlgorithm; import org.cytoscape.view.layout.CyLayoutAlgorithm;
import org.cytoscape.view.model.CyNetworkView; import org.cytoscape.view.model.CyNetworkView;
import org.cytoscape.view.presentation.RenderingEngine; import org.cytoscape.view.presentation.RenderingEngine;
import org.cytoscape.work.Task; import org.cytoscape.work.FinishStatus;
import org.cytoscape.work.ObservableTask;
import org.cytoscape.work.TaskIterator; import org.cytoscape.work.TaskIterator;
import org.cytoscape.work.TaskMonitor; import org.cytoscape.work.TaskObserver;
import org.slf4j.Logger; import org.slf4j.Logger;
import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.CyCore;
...@@ -61,6 +61,9 @@ public class YoshikoCluster { ...@@ -61,6 +61,9 @@ public class YoshikoCluster {
private Image img; private Image img;
private CySubNetwork subnet;
//SYMBOLIC LINKS //SYMBOLIC LINKS
private final YoshikoSolution solution; private final YoshikoSolution solution;
private Logger logger = YoshikoLogger.getInstance().getLogger(); private Logger logger = YoshikoLogger.getInstance().getLogger();
...@@ -90,19 +93,21 @@ public class YoshikoCluster { ...@@ -90,19 +93,21 @@ public class YoshikoCluster {
} }
/** /**
* Generates a subgraph for this cluster by choosing the nodes and induced edges from the original graph * Generates a subgraph for this clusters by choosing the nodes and induced edges from the original graph if such a graph doesn't exist yet.
* @return * @return
*/ */
public CySubNetwork getSubNetwork() { public CySubNetwork getSubNetwork() {
if (subnet == null) {
CyRootNetwork originalGraphAsRoot = CyRootNetwork originalGraphAsRoot =
CyCore.rootNetworkManager.getRootNetwork(solution.getOriginalGraph()); CyCore.rootNetworkManager.getRootNetwork(solution.getOriginalGraph());
//Create nested graph and cluster subnet //Create nested graph and clusters subnet
ArrayList<CyEdge> inducedEdges = new ArrayList<CyEdge>(); ArrayList<CyEdge> inducedEdges = new ArrayList<CyEdge>();
for (CyNode n: nodes) { for (CyNode n: nodes) {
//Sadly Cytoscape doesnt provide a comfort function here //Sadly Cytoscape doesnt provide a comfort function here
List<CyEdge> adjacentEdges = solution.getOriginalGraph().getAdjacentEdgeList(n, CyEdge.Type.ANY); List<CyEdge> adjacentEdges = solution.getOriginalGraph().getAdjacentEdgeList(n, CyEdge.Type.ANY);
for (CyEdge e: adjacentEdges) { for (CyEdge e: adjacentEdges) {
if (nodes.contains(e.getSource()) && nodes.contains(e.getTarget())) { if (nodes.contains(e.getSource()) && nodes.contains(e.getTarget())) {
inducedEdges.add(e); inducedEdges.add(e);
...@@ -110,23 +115,32 @@ public class YoshikoCluster { ...@@ -110,23 +115,32 @@ public class YoshikoCluster {
} }
} }
CySubNetwork subnet = originalGraphAsRoot.addSubNetwork(nodes ,inducedEdges); subnet = originalGraphAsRoot.addSubNetwork(nodes ,inducedEdges);
subnet.getRow(subnet).set(CyNetwork.NAME, LocalizationManager.get("clusters")+" "+(id+1));
subnet.getRow(subnet).set(CyNetwork.NAME, LocalizationManager.get("cluster")+" "+(id+1)); }
return subnet; return subnet;
} }
public void highlight() {
if (CyCore.cy.getCurrentNetwork() == solution.getOriginalGraph()) {
highlightInOriginalGraph();
}
else if (CyCore.cy.getCurrentNetwork() == solution.getMetaGraph()) {
solution.highlightInMetaGraph(this);
}
}
/** /**
* Attempt to select the nodes belonging to this cluster in the original Graph given that they still exist * Attempt to select the nodes belonging to this clusters in the original Graph given that they still exist
*/ */
public void highlightInOriginalGraph() { private void highlightInOriginalGraph() {
try { try {
List<CyRow> allRows = solution.getOriginalGraph().getDefaultNodeTable().getAllRows(); List<CyRow> allRows = solution.getOriginalGraph().getDefaultNodeTable().getAllRows();
for (CyRow r: allRows) { for (CyRow r: allRows) {
r.set("selected", false); r.set("selected", false);
} }
//Select nodes corresponding to the cluster //Select nodes corresponding to the clusters
for (CyNode n : nodes) { for (CyNode n : nodes) {
solution.getOriginalGraph().getRow(n).set("selected", true); solution.getOriginalGraph().getRow(n).set("selected", true);
} }
...@@ -136,37 +150,19 @@ public class YoshikoCluster { ...@@ -136,37 +150,19 @@ public class YoshikoCluster {
} }
} }
public void generateClusterIcon(int width, int height,JLabel label) throws InterruptedException {
public void applyImage(JLabel label, int width, int height) throws Exception {
if (img != null) {
label.setIcon(new ImageIcon(img));
}
else {
getImage(width,height,label);
}
}
private void getImage(int width, int height,JLabel label) {
final CyNetworkView view = CyCore.networkViewFactory.createNetworkView(getSubNetwork()); final CyNetworkView view = CyCore.networkViewFactory.createNetworkView(getSubNetwork());
//layout cluster //layout clusters
final CyLayoutAlgorithm layout = CyCore.layoutAlgorithmManager.getDefaultLayout(); final CyLayoutAlgorithm layout = CyCore.layoutAlgorithmManager.getDefaultLayout();
final TaskIterator createLayout = layout.createTaskIterator( CyCore.runAndWait(layout.createTaskIterator(
view, view,
layout.getDefaultLayoutContext(), layout.getDefaultLayoutContext(),
CyLayoutAlgorithm.ALL_NODE_VIEWS, CyLayoutAlgorithm.ALL_NODE_VIEWS,
null null
)
); );
createLayout.append(
new Task() {
@Override
public void run(TaskMonitor taskMonitor) throws Exception {
taskMonitor.setStatusMessage("Generating cluster view for C:"+id);
view.setVisualProperty(NETWORK_WIDTH, new Double(width)); view.setVisualProperty(NETWORK_WIDTH, new Double(width));
view.setVisualProperty(NETWORK_HEIGHT, new Double(height)); view.setVisualProperty(NETWORK_HEIGHT, new Double(height));
view.fitContent(); view.fitContent();
...@@ -174,29 +170,18 @@ public class YoshikoCluster { ...@@ -174,29 +170,18 @@ public class YoshikoCluster {
StyleManager.style(view, CyCore.visualMappingManager.getCurrentVisualStyle()); StyleManager.style(view, CyCore.visualMappingManager.getCurrentVisualStyle());
RenderingEngine<CyNetwork> renderingEngine = CyCore.renderingEngineFactory.createRenderingEngine(label, view); RenderingEngine<CyNetwork> renderingEngine = CyCore.renderingEngineFactory.createRenderingEngine(label, view);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
img = renderingEngine.createImage(width,height); img = renderingEngine.createImage(width,height);
label.setIcon(new ImageIcon(img)); label.setIcon(new ImageIcon(img));
renderingEngine.dispose(); renderingEngine.dispose();
view.dispose(); view.dispose();
} }
}); public void delete() {
if (subnet != null) {
CyCore.networkManager.destroyNetwork(subnet);
} }
@Override
public void cancel() {}
}
);
CyCore.dialogTaskManager.execute(
createLayout
);
} }
public int getSize() { public int getSize() {
...@@ -215,4 +200,8 @@ public class YoshikoCluster { ...@@ -215,4 +200,8 @@ public class YoshikoCluster {
return solution.getOriginalGraph().getRow(n).get("name", String.class); return solution.getOriginalGraph().getRow(n).get("name", String.class);
} }
} }
...@@ -71,5 +71,11 @@ public class YoshikoResult { ...@@ -71,5 +71,11 @@ public class YoshikoResult {
return originalGraph; return originalGraph;
} }
public void delete() {
for (YoshikoSolution s: solutions) {
s.delete();
}
}
} }
...@@ -22,19 +22,36 @@ ...@@ -22,19 +22,36 @@
package de.hhu.ba.yoshikoWrapper.graphModel; package de.hhu.ba.yoshikoWrapper.graphModel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.swing.JOptionPane;
import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNetwork;
import org.cytoscape.model.CyNode;
import org.cytoscape.model.CyRow;
import org.slf4j.Logger;
import de.hhu.ba.yoshikoWrapper.core.CyCore;
import de.hhu.ba.yoshikoWrapper.logging.YoshikoLogger;
public class YoshikoSolution { public class YoshikoSolution {
private final YoshikoResult result; private final YoshikoResult result;
public ArrayList<YoshikoCluster> cluster; private CyNetwork metaGraph;
private HashMap<YoshikoCluster, CyNode> metaGraphMap;
public ArrayList<YoshikoCluster> clusters;
private final long id; private final long id;
private Logger logger = YoshikoLogger.getInstance().getLogger();
public YoshikoSolution(YoshikoResult yoshikoResult, long id) { public YoshikoSolution(YoshikoResult yoshikoResult, long id) {
cluster = new ArrayList<YoshikoCluster>(); clusters = new ArrayList<YoshikoCluster>();
this.result = yoshikoResult; this.result = yoshikoResult;
this.id = id; this.id = id;
} }
...@@ -42,7 +59,7 @@ public class YoshikoSolution { ...@@ -42,7 +59,7 @@ public class YoshikoSolution {
//_____________GETTER / SETTER ________________// //_____________GETTER / SETTER ________________//
public ArrayList<YoshikoCluster> getClusters() { public ArrayList<YoshikoCluster> getClusters() {
return cluster; return clusters;
} }
/** /**
...@@ -56,4 +73,37 @@ public class YoshikoSolution { ...@@ -56,4 +73,37 @@ public class YoshikoSolution {
return result.getOriginalGraph(); return result.getOriginalGraph();
} }
public void delete() {
for (YoshikoCluster c: clusters) {
c.delete();
}
if (this.metaGraph != null) {
CyCore.networkManager.destroyNetwork(metaGraph);
}
}
public void setMetaGraph(CyNetwork metaGraph, HashMap<YoshikoCluster, CyNode> map) {
this.metaGraph = metaGraph;
this.metaGraphMap = map;
}
public CyNetwork getMetaGraph() {
return metaGraph;
}
public void highlightInMetaGraph(YoshikoCluster yoshikoCluster) {
try {
List<CyRow> allRows = metaGraph.getDefaultNodeTable().getAllRows();
for (CyRow r: allRows) {
r.set("selected", false);
}
metaGraph.getRow(metaGraphMap.get(yoshikoCluster)).set("selected", true);
}
catch (Exception e) {
logger.warn("The graph doesn't exist anymore, can't highlight nodes!");
}
}
} }
...@@ -42,6 +42,7 @@ import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; ...@@ -42,6 +42,7 @@ import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster;
import de.hhu.ba.yoshikoWrapper.swing.GraphicsLoader; import de.hhu.ba.yoshikoWrapper.swing.GraphicsLoader;
import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; import de.hhu.ba.yoshikoWrapper.swing.SwingUtil;
import de.hhu.ba.yoshikoWrapper.tasks.AlgorithmTask;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class ClusterView extends JPanel { public class ClusterView extends JPanel {
...@@ -76,17 +77,17 @@ public class ClusterView extends JPanel { ...@@ -76,17 +77,17 @@ public class ClusterView extends JPanel {
//Swing init //Swing init
title = new JLabel(LocalizationManager.get("cluster")+" "+(c.getID()+1)); title = new JLabel(LocalizationManager.get("clusters")+" "+(c.getID()+1));
clusterSize = new JLabel(LocalizationManager.get("clusterSize")+" "+c.getSize()); clusterSize = new JLabel(LocalizationManager.get("clusterSize")+" "+c.getSize());
icon = new JLabel(); icon = new JLabel();
//icon.setBorder(BorderFactory.createLineBorder(Color.BLACK)); //icon.setBorder(BorderFactory.createLineBorder(Color.BLACK));
cluster.applyImage(icon,CLUSTER_ICON_SIZE, CLUSTER_ICON_SIZE); cluster.generateClusterIcon(CLUSTER_ICON_SIZE, CLUSTER_ICON_SIZE,icon);
SwingUtil.addAll(this,title,clusterSize,icon); SwingUtil.addAll(this,title,clusterSize,icon);
nodeList = new BasicCollapsiblePanel(LocalizationManager.get("nodes")); nodeList = new BasicCollapsiblePanel(LocalizationManager.get("nodes"));
//Loop over nodes in the cluster and add them to the view //Loop over nodes in the clusters and add them to the view
for (CyNode n : c.getSubNetwork().getNodeList()) { for (CyNode n : c.getSubNetwork().getNodeList()) {
nodeList.add( nodeList.add(
new JLabel( new JLabel(
...@@ -147,7 +148,7 @@ public class ClusterView extends JPanel { ...@@ -147,7 +148,7 @@ public class ClusterView extends JPanel {
@Override @Override
public void mouseEntered(MouseEvent e) { public void mouseEntered(MouseEvent e) {
cluster.highlightInOriginalGraph(); cluster.highlight();
setBorder(isSelected ? selectedBorder : highlightBorder); setBorder(isSelected ? selectedBorder : highlightBorder);
} }
......
...@@ -25,9 +25,11 @@ import static javax.swing.GroupLayout.*; ...@@ -25,9 +25,11 @@ import static javax.swing.GroupLayout.*;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties; import java.util.Properties;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
...@@ -58,6 +60,7 @@ import org.cytoscape.model.events.AddedNodesListener; ...@@ -58,6 +60,7 @@ import org.cytoscape.model.events.AddedNodesListener;
import org.cytoscape.model.events.NetworkAboutToBeDestroyedEvent; import org.cytoscape.model.events.NetworkAboutToBeDestroyedEvent;
import org.cytoscape.model.events.NetworkAboutToBeDestroyedListener; import org.cytoscape.model.events.NetworkAboutToBeDestroyedListener;
import org.cytoscape.util.swing.BasicCollapsiblePanel; import org.cytoscape.util.swing.BasicCollapsiblePanel;
import org.cytoscape.view.model.CyNetworkView;
import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.CyCore;
import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
...@@ -123,11 +126,16 @@ NetworkAboutToBeDestroyedListener ...@@ -123,11 +126,16 @@ NetworkAboutToBeDestroyedListener
solutionTabs.add(tab); solutionTabs.add(tab);
} }
marker = new BasicCollapsiblePanel(LocalizationManager.get("solutionMarker"));
marker.setLayout(new BoxLayout(marker,BoxLayout.Y_AXIS));
JLabel costLabel = new JLabel(LocalizationManager.get("cost")+" "+result.getFlags().getTotalCost());
marker.add(costLabel);
if (result.getFlags().getIlpGenerated()) { if (result.getFlags().getIlpGenerated()) {
//TODO: Move to MarkerPanel for better codestyle //TODO: Move to MarkerPanel for better codestyle
//Optional Markers //Optional Markers
marker = new BasicCollapsiblePanel(LocalizationManager.get("ilpMarker"));
marker.setLayout(new BoxLayout(marker,BoxLayout.Y_AXIS));
if(result.getFlags().getOptimal()) { if(result.getFlags().getOptimal()) {
JLabel optimalLabel; JLabel optimalLabel;
optimalLabel = new JLabel(LocalizationManager.get("optimal")); optimalLabel = new JLabel(LocalizationManager.get("optimal"));
...@@ -142,15 +150,15 @@ NetworkAboutToBeDestroyedListener ...@@ -142,15 +150,15 @@ NetworkAboutToBeDestroyedListener
marker.add(new JLabel(result.getFlags().getSolvedInstances()+"/"+result.getFlags().getReducedInstances()+" "+LocalizationManager.get("redSolved"))); marker.add(new JLabel(result.getFlags().getSolvedInstances()+"/"+result.getFlags().getReducedInstances()+" "+LocalizationManager.get("redSolved")));
marker.add(new JLabel(LocalizationManager.get("lastInstanceGap")+" "+(int)(100*result.getFlags().getLastGap())+"%")); marker.add(new JLabel(LocalizationManager.get("lastInstanceGap")+" "+(int)(100*result.getFlags().getLastGap())+"%"));
} }
JLabel costLabel = new JLabel(LocalizationManager.get("cost")+" "+result.getFlags().getTotalCost());
marker.add(costLabel);
if (result.getFlags().getTimedOut()) { if (result.getFlags().getTimedOut()) {
marker.add(new JLabel(LocalizationManager.get("timeoutMarker"))); marker.add(new JLabel(LocalizationManager.get("timeoutMarker")));
} }
marker.setCollapsed(false); marker.setCollapsed(false);
this.add(marker);
} }
this.add(marker);
destroyButton = new JButton(LocalizationManager.get("discardSolution")); destroyButton = new JButton(LocalizationManager.get("discardSolution"));
destroyButton.addActionListener(new ActionListener() { destroyButton.addActionListener(new ActionListener() {
...@@ -172,16 +180,13 @@ NetworkAboutToBeDestroyedListener ...@@ -172,16 +180,13 @@ NetworkAboutToBeDestroyedListener
layout.setHorizontalGroup(horizontalGroup); layout.setHorizontalGroup(horizontalGroup);
layout.setVerticalGroup(verticalGroup); layout.setVerticalGroup(verticalGroup);
if (result.getFlags().getIlpGenerated()) {
horizontalGroup.addComponent(marker,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE);
verticalGroup.addComponent(marker,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE);
}
horizontalGroup horizontalGroup
.addComponent(marker,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE)
.addComponent(invalidLabel,DEFAULT_SIZE, PREFERRED_SIZE,Short.MAX_VALUE) .addComponent(invalidLabel,DEFAULT_SIZE, PREFERRED_SIZE,Short.MAX_VALUE)
.addComponent(tabbedPane,HACKFIX_FIXED_WIDTH, PREFERRED_SIZE,Short.MAX_VALUE) .addComponent(tabbedPane,HACKFIX_FIXED_WIDTH, PREFERRED_SIZE,Short.MAX_VALUE)
.addComponent(destroyButton,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE); .addComponent(destroyButton,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE);
verticalGroup verticalGroup
.addComponent(marker,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE)
.addComponent(invalidLabel,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE) .addComponent(invalidLabel,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE)
.addComponent(tabbedPane,DEFAULT_SIZE, DEFAULT_SIZE,PREFERRED_SIZE) .addComponent(tabbedPane,DEFAULT_SIZE, DEFAULT_SIZE,PREFERRED_SIZE)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, DEFAULT_SIZE, Short.MAX_VALUE)
...@@ -190,6 +195,8 @@ NetworkAboutToBeDestroyedListener ...@@ -190,6 +195,8 @@ NetworkAboutToBeDestroyedListener
layout.setAutoCreateGaps(true); layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true); layout.setAutoCreateContainerGaps(true);
//SWING BLACK MAGIC FOR ADEPTS
this.setMinimumSize(new Dimension(HACKFIX_FIXED_WIDTH,this.getMinimumSize().height));
this.setLayout(layout); this.setLayout(layout);
...@@ -206,6 +213,7 @@ NetworkAboutToBeDestroyedListener ...@@ -206,6 +213,7 @@ NetworkAboutToBeDestroyedListener
} }
public void deleteSolution() { public void deleteSolution() {
int dialogResult = JOptionPane.showConfirmDialog ( int dialogResult = JOptionPane.showConfirmDialog (
null, null,
LocalizationManager.get("deleteSolution"), LocalizationManager.get("deleteSolution"),
...@@ -215,9 +223,19 @@ NetworkAboutToBeDestroyedListener ...@@ -215,9 +223,19 @@ NetworkAboutToBeDestroyedListener
if (dialogResult != JOptionPane.YES_OPTION) { if (dialogResult != JOptionPane.YES_OPTION) {
return; return;
} }
//Restore view
if (result.getOriginalGraph() != null) {
Collection<CyNetworkView> viewsToReturn = CyCore.networkViewManager.getNetworkViews(result.getOriginalGraph());
if (!viewsToReturn.isEmpty()) {
CyCore.cy.setCurrentNetworkView(viewsToReturn.iterator().next());
}
}
CyCore.registrar.unregisterService(this,CytoPanelComponent.class); CyCore.registrar.unregisterService(this,CytoPanelComponent.class);
removeAll(); result.delete();
super.setVisible(false); super.setVisible(false);
} }
private void invalidateResult() { private void invalidateResult() {
......
...@@ -86,14 +86,14 @@ public class SolutionTab extends JPanel { ...@@ -86,14 +86,14 @@ public class SolutionTab extends JPanel {
//Declaration of Swing Components //Declaration of Swing Components
clusterViewList = new ClusterViewList(); clusterViewList = new ClusterViewList();
for (YoshikoCluster c: solution.cluster) { for (YoshikoCluster c: solution.clusters) {
ClusterView clusterView = new ClusterView(c); ClusterView clusterView = new ClusterView(c);
clusterViewList.add(clusterView); clusterViewList.add(clusterView);
} }
scrollPane = new JScrollPane(clusterViewList); scrollPane = new JScrollPane(clusterViewList);
clusterCount = new JLabel(LocalizationManager.get("clusterFound")+" "+s.cluster.size()); clusterCount = new JLabel(LocalizationManager.get("clusterFound")+" "+s.clusters.size());
createClusterView = new JButton(LocalizationManager.get("createClusterView")); createClusterView = new JButton(LocalizationManager.get("createClusterView"));
createMetaGraph = new JButton(LocalizationManager.get("createMetaGraph")); createMetaGraph = new JButton(LocalizationManager.get("createMetaGraph"));
...@@ -170,7 +170,7 @@ public class SolutionTab extends JPanel { ...@@ -170,7 +170,7 @@ public class SolutionTab extends JPanel {
.addGap(8) .addGap(8)
.addComponent(clusterCount,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) .addComponent(clusterCount,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE)
.addGap(8) .addGap(8)
.addComponent(scrollPane,PREFERRED_SIZE,DEFAULT_SIZE,Short.MAX_VALUE) .addComponent(scrollPane,DEFAULT_SIZE,DEFAULT_SIZE,Short.MAX_VALUE)
.addComponent(createClusterView,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) .addComponent(createClusterView,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE)
.addComponent(createMetaGraph,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) .addComponent(createMetaGraph,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE)
); );
......
...@@ -71,7 +71,7 @@ public class AlgorithmTask extends AbstractTask { ...@@ -71,7 +71,7 @@ public class AlgorithmTask extends AbstractTask {
private ResultPanel resultPanel; private ResultPanel resultPanel;
public AlgorithmTask(// <<< Too many variables here, some should be grouped later TODO: public AlgorithmTask(
Window statusWindow, Window statusWindow,
CyNetwork net, CyNetwork net,
ParameterSet parameterSet ParameterSet parameterSet
...@@ -85,6 +85,7 @@ public class AlgorithmTask extends AbstractTask { ...@@ -85,6 +85,7 @@ public class AlgorithmTask extends AbstractTask {
@Override @Override
public void run(TaskMonitor taskMonitor) throws Exception { public void run(TaskMonitor taskMonitor) throws Exception {
//TODO: Improve setProgress values
taskMonitor.setTitle(LocalizationManager.get("yoshTask")); taskMonitor.setTitle(LocalizationManager.get("yoshTask"));
taskMonitor.setProgress(0.0); taskMonitor.setProgress(0.0);
...@@ -127,9 +128,9 @@ public class AlgorithmTask extends AbstractTask { ...@@ -127,9 +128,9 @@ public class AlgorithmTask extends AbstractTask {
parameterSet.solCount, parameterSet.solCount,
parameterSet.reductionRulesBitMask, parameterSet.reductionRulesBitMask,
parameterSet.snrMultFactor, parameterSet.snrMultFactor,
parameterSet.useHeuristic,
parameterSet.usePartitionCuts, parameterSet.usePartitionCuts,
parameterSet.useTriangleCuts, parameterSet.useTriangleCuts
parameterSet.useHeuristic
); );
...@@ -162,30 +163,30 @@ public class AlgorithmTask extends AbstractTask { ...@@ -162,30 +163,30 @@ public class AlgorithmTask extends AbstractTask {
//Fetch number of clusters in the solution //Fetch number of clusters in the solution
long numberOfClusters = result.getNumberOfClusters(i); long numberOfClusters = result.getNumberOfClusters(i);
//Loop over cluster //Loop over clusters
for (long k=0;k<numberOfClusters;k++) { for (long k=0;k<numberOfClusters;k++) {
//Create java instance //Create java instance
YoshikoCluster cluster = new YoshikoCluster(solution,k); YoshikoCluster cluster = new YoshikoCluster(solution,k);
taskMonitor.setStatusMessage("Processing cluster "+(k+1)+" of "+numberOfClusters); taskMonitor.setStatusMessage("Processing clusters "+(k+1)+" of "+numberOfClusters);
IntVector clusterVector = result.getCluster(i, k); IntVector clusterVector = result.getCluster(i, k);
long sizeOfCluster = clusterVector.size(); long sizeOfCluster = clusterVector.size();
for (int l=0;l<sizeOfCluster;l++) { //Unsafe mismatch int long for (int l=0;l<sizeOfCluster;l++) { //Unsafe mismatch int long
taskMonitor.setStatusMessage("Processing node "+(l+1)+ " of "+sizeOfCluster); //taskMonitor.setStatusMessage("Processing node "+(l+1)+ " of "+sizeOfCluster);
int nodeID = clusterVector.get(l); int nodeID = clusterVector.get(l);
CyNode node = nodeMap.indexOf(nodeID); //<<< Another int/long conversion CyNode node = nodeMap.indexOf(nodeID); //<<< Another int/long conversion
cluster.addNode(node); cluster.addNode(node);
net.getRow(node).set(columnName, ""+(k+1)); //Add Cluster ID in table (Remove in final version?) net.getRow(node).set(columnName, ""+(k+1)); //Add Cluster ID in table (Remove in final version?)
} }
//Register cluster with solution for further reference //Register clusters with solution for further reference
solution.cluster.add(cluster); solution.clusters.add(cluster);
} }
//Sort clusters by size, descending as the biggest clusters are usually the most relevant //Sort clusters by size, descending as the biggest clusters are usually the most relevant
solution.cluster.sort(YoshikoCluster.lessThanComparator); solution.clusters.sort(YoshikoCluster.lessThanComparator);
//Register solution with result for further reference //Register solution with result for further reference
yoshikoResult.addSolution(solution); yoshikoResult.addSolution(solution);
} }
......
...@@ -5,8 +5,11 @@ import java.util.ArrayList; ...@@ -5,8 +5,11 @@ import java.util.ArrayList;
import org.cytoscape.model.subnetwork.CySubNetwork; import org.cytoscape.model.subnetwork.CySubNetwork;
import org.cytoscape.view.layout.CyLayoutAlgorithm; import org.cytoscape.view.layout.CyLayoutAlgorithm;
import org.cytoscape.view.model.CyNetworkView; import org.cytoscape.view.model.CyNetworkView;
import org.cytoscape.work.FinishStatus;
import org.cytoscape.work.ObservableTask;
import org.cytoscape.work.Task; import org.cytoscape.work.Task;
import org.cytoscape.work.TaskMonitor; import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.TaskObserver;
import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.CyCore;
import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
...@@ -56,20 +59,30 @@ public class CreateClusterViews implements Task { ...@@ -56,20 +59,30 @@ public class CreateClusterViews implements Task {
CyCore.networkManager.addNetwork(subnet,false); CyCore.networkManager.addNetwork(subnet,false);
//Create network view and register it //Create network view and register it
CyNetworkView subnetView = CyCore.networkViewFactory.createNetworkView(subnet); CyNetworkView subnetView = CyCore.networkViewFactory.createNetworkView(subnet);
//layout cluster //layout clusters
CyCore.dialogTaskManager.execute( CyCore.dialogTaskManager.execute(
layout.createTaskIterator( layout.createTaskIterator(
subnetView, subnetView,
layout.getDefaultLayoutContext(), layout.getDefaultLayoutContext(),
CyLayoutAlgorithm.ALL_NODE_VIEWS, CyLayoutAlgorithm.ALL_NODE_VIEWS,
null null
) ),
); new TaskObserver() {
StyleManager.style(subnetView,CyCore.visualMappingManager.getCurrentVisualStyle()); @Override
public void taskFinished(ObservableTask task) {}
@Override
public void allFinished(FinishStatus finishStatus) {
StyleManager.style(subnetView,CyCore.visualMappingManager.getCurrentVisualStyle());
CyCore.networkViewManager.addNetworkView(subnetView); CyCore.networkViewManager.addNetworkView(subnetView);
} }
}
);
}
} }
@Override @Override
......
...@@ -3,6 +3,8 @@ package de.hhu.ba.yoshikoWrapper.tasks; ...@@ -3,6 +3,8 @@ package de.hhu.ba.yoshikoWrapper.tasks;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import javax.swing.SwingUtilities;
import org.cytoscape.model.CyEdge; import org.cytoscape.model.CyEdge;
import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNetwork;
import org.cytoscape.model.CyNode; import org.cytoscape.model.CyNode;
...@@ -11,9 +13,11 @@ import org.cytoscape.model.subnetwork.CySubNetwork; ...@@ -11,9 +13,11 @@ import org.cytoscape.model.subnetwork.CySubNetwork;
import org.cytoscape.view.layout.CyLayoutAlgorithm; import org.cytoscape.view.layout.CyLayoutAlgorithm;
import org.cytoscape.view.model.CyNetworkView; import org.cytoscape.view.model.CyNetworkView;
import org.cytoscape.work.AbstractTask; import org.cytoscape.work.AbstractTask;
import org.cytoscape.work.FinishStatus;
import org.cytoscape.work.ObservableTask;
import org.cytoscape.work.Task; import org.cytoscape.work.Task;
import org.cytoscape.work.TaskIterator;
import org.cytoscape.work.TaskMonitor; import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.TaskObserver;
import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.CyCore;
import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
...@@ -76,8 +80,10 @@ public class CreateMetaGraphTask extends AbstractTask { ...@@ -76,8 +80,10 @@ public class CreateMetaGraphTask extends AbstractTask {
CyCore.networkManager.addNetwork(subnet,false); CyCore.networkManager.addNetwork(subnet,false);
//Create network view and register it //Create network view and register it
CyNetworkView subnetView = CyCore.networkViewFactory.createNetworkView(subnet); CyNetworkView subnetView = CyCore.networkViewFactory.createNetworkView(subnet);
//layout cluster
CyCore.dialogTaskManager.execute( //Apply layout
CyCore.runAndWait(
layout.createTaskIterator( layout.createTaskIterator(
subnetView, subnetView,
layout.getDefaultLayoutContext(), layout.getDefaultLayoutContext(),
...@@ -90,17 +96,23 @@ public class CreateMetaGraphTask extends AbstractTask { ...@@ -90,17 +96,23 @@ public class CreateMetaGraphTask extends AbstractTask {
CyCore.networkViewManager.addNetworkView(subnetView,false); CyCore.networkViewManager.addNetworkView(subnetView,false);
//Link cluster node in meta graph and subnet graph to use Cytoscape Nested Network feature //Link clusters node in meta graph and subnet graph to use Cytoscape Nested Network feature
clusterNode.setNetworkPointer(subnet); clusterNode.setNetworkPointer(subnet);
//Set node attributes //Set node attributes
metaGraph.getRow(clusterNode).set("name", LocalizationManager.get("cluster")+" "+c.getID()); metaGraph.getRow(clusterNode).set("name", LocalizationManager.get("clusters")+" "+c.getID());
metaGraph.getRow(clusterNode).set(StyleManager.CLUSTERSIZE_COLUMN_NAME,c.getSize()); metaGraph.getRow(clusterNode).set(StyleManager.CLUSTERSIZE_COLUMN_NAME,c.getSize());
map.put(c, clusterNode); map.put(c, clusterNode);
} }
//EDGE_PROCESSING
//We are checking if any edges in the original graph connect clusters, if so we count them
taskMonitor.setStatusMessage(LocalizationManager.get("metaGraph_edges")); taskMonitor.setStatusMessage(LocalizationManager.get("metaGraph_edges"));
//Add edges (O(|C|^2*|V|^2) can maybe be improved? //TODO
for (YoshikoCluster c1:solution.getClusters()) { for (int x = 0; x <solution.getClusters().size(); x ++) {
for (YoshikoCluster c2:solution.getClusters()) { YoshikoCluster c1 = solution.getClusters().get(x);
for (int y = x; y <solution.getClusters().size(); y ++) {
YoshikoCluster c2 = solution.getClusters().get(y);
if(isTerminated) { if(isTerminated) {
throw new Exception("Terminated by user!"); throw new Exception("Terminated by user!");
...@@ -112,6 +124,7 @@ public class CreateMetaGraphTask extends AbstractTask { ...@@ -112,6 +124,7 @@ public class CreateMetaGraphTask extends AbstractTask {
) { ) {
continue; continue;
} }
//TODO: Improve running time here?
for (CyNode c1n : c1.getSubNetwork().getNodeList()) { for (CyNode c1n : c1.getSubNetwork().getNodeList()) {
for (CyNode c2n : c2.getSubNetwork().getNodeList()) { for (CyNode c2n : c2.getSubNetwork().getNodeList()) {
if (solution.getOriginalGraph().containsEdge(c1n, c2n) || solution.getOriginalGraph().containsEdge(c2n, c1n)) { if (solution.getOriginalGraph().containsEdge(c1n, c2n) || solution.getOriginalGraph().containsEdge(c2n, c1n)) {
...@@ -131,32 +144,22 @@ public class CreateMetaGraphTask extends AbstractTask { ...@@ -131,32 +144,22 @@ public class CreateMetaGraphTask extends AbstractTask {
} }
} }
solution.setMetaGraph(metaGraph,map);
CyNetworkView view = CyCore.networkViewFactory.createNetworkView(metaGraph); CyNetworkView view = CyCore.networkViewFactory.createNetworkView(metaGraph);
//Layout and style solution //Layout and style solution
CyCore.runAndWait(
TaskIterator it = layout.createTaskIterator( layout.createTaskIterator(
view, view,
layout.getDefaultLayoutContext(), layout.getDefaultLayoutContext(),
CyLayoutAlgorithm.ALL_NODE_VIEWS, CyLayoutAlgorithm.ALL_NODE_VIEWS,
null null
)
); );
it.append(new Task() {
@Override
public void run(TaskMonitor taskMonitor) throws Exception {
StyleManager.styleWithMapping(view, CyCore.visualMappingManager.getCurrentVisualStyle()); StyleManager.styleWithMapping(view, CyCore.visualMappingManager.getCurrentVisualStyle());
}
@Override
public void cancel() {}
});
CyCore.dialogTaskManager.execute(
it
);
CyCore.networkManager.addNetwork(metaGraph,false); CyCore.networkManager.addNetwork(metaGraph,false);
CyCore.networkViewManager.addNetworkView( CyCore.networkViewManager.addNetworkView(
...@@ -166,6 +169,7 @@ public class CreateMetaGraphTask extends AbstractTask { ...@@ -166,6 +169,7 @@ public class CreateMetaGraphTask extends AbstractTask {
view.updateView(); view.updateView();
CyCore.cy.setCurrentNetworkView(view); CyCore.cy.setCurrentNetworkView(view);
} }
@Override @Override
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
about = INSERT SOME AMAZING INFO ABOUT THIS APPLICATION,\n THE AUTHOR AND WHERE TO FIND MORE INFO HERE\n <a href=\"www.hhu.de\" >LINK</a> about = INSERT SOME AMAZING INFO ABOUT THIS APPLICATION,\n THE AUTHOR AND WHERE TO FIND MORE INFO HERE\n <a href=\"www.hhu.de\" >LINK</a>
aboutButton = About Yoshiko aboutButton = About Yoshiko
aboutTitle = Yoshiko Plugin Info aboutTitle = Yoshiko Plugin Info
cluster = Cluster clusters = Cluster
clusterFound = Clusters found: clusterFound = Clusters found:
clusterSize = Cluster Size: clusterSize = Cluster Size:
continueTimeout = The ILP has exceeded the given time limit. Do you want to continue? (This may take a long time) continueTimeout = The ILP has exceeded the given time limit. Do you want to continue? (This may take a long time)
...@@ -46,7 +46,6 @@ firstStart = Thanks for using the Yoshiko Clustering Tool!\nIt appears, that thi ...@@ -46,7 +46,6 @@ firstStart = Thanks for using the Yoshiko Clustering Tool!\nIt appears, that thi
gap = Gap gap = Gap
getYoshiko = Get Yoshiko Library getYoshiko = Get Yoshiko Library
icTooltip = This value is used to determine what the algorithm pays when inserting an edge.\nExisting mappings overwrite this value.\nA higher value means that the algorithm is less likely to insert edges in order to generate a cluster. icTooltip = This value is used to determine what the algorithm pays when inserting an edge.\nExisting mappings overwrite this value.\nA higher value means that the algorithm is less likely to insert edges in order to generate a cluster.
ilpMarker = ILP Properties
incompleteResult = This run yielded no usable result! incompleteResult = This run yielded no usable result!
instance = Instance instance = Instance
invalidated = No longer valid, original graph changed! invalidated = No longer valid, original graph changed!
...@@ -77,6 +76,7 @@ resultsPanelTitle = Yoshiko Results ...@@ -77,6 +76,7 @@ resultsPanelTitle = Yoshiko Results
run = Perform Algorithm run = Perform Algorithm
showAdvanced = Show advanced options showAdvanced = Show advanced options
solution = Solution solution = Solution
solutionMarker = Solution Properties
status_createCV = Creating cluster view for cluster: status_createCV = Creating cluster view for cluster:
......
No preview for this file type
...@@ -30,6 +30,14 @@ ...@@ -30,6 +30,14 @@
\cleardoublepage \cleardoublepage
\begin{abstract} \begin{abstract}
This paper describes an implementation of the Yoshiko-alorithm,
which clusters data based on the weighted cluster-editing problem,
as a plugin for Cytoscape.
Cytoscape is a network visualization and analysis tool (insert info)
Yoshiko is based on work from (insert info)
\end{abstract} \end{abstract}
...@@ -40,6 +48,8 @@ ...@@ -40,6 +48,8 @@
\section{Introduction} \section{Introduction}
\section{The Yoshiko-App for Cytoscape} \section{The Yoshiko-App for Cytoscape}
\subsection{Technical Details} \subsection{Technical Details}
\subsubsection{Program Structure}
\subsubsection{JNI}
\subsection{Algorithm} \subsection{Algorithm}
\input{Chapter/alg_overview} \input{Chapter/alg_overview}
\subsubsection{Data Modeling} \subsubsection{Data Modeling}
...@@ -49,4 +59,6 @@ ...@@ -49,4 +59,6 @@
\input{Chapter/dm_impl} \input{Chapter/dm_impl}
\section{Evaluation of the Yoshiko Algorithm} \section{Evaluation of the Yoshiko Algorithm}
\section{Outlook} \section{Outlook}
\subsection{Multigraph Analysis}
\subsection{Integration in other frameworks}
\end{document} \end{document}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment