diff --git a/pom.xml b/pom.xml index 47ac4958f7ebda9ee82b1adc724de7a0be4cb6af..42698a1c1b7748931a415eed0d23655fe230335b 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ <groupId>de.hhu.ba</groupId> <artifactId>yoshikoWrapper</artifactId> - <version>0.1.4</version> + <version>0.1.5</version> <name>YoshikoWrapper</name> diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java b/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java index b79892ee08f50af56220b59916d69d6ba2beb93d..f34df8026716566d65a387afae841db54cfa564b 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java @@ -110,7 +110,7 @@ public class CyActivator extends AbstractCyActivator { } } - //Register commands / CyRest + //Register commands / CyRest //TODO: Group shared calls for better code readability / less lines of code TaskFactory commandTaskFactory_PERFORM_ALGORITHM = new CommandTaskFactory(YoshikoCommand.PERFORM_ALGORITHM); Properties props_PERFORM_ALGORITHM = new Properties(); props_PERFORM_ALGORITHM.setProperty(COMMAND_NAMESPACE, "yoshiko"); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java index 74fd62bc7b07e228e4ad5b788521a10a27306697..62271fab52f1c72469bfcf77ab5cfb9a3c7baafa 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java @@ -52,6 +52,9 @@ public class ParameterSet implements TunableValidator /**Describes whether auto configuration of the reduction rules is to be used. Overrides the bit mask.**/ public boolean suggestReduction = true; + @Tunable(description="Determines the number of clusters that are to be generated. -1 generates the optimal amount of clusters in the sense of WCE") + public int clusterCount = -1; + @Override public ValidationState getValidationState(Appendable errMsg) { System.out.println("DEBUG: Running VALIDATION of tunables"); //TODO: Move to logger (if it would work) @@ -68,6 +71,11 @@ public class ParameterSet implements TunableValidator errMsg.append("The Bitmask provided is invalid! Needs to be six bit binary (example: 011001)\n"); return ValidationState.INVALID; } + //Checks for cluster count number + if ((clusterCount < 0 && clusterCount != -1)||(clusterCount == 0)) { + errMsg.append("Invalid cluster count number!"); + return ValidationState.INVALID; + } return ValidationState.OK; } catch (IOException e) { // TODO Auto-generated catch block diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshikoLoader.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshikoLoader.java index f7d349d0ca9dd87ba359202f9edf84e3cc464d9a..937bf0ec72c5a2ae81a3b0a32ad4bfb4c22dff40 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshikoLoader.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/YoshikoLoader.java @@ -31,7 +31,7 @@ import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface; public class YoshikoLoader { - public static final String REQUIRED_VERSION = "2.1.1"; + public static final String REQUIRED_VERSION = "2.1.2"; private static boolean isLoaded; diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java b/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java index 1ef7cc8345a480edecdeadb8803c5e8634e838e4..24ca2d5df9c0002ac7ca3cf7b6d976184d6834bc 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java @@ -15,6 +15,11 @@ public class GraphAnalyzer { //private static Logger logger = YoshikoLogger.getInstance().getLogger(); + /** + * Simple helper function, checks if a network contains multiple edges between a pair of nodes + * @param net The CyNetwork that is to be analyzed + * @return <b>true</b> if a pair of nodes exists that is connected with more than one edge, <b>false</b> otherwise + */ public static boolean isMultiGraph(CyNetwork net) { //TODO: Better algorithm? @@ -43,7 +48,7 @@ public class GraphAnalyzer { * This function is symmetric * @param e1 An arbitrary CyEdge * @param e2 An arbitrary CyEdge - * @return true if the edges connect the same pair of nodes, false otherwise + * @return <b>true</b> if the edges connect the same pair of nodes, <b>false</b> otherwise */ private static boolean connectSameNodes(CyEdge e1, CyEdge e2) { if (//Treating all edges as undirected here @@ -98,12 +103,23 @@ public class GraphAnalyzer { ret += (usePDRRule ? "1" : "0"); ret += (useSNRule ? "1" : "0"); + //TODO: Spend some thoughts on logging, make a coherent design decision on logging //logger.info("Suggesting the following reduction-rules bitmask: "+ret); - System.out.println("Suggesting the following reduction-rules bitmask: "+ret); + //System.out.println("Suggesting the following reduction-rules bitmask: "+ret); return ret; } + /** + * Simple helper function that checks if a WCE instance contains real values (as opposed to only integers) + * @param net The network from which the WCE instance is to be derived + * @param weightColumn The CyColumn from which - if != null - the edge weights are taken + * @param permanentColumn The CyColumn from which - if != null - we derive if edges are permanent + * @param forbiddenColumn The CyColumn from which - if != null - we derive if edges are forbidden + * @param defaultInsertionCost The insertion cost used for non-existing edges or ones with no mapping associated + * @param defaultDeletionCost The deletion cost for edges with no mapping associated + * @return true if the WCE instance is real-valued, false otherwise + */ public static boolean containsRealValues( CyNetwork net, CyColumn weightColumn, diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ClusterCountChooser.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ClusterCountChooser.java new file mode 100644 index 0000000000000000000000000000000000000000..24932a0f2663aec9cbecf6059ca4afe8d7071e48 --- /dev/null +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ClusterCountChooser.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (C) 2017 Philipp Spohr + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ +package de.hhu.ba.yoshikoWrapper.swing.components; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; +import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; + +@SuppressWarnings("serial") +public class ClusterCountChooser extends JPanel { + private final IntegerInputField numSolutionsSetter; + private final JLabel label; + + public ClusterCountChooser() { + //Swing Component init + numSolutionsSetter = new IntegerInputField(); + label = new JLabel(LocalizationManager.get("nrClusters")); + SwingUtil.addAll(this,label, numSolutionsSetter); + } + + @Override + public void setEnabled(boolean enabled) { + numSolutionsSetter.setEnabled(enabled); + } + + public int getClusterCount() { + return numSolutionsSetter.getValueAsInt(); + } +} diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/EditCostPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/EditCostPanel.java index 38b0126b43ba7aa8fad14ff97da8fffa3b32cafb..4beef6ff2d19d37adaf29c52000d828a1307ad4e 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/EditCostPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/EditCostPanel.java @@ -27,8 +27,6 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.GroupLayout.Alignment; -import org.cytoscape.model.CyColumn; - import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java index 32d5906cf7fce2e4b63f8afa8f6092df11a75d13..32fd5d773f4e8c3c6129d5404e9c3329ea666fa9 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/MainPanel.java @@ -359,6 +359,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent { ret.usePartitionCuts = opModePanel.usePartitionCuts(); ret.solCount = opModePanel.getSolCount(); ret.disableMultiThreading = opModePanel.isMultiThreadingDisabled(); + ret.clusterCount = opModePanel.getClusterCount(); return ret; } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/OperationModePanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/OperationModePanel.java index bda3f6f4b5c69a8a640831aa076d23df28e04fef..8a4287cc4e78b6d075456108f757a39d8ad70192 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/OperationModePanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/OperationModePanel.java @@ -41,6 +41,8 @@ import javax.swing.GroupLayout.Alignment; public class OperationModePanel extends JPanel{ //SWING COMPONENTS + private final JCheckBox useClusterCount; + private final ClusterCountChooser ccChooser; private final JRadioButton useHeuristic; private final JRadioButton useILP; private final TimeLimitSetter timeLimitSetter; @@ -53,6 +55,12 @@ public class OperationModePanel extends JPanel{ public OperationModePanel() { + useClusterCount = new JCheckBox(LocalizationManager.get("useClusterCount")); + ccChooser = new ClusterCountChooser(); + ccChooser.setEnabled(false); + + useClusterCount.addActionListener(ccSwitch); + heuristicGroup = new ButtonGroup(); useILP = new JRadioButton("Use Integer Linear Programming"); @@ -79,6 +87,8 @@ public class OperationModePanel extends JPanel{ useHeuristic.addActionListener(ilpHeuristicSwitch); SwingUtil.addAll(this, + useClusterCount, + ccChooser, useHeuristic, useILP, solutionNumberChooser, @@ -97,6 +107,8 @@ public class OperationModePanel extends JPanel{ layout.setAutoCreateContainerGaps(true); layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING,true) + .addComponent(useClusterCount, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(ccChooser, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(useHeuristic, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(useILP, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(solutionNumberChooser, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) @@ -107,6 +119,8 @@ public class OperationModePanel extends JPanel{ ); layout.setVerticalGroup(layout.createSequentialGroup() + .addComponent(useClusterCount) + .addComponent(ccChooser) .addComponent(useHeuristic) .addComponent(useILP) .addComponent(solutionNumberChooser) @@ -137,13 +151,21 @@ public class OperationModePanel extends JPanel{ } } - ActionListener ilpHeuristicSwitch = new ActionListener() { + private ActionListener ilpHeuristicSwitch = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ilpHeuristicSwitch(); } }; + private ActionListener ccSwitch = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + ccChooser.setEnabled(useClusterCount.isSelected()); + } + + }; //SETTER GETTER public int getTimeLimit() { @@ -169,4 +191,8 @@ public class OperationModePanel extends JPanel{ public int getSolCount() { return solutionNumberChooser.getSolCount(); } + + public int getClusterCount() { + return useClusterCount.isSelected() ? ccChooser.getClusterCount() : -1; + } } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ResultPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ResultPanel.java index dfb0eebb8bd3b79d670aff1c0e263905e3923105..d276d08c05343ca9a817a6aeeb697059abd0867f 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ResultPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ResultPanel.java @@ -43,7 +43,6 @@ import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.LayoutStyle; import javax.swing.SwingConstants; -import javax.swing.SwingUtilities; import org.cytoscape.application.swing.CytoPanelComponent; import org.cytoscape.application.swing.CytoPanelName; diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java index 331c298188cd2a1912df5b54aecf9747d351ddce..4031bdf20b28d9edd4739319cd701153dceaf3c7 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java @@ -170,7 +170,8 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask, Tunab parameterSet.snrMultFactor, parameterSet.useHeuristic, parameterSet.usePartitionCuts, - parameterSet.useTriangleCuts + parameterSet.useTriangleCuts, + parameterSet.clusterCount ); @@ -261,7 +262,13 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask, Tunab } + /** + * Simple helper function that analyzes C++ results and identifies solutions that are not usable or meaningful + * @param result The ClusterEditingSolutions object generated in C++ by a Yoshiko run + * @throws Exception Throws an exception if the result is not usable + */ private void checkForInvalidSolutions(ClusterEditingSolutions result) throws Exception { + //TODO: Feasible might be the wrong word here if (result == null) { //There was no c_result object generated at all throw new Exception(LocalizationManager.get("noFeasible")); diff --git a/src/main/resources/YoshikoStrings.properties b/src/main/resources/YoshikoStrings.properties index b20a177a70f2a91e877d6071906459d786118ec7..ce6dff546d03fce1a311296c3fbdec64096eb48d 100644 --- a/src/main/resources/YoshikoStrings.properties +++ b/src/main/resources/YoshikoStrings.properties @@ -74,6 +74,8 @@ optionpane_title = Yoshiko Info noClustersSelected = You have not selected any clusters notOptimal = Optimality not guaranteed nrSolutions = Number of Solutions: +nrClusters = Number of Clusters: +useClusterCount = Define cluster count operationMode = Operation Mode optimal = Optimal Solution paidCost = Paid a total modification cost of: