diff --git a/pom.xml b/pom.xml index 34a0ed52a57a7f8ea3ec7f7c251eafcd820b1d68..8cee3140f295e25628a57a43a7da096333407220 100644 --- a/pom.xml +++ b/pom.xml @@ -157,6 +157,11 @@ <artifactId>swing-util-api</artifactId> <version>${cytoscape.api.version}</version> </dependency> + <dependency> + <groupId>org.cytoscape</groupId> + <artifactId>group-api</artifactId> + <version>${cytoscape.api.version}</version> + </dependency> </dependencies> <description>A Cytoscape plugin for graph-based clustering that wraps the yoshiko algorithm.</description> diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java b/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java index 14967895edce8fb4bc906035114e91f5c3f97409..0a088f54021c7bf0cf2362aacc42e23a75987b6b 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java @@ -38,6 +38,7 @@ import org.cytoscape.model.subnetwork.CyRootNetworkManager; import org.cytoscape.service.util.AbstractCyActivator; import org.cytoscape.service.util.CyServiceRegistrar; import org.cytoscape.session.events.SessionLoadedListener; +import org.cytoscape.task.create.CloneNetworkTaskFactory; import org.cytoscape.task.visualize.ApplyVisualStyleTaskFactory; import org.cytoscape.view.model.CyNetworkViewFactory; import org.cytoscape.view.layout.CyLayoutAlgorithmManager; @@ -87,6 +88,7 @@ public class CyActivator extends AbstractCyActivator { CyCore.rootNetworkManager = getService(context,CyRootNetworkManager.class); CyCore.applyVisualStyleTaskFactory = getService(context,ApplyVisualStyleTaskFactory.class); CyCore.renderingEngineFactory = getService(context,RenderingEngineFactory.class); + CyCore.cloneNetworkTaskFactory = getService(context,CloneNetworkTaskFactory.class); //Set language according to settings LocalizationManager.switchLanguage(cm.getProperties().getProperty("locale", "enUS")); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java index 1bb46b7a0e44e9f6153264c5e631ca1594dec37a..50887d924d89f05fdb3108aa2833a61511e394f9 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java @@ -30,7 +30,6 @@ import org.cytoscape.application.swing.CytoPanel; import org.cytoscape.application.swing.CytoPanelComponent; import org.cytoscape.application.swing.CytoPanelName; import org.cytoscape.application.swing.CytoPanelState; -import org.cytoscape.model.CyColumn; import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNode; import org.cytoscape.work.AbstractTask; @@ -58,19 +57,8 @@ public class AlgorithmTask extends AbstractTask { private Window statusWindow; //Parameters - private final double insertionCostDefault; - private final double deletionCostDefault; - private final CyColumn permanentColumn; - private final CyColumn forbiddenColumn; - private CyColumn weightColumn; - private int timeLimit; - private CyNetwork net; - private String bitMaskRules; - private double multiplicativeFactor; - private boolean separatePartitionCuts; - private boolean separateTriangles; - private boolean useHeuristic; - private int numberOfSolutions; + private final ParameterSet parameterSet; + private final CyNetwork net; //Temps, need to be freed in C++ private LibraryInput input; @@ -82,34 +70,12 @@ public class AlgorithmTask extends AbstractTask { public AlgorithmTask(// <<< Too many variables here, some should be grouped later TODO: Window statusWindow, CyNetwork net, - int timeLimit, - CyColumn weightColumn, - CyColumn permanentColumn, - CyColumn forbiddenColumn, - double insertionCostDefault, - double deletionCostDefault, - String bitMaskRules, - double multiplicativeFactor, - boolean separatePartitionCuts, - boolean separateTriangles, - boolean useHeuristic, - int numberOfSolutions + ParameterSet parameterSet ) { this.statusWindow = statusWindow; this.net = net; - this.timeLimit = timeLimit; - this.weightColumn = weightColumn; - this.permanentColumn = permanentColumn; - this.forbiddenColumn = forbiddenColumn; - this.insertionCostDefault = insertionCostDefault; - this.deletionCostDefault = deletionCostDefault; - this.bitMaskRules = bitMaskRules; - this.multiplicativeFactor = multiplicativeFactor; - this.separatePartitionCuts = separatePartitionCuts; - this.separateTriangles = separateTriangles; - this.useHeuristic = useHeuristic; - this.numberOfSolutions = numberOfSolutions; + this.parameterSet = parameterSet; } @Override @@ -125,7 +91,7 @@ public class AlgorithmTask extends AbstractTask { } //Set time limit - LibraryInterface.setTimeLimit(timeLimit); + LibraryInterface.setTimeLimit(parameterSet.timeLimit); //Create a node map to identify nodes and eges in the solution NodeMap nodeMap = new NodeMap(net); @@ -135,24 +101,24 @@ public class AlgorithmTask extends AbstractTask { input = NetworkParser.parseNetwork( net, nodeMap, - weightColumn, - permanentColumn, - forbiddenColumn, - deletionCostDefault + parameterSet.weightColumn, + parameterSet.permanentColumn, + parameterSet.forbiddenColumn, + parameterSet.defaultDeletionCost ); taskMonitor.setProgress(0.2); //Set the default value for insertion cost - input.setDefaultInsertionCost(insertionCostDefault); + input.setDefaultInsertionCost(parameterSet.defaultInsertionCost); //Call Yoshiko <<< Algorithm is performed here ca = LibraryInterface.getRun(input, - numberOfSolutions, - bitMaskRules, - multiplicativeFactor, - separatePartitionCuts, - separateTriangles, - useHeuristic + parameterSet.solCount, + parameterSet.reductionRulesBitMask, + parameterSet.snrMultFactor, + parameterSet.usePartitionCuts, + parameterSet.useTriangleCuts, + parameterSet.useHeuristic ); class CallbackHandler extends CplexInformer{ diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java index ab7cefae60d41026fe780f4caaa54cfec85aee52..803d3ee74546377edfc4b2bd82ee2c3a8d8ed81e 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java @@ -28,6 +28,7 @@ import org.cytoscape.model.CyNetworkFactory; import org.cytoscape.model.CyNetworkManager; import org.cytoscape.model.subnetwork.CyRootNetworkManager; import org.cytoscape.service.util.CyServiceRegistrar; +import org.cytoscape.task.create.CloneNetworkTaskFactory; import org.cytoscape.task.visualize.ApplyVisualStyleTaskFactory; import org.cytoscape.view.layout.CyLayoutAlgorithmManager; import org.cytoscape.view.model.CyNetworkViewFactory; @@ -62,5 +63,7 @@ public class CyCore { public static CyRootNetworkManager rootNetworkManager; public static ApplyVisualStyleTaskFactory applyVisualStyleTaskFactory; public static RenderingEngineFactory<CyNetwork> renderingEngineFactory; + public static CloneNetworkTaskFactory cloneNetworkTaskFactory; + // } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java new file mode 100644 index 0000000000000000000000000000000000000000..863c86959a06f4113adb80f8b100fded4e81380c --- /dev/null +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java @@ -0,0 +1,20 @@ +package de.hhu.ba.yoshikoWrapper.core; + +import org.cytoscape.model.CyColumn; + +public class ParameterSet { + + public int timeLimit; + public CyColumn weightColumn; + public CyColumn permanentColumn; + public CyColumn forbiddenColumn; + public double defaultInsertionCost; + public double defaultDeletionCost; + public String reductionRulesBitMask; + public double snrMultFactor; + public boolean useTriangleCuts; + public boolean usePartitionCuts; + public boolean useHeuristic; + public int solCount; + +} diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/package-info.java b/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..6897d9a8757c9cddf4f889b75048e6de555cdb96 --- /dev/null +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author Philipp Spohr, Sep 5, 2017 + * + */ +package de.hhu.ba.yoshikoWrapper.cytoUtil; \ No newline at end of file diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoCluster.java b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoCluster.java index 40b3878452055c7a7b5131e3d62aa3464cc510e8..2e1f1d1e1059feb3a394b1eefd8ee6570cec2afc 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoCluster.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoCluster.java @@ -94,8 +94,11 @@ public class YoshikoCluster { } } + /** + * Attempt to select the nodes belonging to this cluster in the original Graph given that they still exist + */ public void select() { - if (originalGraph.getDefaultNodeTable() != null) { + try { List<CyRow> allRows = originalGraph.getDefaultNodeTable().getAllRows(); for (CyRow r: allRows) { r.set("selected", false); @@ -105,21 +108,23 @@ public class YoshikoCluster { originalGraph.getRow(n).set("selected", true); } } - else { + catch (Exception e) { logger.warn("The graph doesn't exist anymore, can't highlight nodes!"); } } public void generateImage(JLabel label, int width, int height) { + if (net == null) { createSubNetwork(); } - CyNetworkView view = CyCore.networkViewFactory.createNetworkView(net); + + final CyNetworkView view = CyCore.networkViewFactory.createNetworkView(net); //layout cluster - CyLayoutAlgorithm layout = CyCore.layoutAlgorithmManager.getDefaultLayout(); - TaskIterator createLayout = layout.createTaskIterator( + final CyLayoutAlgorithm layout = CyCore.layoutAlgorithmManager.getDefaultLayout(); + final TaskIterator createLayout = layout.createTaskIterator( view, layout.getDefaultLayoutContext(), CyLayoutAlgorithm.ALL_NODE_VIEWS, @@ -161,7 +166,7 @@ public class YoshikoCluster { @Override public void cancel() { - // TODO Auto-generated method stub + //Nothing to do as GC is handled by JAVA } } @@ -197,6 +202,4 @@ public class YoshikoCluster { return originalGraph.getRow(n).get("name", String.class); } - - } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoSolution.java b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoSolution.java index bb1a5e5b92af9db4219ed6ee67c54ce6d2175444..ed2227917e664819a54d953e8e40e32f5eaaf860 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoSolution.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoSolution.java @@ -28,17 +28,23 @@ import org.cytoscape.model.CyEdge; import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNode; import org.cytoscape.model.CyEdge.Type; + import org.cytoscape.model.subnetwork.CySubNetwork; import org.cytoscape.view.layout.CyLayoutAlgorithm; import org.cytoscape.view.model.CyNetworkView; import org.cytoscape.view.presentation.property.BasicVisualLexicon; import org.cytoscape.view.vizmap.VisualStyle; import org.cytoscape.view.vizmap.mappings.ContinuousMapping; + import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; public class YoshikoSolution { + /** + * The original Graph from which the solution was generated. + * NOTE: This can be destroyed or modified during runtime while the solution still exists and may become invalid + */ private CyNetwork originalGraph; public ArrayList<YoshikoCluster> cluster; diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java index 4fe0d95f0c611eeb39fc65b9e982fea289ae76db..0ce16d3353256cea0d0d6aa10404054f79118edc 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java @@ -53,6 +53,7 @@ import de.hhu.ba.yoshikoWrapper.core.AlgorithmTask; import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.GraphicsLoader; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; +import de.hhu.ba.yoshikoWrapper.core.ParameterSet; import de.hhu.ba.yoshikoWrapper.core.YoshikoLoader; /**This class describes the Swing Panel that the user interacts with in cytoscape @@ -212,18 +213,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent { AbstractTask yoshiko = new AlgorithmTask( popupLevel, CyCore.cy.getCurrentNetwork(), - opModePanel.getTimeLimit(), - ecPanel.getWeightColumn(), - ecPanel.getPermanentColumn(), - ecPanel.getForbiddenColumn(), - ecPanel.getDefaultInsertionCost(), - ecPanel.getDefaultDeletionCost(), - reductionRulesChooser.getBitMask(), - reductionRulesChooser.getMultFactor(), - opModePanel.useTriangleCuts(), - opModePanel.usePartitionCuts(), - opModePanel.useHeuristic(), - opModePanel.getSolCount() + fetchParameter() ); /** * Don't queue multiple runs at once because that will get messy @@ -247,6 +237,26 @@ public class MainPanel extends JPanel implements CytoPanelComponent { } }; + /** + * Fetches all the parameters from the various swing components and packs them into a neat abstract wrapper class + * @return The currently selected parameter wrapped in a ParameterSet + */ + private ParameterSet fetchParameter() { + ParameterSet ret = new ParameterSet(); + ret.timeLimit = opModePanel.getTimeLimit(); + ret.weightColumn = ecPanel.getWeightColumn(); + ret.permanentColumn = ecPanel.getPermanentColumn(); + ret.forbiddenColumn = ecPanel.getForbiddenColumn(); + ret.defaultInsertionCost = ecPanel.getDefaultInsertionCost(); + ret.defaultDeletionCost = ecPanel.getDefaultDeletionCost(); + ret.reductionRulesBitMask = reductionRulesChooser.getBitMask(); + ret.snrMultFactor = reductionRulesChooser.getMultFactor(); + ret.useTriangleCuts = opModePanel.useTriangleCuts(); + ret.usePartitionCuts = opModePanel.usePartitionCuts(); + ret.useHeuristic = opModePanel.useHeuristic(); + ret.solCount = opModePanel.getSolCount(); + return ret; + } //GETTER / SETTER