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/ConfigurationManager.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ConfigurationManager.java index 1fbcaac81d772d4823c42011b40a246ce02ff402..d564e2090eeb1390ff8ca2e4d79bab943c35bc3e 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/ConfigurationManager.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ConfigurationManager.java @@ -1,16 +1,16 @@ /******************************************************************************* * 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 @@ -25,9 +25,9 @@ import org.cytoscape.property.AbstractConfigDirPropsReader; import org.cytoscape.property.CyProperty; public class ConfigurationManager extends AbstractConfigDirPropsReader{ - + public ConfigurationManager(String appName, String fileName){ super(appName, fileName, CyProperty.SavePolicy.CONFIG_DIR); - this.getProperties().list(System.out); - } + //this.getProperties().list(System.out); + } } 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 08ac18a7aa2ab569817cdbee9f7f90dcf7467331..ce7fbd136ec6bf41ee259a750c545b578216c6af 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java @@ -4,21 +4,25 @@ package de.hhu.ba.yoshikoWrapper.core; import java.io.IOException; import org.cytoscape.model.CyColumn; +import org.cytoscape.model.CyNetwork; import org.cytoscape.work.Tunable; import org.cytoscape.work.TunableValidator; public class ParameterSet implements TunableValidator { + @Tunable(description="Network to analyze for clusters", context="nogui") + public CyNetwork net = CyCore.cy.getCurrentNetwork(); + @Tunable(description="Time Limit for the ILP mode", context="nogui") public int timeLimit = -1; @Tunable(description="A column in the edge table containing weights", context="nogui") - public CyColumn weightColumn; + public String weightColumnName; @Tunable(description="A column containing boolean entries for edges that are to be treated as permanent",context="nogui") - public CyColumn permanentColumn; + public String permanentColumnName; @Tunable(description="A column containing boolean entries for edges that are to be treated as forbidden",context="nogui") - public CyColumn forbiddenColumn; + public String forbiddenColumnName; @Tunable(description="The default insertion cost that is to be used for non-existing edges",context="nogui") public double defaultInsertionCost = -1; @@ -48,18 +52,36 @@ 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",context="nogui") + public int clusterCount = -1; + @Override public ValidationState getValidationState(Appendable errMsg) { - if (!checkBitmask(reductionRulesBitMask)) { - try { - errMsg.append("The Bitmask provided is invalid! Needs to be six bit binary (example: 011001)"); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + System.out.println("DEBUG: Running VALIDATION of tunables"); //TODO: Move to logger (if it would work) + try { + if (net!= null) { + //Verify column validity + CyColumn weightColumn = net.getDefaultEdgeTable().getColumn(weightColumnName); + if (weightColumn == null) { + errMsg.append("Could not find a column named: "+weightColumnName+"\n"); + return ValidationState.INVALID; + } + } + if (!checkBitmask(reductionRulesBitMask)) { + 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.INVALID; + return ValidationState.OK; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } - return ValidationState.OK; + return ValidationState.INVALID; } /** @@ -79,4 +101,12 @@ public class ParameterSet implements TunableValidator return true; } + @Override + public String toString(){ + String ret = ""; + ret += "Target Cluster Count: "+clusterCount+"\n"; + //TODO + return ret; + } + } 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/help/HelpLinks.java b/src/main/java/de/hhu/ba/yoshikoWrapper/help/HelpLinks.java index 58fdf46211f98224e07e218effff8d87b35b6a45..edefa932dce4a11925351be112944e59ae126a01 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/help/HelpLinks.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/help/HelpLinks.java @@ -27,7 +27,8 @@ public final class HelpLinks { public static final HashMap<String,Object> mainInfo = new HashMap<String,Object>(); static { - mainInfo.put("url", "https://spqrph.github.io/cytoscape-tutorials/presentations/yoshiko.html#/title"); + mainInfo.put("url", "file:///home/philipp/workspace/cs/cytoscape-tutorials/presentations/yoshiko.html"); + //mainInfo.put("url", "https://spqrph.github.io/cytoscape-tutorials/presentations/yoshiko.html#/title"); } } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/ClusterEditingSolutions.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/ClusterEditingSolutions.java index 10eab6276ae28f1834ada45e49b549979c532555..ae586e770de1d3b690605f796256845df2c7054e 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/ClusterEditingSolutions.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/ClusterEditingSolutions.java @@ -59,6 +59,10 @@ public class ClusterEditingSolutions { LibraryInterfaceJNI.ClusterEditingSolutions_setFlags(swigCPtr, this, SolutionFlags.getCPtr(f), f); } + public void printSolution(long index) { + LibraryInterfaceJNI.ClusterEditingSolutions_printSolution(swigCPtr, this, index); + } + public ClusterEditingSolutions() { this(LibraryInterfaceJNI.new_ClusterEditingSolutions(), true); } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java index 82e0dee42b697daf9b2669c8a35bea80c5070fe7..227ab8a923211019d5bf0f831f9055addfadd5f1 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java @@ -25,8 +25,8 @@ public class LibraryInterface { LibraryInterfaceJNI.setVerbosity(level); } - public static CoreAlgorithm getRun(LibraryInput input, int nrOptimalSolutions, String rulesBitMask, double multiplicativeFactor, boolean useHeuristic, boolean separatePartitionCuts, boolean separateTriangles) { - long cPtr = LibraryInterfaceJNI.getRun(LibraryInput.getCPtr(input), input, nrOptimalSolutions, rulesBitMask, multiplicativeFactor, useHeuristic, separatePartitionCuts, separateTriangles); + public static CoreAlgorithm getRun(LibraryInput input, int nrOptimalSolutions, String rulesBitMask, double multiplicativeFactor, boolean useHeuristic, boolean separatePartitionCuts, boolean separateTriangles, int targetClusterCount) { + long cPtr = LibraryInterfaceJNI.getRun(LibraryInput.getCPtr(input), input, nrOptimalSolutions, rulesBitMask, multiplicativeFactor, useHeuristic, separatePartitionCuts, separateTriangles, targetClusterCount); return (cPtr == 0) ? null : new CoreAlgorithm(cPtr, false); } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java index 10744f7c6dc6ec23408e90eb9e0169dd6df0482c..49549a4b657af8b0dd0a8ef300f2319e92c77f75 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java @@ -53,6 +53,7 @@ public class LibraryInterfaceJNI { public final static native long ClusterEditingSolutions_getNumberOfSolutions(long jarg1, ClusterEditingSolutions jarg1_); public final static native long ClusterEditingSolutions_getFlags(long jarg1, ClusterEditingSolutions jarg1_); public final static native void ClusterEditingSolutions_setFlags(long jarg1, ClusterEditingSolutions jarg1_, long jarg2, SolutionFlags jarg2_); + public final static native void ClusterEditingSolutions_printSolution(long jarg1, ClusterEditingSolutions jarg1_, long jarg2); public final static native long new_ClusterEditingSolutions(); public final static native void delete_ClusterEditingSolutions(long jarg1); public final static native long new_LibraryInput(); @@ -79,7 +80,7 @@ public class LibraryInterfaceJNI { public final static native void setTimeLimit(int jarg1); public final static native void setThreadLimit(int jarg1); public final static native void setVerbosity(int jarg1); - public final static native long getRun(long jarg1, LibraryInput jarg1_, int jarg2, String jarg3, double jarg4, boolean jarg5, boolean jarg6, boolean jarg7); + public final static native long getRun(long jarg1, LibraryInput jarg1_, int jarg2, String jarg3, double jarg4, boolean jarg5, boolean jarg6, boolean jarg7, int jarg8); public static void SwigDirector_CplexInformer_updateStatus__SWIG_0(CplexInformer jself, int state) { jself.updateStatus(YoshikoState.swigToEnum(state)); 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..852cd5ec25c55dd2687d1dde4908aa871fe92302 --- /dev/null +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ClusterCountChooser.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.BoxLayout; +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(1,Integer.MAX_VALUE); + numSolutionsSetter.setValue(2); + label = new JLabel(LocalizationManager.get("nrClusters")); + + SwingUtil.addAll(this,label, numSolutionsSetter); + + BoxLayout layout = new BoxLayout(this, BoxLayout.LINE_AXIS); + this.setLayout(layout); + } + + @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/ColumnMapper.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ColumnMapper.java index ada41217a66d5f9c8265426c933e1cbb47e5997e..1f1169b514f83956a7321d793f0608d3039890ef 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ColumnMapper.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ColumnMapper.java @@ -60,7 +60,7 @@ SetCurrentNetworkListener { //Swing components - private final JComboBox<CyColumn> editingCostMapper; + private final JComboBox<CyColumn> weightMapper; private final JComboBox<CyColumn> permanentMapper; private final JComboBox<CyColumn> forbiddenMapper; @@ -79,12 +79,12 @@ SetCurrentNetworkListener //SWING COMPONENTS //Combo-Boxes that map to the CyColumns - editingCostMapper = new JComboBox<CyColumn>(); + weightMapper = new JComboBox<CyColumn>(); permanentMapper = new JComboBox<CyColumn>(); forbiddenMapper = new JComboBox<CyColumn>(); //Should only be enabled if the option is checked - editingCostMapper.setEnabled(false); + weightMapper.setEnabled(false); permanentMapper.setEnabled(false); forbiddenMapper.setEnabled(false); @@ -93,7 +93,7 @@ SetCurrentNetworkListener useMappingForb = new JCheckBox("Map edges as forbidden"); useMappingCost.addActionListener( - new EnableWhenSelectedListener(useMappingCost, editingCostMapper) + new EnableWhenSelectedListener(useMappingCost, weightMapper) ); useMappingPerm.addActionListener( new EnableWhenSelectedListener(useMappingPerm, permanentMapper) @@ -103,7 +103,7 @@ SetCurrentNetworkListener ); - SwingUtil.addAll(this,useMappingCost,editingCostMapper); + SwingUtil.addAll(this,useMappingCost,weightMapper); SwingUtil.addAll(this,useMappingPerm,permanentMapper); SwingUtil.addAll(this,useMappingForb,forbiddenMapper); @@ -117,7 +117,7 @@ SetCurrentNetworkListener .addComponent(useMappingForb) ) .addGroup(layout.createParallelGroup(Alignment.LEADING) - .addComponent(editingCostMapper) + .addComponent(weightMapper) .addComponent(permanentMapper) .addComponent(forbiddenMapper) ) @@ -127,7 +127,7 @@ SetCurrentNetworkListener layout.setVerticalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addComponent(useMappingCost) - .addComponent(editingCostMapper) + .addComponent(weightMapper) ) .addGroup(layout.createParallelGroup() .addComponent(useMappingPerm) @@ -153,18 +153,18 @@ SetCurrentNetworkListener if (net != null) { //Check if a network is loaded //Clear entries - editingCostMapper.removeAllItems(); + weightMapper.removeAllItems(); for (CyColumn c : net.getDefaultEdgeTable().getColumns()){ //Only add columns with numeric values if (c.getType() == Integer.class || c.getType() == Double.class) { - editingCostMapper.addItem(c); + weightMapper.addItem(c); } } - boolean enable = (editingCostMapper.getItemCount() > 0) ? true : false; + boolean enable = (weightMapper.getItemCount() > 0) ? true : false; useMappingCost.setEnabled(enable); if (!useMappingCost.isEnabled()) { useMappingCost.setSelected(false); - editingCostMapper.setEnabled(false); + weightMapper.setEnabled(false); } forbiddenMapper.removeAllItems(); @@ -247,7 +247,7 @@ SetCurrentNetworkListener public CyColumn getEditingCostColumn() { if (useMappingCost.isSelected()) { - return editingCostMapper.getItemAt(editingCostMapper.getSelectedIndex()); + return weightMapper.getItemAt(weightMapper.getSelectedIndex()); } return null; } 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 ccbc108a8db5bb79d4000ba07a0280b74c6a239d..b52e77685d866a4aa3c30643e17e4f4260ceae57 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 @@ -25,10 +25,9 @@ package de.hhu.ba.yoshikoWrapper.swing.components; import javax.swing.GroupLayout; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JSeparator; import javax.swing.GroupLayout.Alignment; -import org.cytoscape.model.CyColumn; - import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; @@ -40,6 +39,8 @@ public class EditCostPanel extends JPanel { private final DoubleInputField icField; private final DoubleInputField dcField; + + private final JSeparator separator; private final JLabel icLabel; private final JLabel dcLabel; @@ -59,15 +60,16 @@ public class EditCostPanel extends JPanel { icField.setText("-1.0"); icField.setToolTipText(LocalizationManager.get("icTooltip")); dcField.setText("1.0"); + + separator = new JSeparator(JSeparator.HORIZONTAL); icLabel = new JLabel(LocalizationManager.get("defaultInsertion")); dcLabel = new JLabel(LocalizationManager.get("defaultDeletion")); //Add components - SwingUtil.addAll(this,icLabel,icField); - SwingUtil.addAll(this,dcLabel,dcField); + SwingUtil.addAll(this,columnMapper,separator,icLabel,icField,dcLabel,dcField); //SwingUtil.addAll(helpButton); - SwingUtil.addAll(this,columnMapper); + //Layout @@ -76,6 +78,7 @@ public class EditCostPanel extends JPanel { layout.setHorizontalGroup(layout.createParallelGroup() //.addComponent(helpButton,Alignment.TRAILING) .addComponent(columnMapper) + .addComponent(separator) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.LEADING) .addComponent(icLabel) @@ -92,6 +95,7 @@ public class EditCostPanel extends JPanel { layout.setVerticalGroup(layout.createSequentialGroup() //.addComponent(helpButton) .addComponent(columnMapper) + .addComponent(separator) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(icLabel) .addGap(4) @@ -109,17 +113,11 @@ public class EditCostPanel extends JPanel { } //SETTER / GETTER - public CyColumn getWeightColumn() { - return columnMapper.getEditingCostColumn(); - } - - public CyColumn getPermanentColumn() { - return columnMapper.getPermanentColumn(); - } + public String getPermanentColumnName() { + return columnMapper.getPermanentColumn() != null ? columnMapper.getPermanentColumn().getName() : null; } - public CyColumn getForbiddenColumn() { - return columnMapper.getForbiddenColumn(); - } + public String getForbiddenColumnName() { + return columnMapper.getForbiddenColumn() != null ? columnMapper.getForbiddenColumn().getName() : null; } public double getDefaultInsertionCost() { return icField.getValueAsDouble(); @@ -133,4 +131,8 @@ public class EditCostPanel extends JPanel { return columnMapper; } + public String getWeightColumnName() { + return columnMapper.getEditingCostColumn() != null ? columnMapper.getEditingCostColumn().getName() : null; + } + } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/IntegerInputField.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/IntegerInputField.java index d7d337652ee5627a088f5eb4d714c69fcdc9e95a..7b39fd0bf2e1028120ba27092f8f167fc2712c3b 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/IntegerInputField.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/IntegerInputField.java @@ -34,12 +34,12 @@ public class IntegerInputField extends JFormattedTextField{ private final NumberFormatter formatter; -// public IntegerInputField(int minValue, int maxValue) { -// super(); -// formatter = FormatHelper.getIntegerFormatter(minValue,maxValue); -// this.setFormatter(formatter); -// this.setColumns(8); -// } + public IntegerInputField(int minValue, int maxValue) { + super(); + formatter = FormatHelper.getIntegerFormatter(minValue,maxValue); + this.setFormatter(formatter); + this.setColumns(8); + } public IntegerInputField() { super(); 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 b0771da0950f3cb95c9a366a511cd6ddbd8095fb..5fc0e50b3554b91bb10f23563ba2c5eae93d1e68 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 @@ -209,7 +209,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent { .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(about,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE) ) - .addGap(4) + .addGap(8) .addComponent(showAdvancedOptions,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE) .addComponent(scrollPane,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE) .addComponent(runButton,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE) @@ -228,7 +228,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent { .addComponent(header,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) .addComponent(about,Alignment.TRAILING,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) ) - .addGap(4) + .addGap(8) .addComponent(showAdvancedOptions,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) .addComponent(scrollPane,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) .addComponent(runButton,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) @@ -314,7 +314,6 @@ public class MainPanel extends JPanel implements CytoPanelComponent { if (YoshikoLoader.isLibraryLoaded()){ AbstractTask yoshiko = new AlgorithmTask( popupLevel, - networkToBeProcessed, fetchParameters(networkToBeProcessed) ); /** @@ -345,10 +344,11 @@ public class MainPanel extends JPanel implements CytoPanelComponent { */ private ParameterSet fetchParameters(CyNetwork net) { ParameterSet ret = new ParameterSet(); + ret.net = net; ret.timeLimit = opModePanel.getTimeLimit(); - ret.weightColumn = ecPanel.getWeightColumn(); - ret.permanentColumn = ecPanel.getPermanentColumn(); - ret.forbiddenColumn = ecPanel.getForbiddenColumn(); + ret.weightColumnName = ecPanel.getWeightColumnName(); + ret.permanentColumnName = ecPanel.getPermanentColumnName(); + ret.forbiddenColumnName = ecPanel.getForbiddenColumnName(); ret.defaultInsertionCost = ecPanel.getDefaultInsertionCost(); ret.defaultDeletionCost = ecPanel.getDefaultDeletionCost(); ret.useHeuristic = opModePanel.useHeuristic(); @@ -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..e49f4aed07d885cf11cb6fc030efbe902c2cee1d 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, DEFAULT_SIZE) .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 eab819be1f5b29b128c855e53f36b9b328fc19e9..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; @@ -185,7 +184,7 @@ NetworkAboutToBeDestroyedListener verticalGroup .addComponent(marker,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) .addComponent(invalidLabel,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE) - .addComponent(tabbedPane,PREFERRED_SIZE, DEFAULT_SIZE,Short.MAX_VALUE) + .addComponent(tabbedPane,DEFAULT_SIZE, DEFAULT_SIZE,DEFAULT_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(destroyButton,DEFAULT_SIZE, DEFAULT_SIZE,PREFERRED_SIZE); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/SolutionTab.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/SolutionTab.java index 104d39ae14275af3f91d1aad40f72f308e7af8b1..83a7ef3ae76973f81b6a4bf2d751de1de2a89d9a 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/SolutionTab.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/SolutionTab.java @@ -203,27 +203,32 @@ public class SolutionTab extends JPanel { layout = new GroupLayout(this); layout.setHorizontalGroup(layout.createParallelGroup(Alignment.CENTER,true) + .addComponent(createClusterView,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) + .addComponent(createMetaGraph,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) .addGap(8) .addComponent(clusterCount,DEFAULT_SIZE,DEFAULT_SIZE,Short.MAX_VALUE) .addComponent(hideSingles,DEFAULT_SIZE,DEFAULT_SIZE,Short.MAX_VALUE) .addGap(8) .addComponent(scrollPane,PREFERRED_SIZE,PREFERRED_SIZE,Short.MAX_VALUE) - .addComponent(createClusterView,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) - .addComponent(createMetaGraph,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) + .addGap(4) ); layout.setVerticalGroup(layout.createSequentialGroup() + .addComponent(createClusterView,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) + .addComponent(createMetaGraph,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) .addGap(8) .addComponent(clusterCount,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) .addComponent(hideSingles,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) - .addGap(8) - .addComponent(scrollPane,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) - .addComponent(createClusterView,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) - .addComponent(createMetaGraph,DEFAULT_SIZE,DEFAULT_SIZE,DEFAULT_SIZE) + .addGap(4) + .addComponent(scrollPane,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) + .addGap(4) ); this.setLayout(layout); } + /** + * Simply disables the CCV and CMG graph to visually highlight the fact that those tasks are no longer possible + */ public void invalidateResult() { createClusterView.setEnabled(false); createMetaGraph.setEnabled(false); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java b/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java index dc9e5cc66d1be0ab208b55a210d73e4f931d7335..ebd95002c5446435990241db14abeee6ce3b0b02 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java @@ -45,7 +45,6 @@ public class CommandTaskFactory implements TaskFactory{ else if (command == YoshikoCommand.PERFORM_ALGORITHM) { return new TaskIterator( new AlgorithmTask( - null, null, new ParameterSet() ) 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 d764f9e387b34b9411110f0fd78a14efcfbc81f4..1f252f95c85a0038134f0717efd2e7816061b5ea 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java @@ -30,13 +30,13 @@ 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.CyNetwork; +import org.cytoscape.model.CyColumn; import org.cytoscape.model.CyNode; import org.cytoscape.work.AbstractTask; import org.cytoscape.work.ContainsTunables; import org.cytoscape.work.ObservableTask; import org.cytoscape.work.TaskMonitor; -import org.cytoscape.work.Tunable; +import org.cytoscape.work.TunableValidator; import org.slf4j.Logger; import de.hhu.ba.yoshikoWrapper.core.CyCore; @@ -58,7 +58,7 @@ import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface; import de.hhu.ba.yoshikoWrapper.swing.components.ResultPanel; -public class AlgorithmTask extends AbstractTask implements ObservableTask { +public class AlgorithmTask extends AbstractTask implements ObservableTask, TunableValidator { //Constants private static final String SOLUTION_COLUMN_PREFIX = "yoshikoSolution_"; //TODO: Make customizable? @@ -77,8 +77,7 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { @ContainsTunables public ParameterSet parameterSet = null; - @Tunable(description="Network to analyze for clusters", context="nogui") - public CyNetwork net = CyCore.cy.getCurrentNetwork(); + //Temps, pointing to and need to be freed in C++ private LibraryInput c_input; @@ -98,12 +97,10 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { */ public AlgorithmTask( Window statusWindow, - CyNetwork net, ParameterSet parameterSet ) { this.statusWindow = statusWindow; - this.net = net; this.parameterSet = parameterSet; } @@ -115,8 +112,8 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { taskMonitor.setTitle(LocalizationManager.get("yoshTask")); taskMonitor.setProgress(0.0); - //Get current network - if (net == null) { + //Check current network + if (parameterSet.net == null) { logger.warn("CoreAlgorithm called on a net that is NULL!"); throw new Exception("CoreAlgorithm called on a net that is NULL!"); //TODO: Localize } @@ -131,25 +128,30 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { } //Create a node map to identify nodes and eges in the solution - NodeMap nodeMap = new NodeMap(net); + NodeMap nodeMap = new NodeMap(parameterSet.net); taskMonitor.setProgress(0.1); + //We identify the columns if they exist from their given names + CyColumn weightColumn = parameterSet.weightColumnName != null ? parameterSet.net.getDefaultEdgeTable().getColumn(parameterSet.weightColumnName) : null; + CyColumn permanentColumn = parameterSet.permanentColumnName != null ? parameterSet.net.getDefaultEdgeTable().getColumn(parameterSet.permanentColumnName) : null; + CyColumn forbiddenColumn = parameterSet.forbiddenColumnName != null ? parameterSet.net.getDefaultEdgeTable().getColumn(parameterSet.forbiddenColumnName) : null; + //Generate an c_input instance from the network c_input = NetworkParser.parseNetwork( - net, + parameterSet.net, nodeMap, - parameterSet.weightColumn, - parameterSet.permanentColumn, - parameterSet.forbiddenColumn, + weightColumn, + permanentColumn, + forbiddenColumn, parameterSet.defaultDeletionCost ); taskMonitor.setProgress(0.2); boolean containsRealValues = GraphAnalyzer.containsRealValues( - net, - parameterSet.weightColumn, - parameterSet.permanentColumn, - parameterSet.forbiddenColumn, + parameterSet.net, + weightColumn, + permanentColumn, + forbiddenColumn, parameterSet.defaultInsertionCost, parameterSet.defaultDeletionCost); @@ -161,6 +163,8 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { //Set the default value for insertion cost c_input.setDefaultInsertionCost(parameterSet.defaultInsertionCost); + System.out.print(parameterSet.toString()); //TODO: Move to debug logger + //Call Yoshiko <<< Algorithm is performed here c_algorithm = LibraryInterface.getRun(c_input, parameterSet.solCount, @@ -168,7 +172,8 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { parameterSet.snrMultFactor, parameterSet.useHeuristic, parameterSet.usePartitionCuts, - parameterSet.useTriangleCuts + parameterSet.useTriangleCuts, + parameterSet.clusterCount ); @@ -184,7 +189,7 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { taskMonitor.setStatusMessage("Found: "+numberOfSolutions+" solutions!"); //TODO: Localize - result = new YoshikoResult(net,c_result.getFlags()); + result = new YoshikoResult(parameterSet.net,c_result.getFlags()); //Loop over (multiple) solutions for (long i=0;i<numberOfSolutions;i++) { @@ -195,8 +200,8 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { String columnName = SOLUTION_COLUMN_PREFIX+(i+1); - net.getDefaultNodeTable().deleteColumn(columnName); - net.getDefaultNodeTable().createColumn(columnName, String.class, false); + parameterSet.net.getDefaultNodeTable().deleteColumn(columnName); + parameterSet.net.getDefaultNodeTable().createColumn(columnName, String.class, false); //Fetch number of clusters in the solution long numberOfClusters = c_result.getNumberOfClusters(i); @@ -218,7 +223,7 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { CyNode node = nodeMap.indexOf(nodeID); //<<< Another int/long conversion cluster.addNode(node); - net.getRow(node).set(columnName, ""+(k+1)); //Add Cluster ID in table (Remove in final version?) + parameterSet.net.getRow(node).set(columnName, ""+(k+1)); //Add Cluster ID in table (Remove in final version?) } //Register clusters with solution for further reference solution.addCluster(cluster); @@ -259,7 +264,13 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { } + /** + * 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")); @@ -308,4 +319,10 @@ public class AlgorithmTask extends AbstractTask implements ObservableTask { } return null; } + + @Override + public ValidationState getValidationState(Appendable errMsg) { + //In order to validate the arguments for this task we simply check the ParameterSet + return parameterSet.getValidationState(errMsg); + } } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViewsTask.java b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViewsTask.java index 72d6270300e9c7cb0f846599e7681cd24cc4245c..0531fa72a63ae661e5e6889ad1200edce2c8cc24 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViewsTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViewsTask.java @@ -22,6 +22,10 @@ public class CreateClusterViewsTask implements Task { @Tunable public ArrayList<YoshikoCluster> clusters; //TODO: Make Tunable, reference by ID? + /** + * Killswitch, used to determine if the algorithm has been terminated. + * We can use this to cancel at a given point (so we don't need to finish the entire task) + */ private boolean isTerminated; /** @@ -77,11 +81,8 @@ public class CreateClusterViewsTask implements Task { StyleManager.style(subnetView,CyCore.visualMappingManager.getCurrentVisualStyle()); CyCore.networkViewManager.addNetworkView(subnetView); } - } ); - - } } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateMetaGraphTask.java b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateMetaGraphTask.java index 1f24dea291ab3a44cd99620a3e77873ec348e0d3..dd1c24e4b543ed1fa48a5b106ed32d1e00f0b748 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateMetaGraphTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateMetaGraphTask.java @@ -20,6 +20,8 @@ import de.hhu.ba.yoshikoWrapper.cytoUtil.StyleManager; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoSolution; +//TODO: Should also not be possible / throw an exception if the result was invalidated (might currently just be disabled via GUI) + public class CreateMetaGraphTask extends AbstractTask{ private final YoshikoSolution solution; @@ -94,7 +96,7 @@ public class CreateMetaGraphTask extends AbstractTask{ //Link clusters node in meta graph and subnet graph to use Cytoscape Nested Network feature clusterNode.setNetworkPointer(subnet); //Set node attributes - metaGraph.getRow(clusterNode).set("name", LocalizationManager.get("clusters")+" "+c.getID()); + metaGraph.getRow(clusterNode).set("name", LocalizationManager.get("clusters")+" "+(c.getID()+1)); metaGraph.getRow(clusterNode).set(StyleManager.CLUSTERSIZE_COLUMN_NAME,c.getSize()); map.put(c, clusterNode); } @@ -105,12 +107,13 @@ public class CreateMetaGraphTask extends AbstractTask{ taskMonitor.setStatusMessage(LocalizationManager.get("metaGraph_edges")); Iterator<YoshikoCluster> it1 = solution.getClusters().iterator(); - Iterator<YoshikoCluster> it2 = solution.getClusters().iterator(); while (it1.hasNext()) { YoshikoCluster c1 = it1.next(); + Iterator<YoshikoCluster> it2 = solution.getClusters().iterator(); while(it2.hasNext()) { YoshikoCluster c2 = it2.next(); + System.out.println("Debug: Processing edges between cluster "+c1.getID()+" and "+c2.getID()); if(isTerminated) { throw new Exception("Terminated by user!"); @@ -126,7 +129,9 @@ public class CreateMetaGraphTask extends AbstractTask{ for (CyNode c1n : c1.getSubNetwork().getNodeList()) { for (CyNode c2n : c2.getSubNetwork().getNodeList()) { if (solution.getOriginalGraph().containsEdge(c1n, c2n) || solution.getOriginalGraph().containsEdge(c2n, c1n)) { + System.out.println("Debug: Found relevant edge from "+c1n.getSUID()+ " to "+c2n.getSUID()); if (!metaGraph.containsEdge(map.get(c1), map.get(c2))){ + System.out.println("We create a new edge for it"); CyEdge edge = metaGraph.addEdge(map.get(c1), map.get(c2), false); metaGraph.getRow(edge).set(StyleManager.EDGESTRENGTH_COLUMN_NAME,1); } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/GetClustersTask.java b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/GetClustersTask.java index 0afa05ee33f92ccef1c46a09cdcccb6cfd4ba1c5..6a49b1ec30360ba2c7587d1d3d934301bb991b51 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/GetClustersTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/GetClustersTask.java @@ -9,16 +9,32 @@ import org.cytoscape.work.Tunable; import de.hhu.ba.yoshikoWrapper.core.ResultList; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoResult; -import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoSolution; +/** + * A task that retrieves the clusters associated with a given solution in a given result. This is meant to be used via CyRest / command line functionality exclusively + * + * @author Philipp Spohr, Dec 12, 2017 + * + */ public class GetClustersTask implements ObservableTask { + + /** + * The ID of the result for which the clusters are to be retrieved + */ @Tunable(description="The result ID for which the solutions should be displayed", context="nogui") public int resultID = -1; + /** + * The ID of the solution for which the clusters are to be retrieved + */ @Tunable(description="The solution ID for which the solutions should be displayed", context="nogui") public long solutionID = -1; + + /** + * The clusters as a collection when they are retrieved + */ private Collection<YoshikoCluster> clusters; @Override diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/GetSolutionsTask.java b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/GetSolutionsTask.java index b36ef963bb0ea5351638f4897718f6e571fa21f3..b4d60d6e441b55b250880ebb1c2d5eaf55444051 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/GetSolutionsTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/GetSolutionsTask.java @@ -10,11 +10,23 @@ import de.hhu.ba.yoshikoWrapper.core.ResultList; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoResult; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoSolution; +/** + * Basic task that retrieves solutions associated with a run (result) + * This is meant to be invoked from cmd / CyRest exclusively to receive solution IDs + * @author Philipp Spohr, Dec 12, 2017 + * + */ public class GetSolutionsTask implements ObservableTask { + /** + * The result ID for the result/run for which the solutions are to be retrieved + */ @Tunable(description="The result ID for which the solutions should be displayed", context="nogui") public int resultID = -1; + /** + * The solutions as a collection in case the task was successful + */ private Collection<YoshikoSolution> solutions; @Override @@ -27,9 +39,7 @@ public class GetSolutionsTask implements ObservableTask { } @Override - public void cancel() { - // TODO Auto-generated method stub - } + public void cancel() {} //There is nothing here that remains in an instable state as we are simply reading / retrieving data @SuppressWarnings("unchecked") @Override @@ -44,4 +54,5 @@ public class GetSolutionsTask implements ObservableTask { return null; } + } diff --git a/src/main/resources/YoshikoStrings.properties b/src/main/resources/YoshikoStrings.properties index b20a177a70f2a91e877d6071906459d786118ec7..c123781d3c6361033c37b6a20c09f495d710fc8e 100644 --- a/src/main/resources/YoshikoStrings.properties +++ b/src/main/resources/YoshikoStrings.properties @@ -61,7 +61,7 @@ libraryPanel = Library metaGraph = Meta Graph metaGraph_edges = Fetching edges and calculating edge strengths multFactor = Multiplicative Factor for SNR: -multiGraphWarning = This graph is a multigraph. This algorithms behavior on multigraphs is not yet researched. +multiGraphWarning = This graph is a multigraph. Running Yoshiko on the corresponding simple graph... networkParsingException: An error occured while parsing the network: noFeasible = No feasible solution found! @@ -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: