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 87da79a3c3a696e288a56a4ae30390e1f11bf963..753d5bb3f4ce91fe61c17142c67b0d847896a861 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/ParameterSet.java @@ -22,5 +22,7 @@ public class ParameterSet { public boolean useHeuristic; public int solCount; public boolean disableMultiThreading; + /**Describes whether auto configuration of the reduction rules is to be used. Overrides the bit mask.**/ + public boolean suggestReduction; } 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 dfc6d39ea6efbcff99994b46f3b760d66d3610ca..51c1dafca4c2ad4ca4b6d1358563520ce860b464 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/cytoUtil/GraphAnalyzer.java @@ -2,10 +2,19 @@ package de.hhu.ba.yoshikoWrapper.cytoUtil; import java.util.List; +import org.cytoscape.model.CyColumn; import org.cytoscape.model.CyEdge; import org.cytoscape.model.CyNetwork; +import org.cytoscape.model.CyRow; +import org.slf4j.Logger; + +import de.hhu.ba.yoshikoWrapper.logging.YoshikoLogger; + public class GraphAnalyzer { + + private static Logger logger = YoshikoLogger.getInstance().getLogger(); + public static boolean isMultiGraph(CyNetwork net) { //TODO: Better algorithm? @@ -47,4 +56,87 @@ public class GraphAnalyzer { } return false; } + + /** + * Generates a fitting bitmask by choosing the reduction rules that appear to be the best choice based on current research + * @param containsRealValues + * @param heuristic + * @return + */ + public static String suggestReductionRules(boolean containsRealValues, boolean heuristic) { + + //TODO: Maybe also choose SNR Factor? + //TODO: More research, identify good rules + + boolean useCRule = false,useCCRule= false,useACRule= false,useHERule= false,usePDRRule= false,useSNRule = false; + String ret = ""; + + //First of all: We don't choose any rules when in heuristic mode + if (!heuristic) { + //We check if the graph contains real weights + if (!containsRealValues) { + useCRule = true; + useCCRule = true; + useACRule = true; + useHERule = true; + } + usePDRRule = true; + useSNRule = true; + } + + ret += (useCRule ? "1" : "0"); + ret += (useCCRule ? "1" : "0"); + ret += (useACRule ? "1" : "0"); + ret += (useHERule ? "1" : "0"); + ret += (usePDRRule ? "1" : "0"); + ret += (useSNRule ? "1" : "0"); + + //logger.info("Suggesting the following reduction-rules bitmask: "+ret); + System.out.println("Suggesting the following reduction-rules bitmask: "+ret); + + return ret; + } + + public static boolean containsRealValues( + CyNetwork net, + CyColumn weightColumn, + CyColumn permanentColumn, + CyColumn forbiddenColumn, + double defaultInsertionCost, + double defaultDeletionCost) + { + //Simple checks: Deletion and Insertion Costs + if (defaultInsertionCost % 1 != 0 || defaultDeletionCost % 1 != 0) { + return true; + } + + if (net != null){ + //Fetch edges + List<CyEdge> edges = net.getEdgeList(); + + //Loop over edges + for (CyEdge e : edges) { + + //Fetch entry and check if it exists + CyRow edgeEntry = net.getRow(e); + + //Check if there is a weight column defined, else skip + if (weightColumn != null){ + //Check if the column contains an entry for the respective edge + //It is possible, that there are missing entries + if (edgeEntry.get(weightColumn.getName(), weightColumn.getType()) != null){ + if (weightColumn.getType() == Double.class) { + double weight = edgeEntry.get(weightColumn.getName(), Double.class); + if (weight%1!=0) { + return true; + } + } + } + } + } + } + return false; + } + + } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoResult.java b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoResult.java index b2441e51e7f980f045986c10438796b23d953dae..7394b3efaf5d4b92ba579d8d3b55722a82fffe70 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoResult.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoResult.java @@ -31,7 +31,7 @@ import de.hhu.ba.yoshikoWrapper.swig.SolutionFlags; /**Basic data class that represents a CES instance internally. By using this class the C++ resources can be freed upon retrieval. * */ -public class YoshikoResult { +public class YoshikoResult{ private CyNetwork originalGraph; 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 2ee951a40ec47fb72e35de0dfb8d5f3263197868..ccbc108a8db5bb79d4000ba07a0280b74c6a239d 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 @@ -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 @@ -34,47 +34,47 @@ import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; @SuppressWarnings("serial") //Will never be serialized public class EditCostPanel extends JPanel { - + //SWING COMPONENTS private final ColumnMapper columnMapper; - + private final DoubleInputField icField; private final DoubleInputField dcField; - + private final JLabel icLabel; private final JLabel dcLabel; - - private final HelpButton helpButton; - + + //private final HelpButton helpButton; + public EditCostPanel() { //Initialize components - helpButton = new HelpButton(); - + //helpButton = new HelpButton(); + columnMapper = new ColumnMapper(); - + icField = new DoubleInputField(Double.NEGATIVE_INFINITY,0); dcField = new DoubleInputField(0,Double.POSITIVE_INFINITY); - + icField.setText("-1.0"); icField.setToolTipText(LocalizationManager.get("icTooltip")); dcField.setText("1.0"); - + 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(helpButton); + //SwingUtil.addAll(helpButton); SwingUtil.addAll(this,columnMapper); - + //Layout GroupLayout layout = new GroupLayout(this); - + layout.setHorizontalGroup(layout.createParallelGroup() - .addComponent(helpButton,Alignment.TRAILING) + //.addComponent(helpButton,Alignment.TRAILING) .addComponent(columnMapper) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.LEADING) @@ -88,9 +88,9 @@ public class EditCostPanel extends JPanel { ) ) ); - + layout.setVerticalGroup(layout.createSequentialGroup() - .addComponent(helpButton) + //.addComponent(helpButton) .addComponent(columnMapper) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(icLabel) @@ -103,20 +103,20 @@ public class EditCostPanel extends JPanel { .addComponent(dcField) ) ); - + this.setLayout(layout); - + } //SETTER / GETTER public CyColumn getWeightColumn() { return columnMapper.getEditingCostColumn(); } - + public CyColumn getPermanentColumn() { return columnMapper.getPermanentColumn(); } - + public CyColumn getForbiddenColumn() { return columnMapper.getForbiddenColumn(); } @@ -124,7 +124,7 @@ public class EditCostPanel extends JPanel { public double getDefaultInsertionCost() { return icField.getValueAsDouble(); } - + public double getDefaultDeletionCost() { return dcField.getValueAsDouble(); } @@ -132,5 +132,5 @@ public class EditCostPanel extends JPanel { public ColumnMapper getColumnMapper() { return columnMapper; } - + } 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 5c521c5319b22c3e908887d83e34784ede30649f..c14921df077395293038e273d2af5b8d6227c611 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 @@ -58,7 +58,9 @@ import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.core.ParameterSet; import de.hhu.ba.yoshikoWrapper.core.YoshikoLoader; +import de.hhu.ba.yoshikoWrapper.cytoUtil.CommandExecutor; import de.hhu.ba.yoshikoWrapper.cytoUtil.GraphAnalyzer; +import de.hhu.ba.yoshikoWrapper.help.HelpLinks; import de.hhu.ba.yoshikoWrapper.swing.GraphicsLoader; import de.hhu.ba.yoshikoWrapper.swing.LibraryPanelFactory; import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; @@ -117,7 +119,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent { @Override public void actionPerformed(ActionEvent e) { - //CommandExecutorTaskFactory fac; + CommandExecutor.executeCommand("cybrowser", "show",HelpLinks.mainInfo , null); } }); @@ -312,7 +314,7 @@ public class MainPanel extends JPanel implements CytoPanelComponent { AbstractTask yoshiko = new AlgorithmTask( popupLevel, networkToBeProcessed, - fetchParameter() + fetchParameters(networkToBeProcessed) ); /** * Don't queue multiple runs at once because that will get messy @@ -340,7 +342,7 @@ 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() { + private ParameterSet fetchParameters(CyNetwork net) { ParameterSet ret = new ParameterSet(); ret.timeLimit = opModePanel.getTimeLimit(); ret.weightColumn = ecPanel.getWeightColumn(); @@ -348,11 +350,12 @@ public class MainPanel extends JPanel implements CytoPanelComponent { ret.forbiddenColumn = ecPanel.getForbiddenColumn(); ret.defaultInsertionCost = ecPanel.getDefaultInsertionCost(); ret.defaultDeletionCost = ecPanel.getDefaultDeletionCost(); + ret.useHeuristic = opModePanel.useHeuristic(); ret.reductionRulesBitMask = reductionRulesChooser.getBitMask(); + ret.suggestReduction = reductionRulesChooser.useAutoConfig(); ret.snrMultFactor = reductionRulesChooser.getMultFactor(); ret.useTriangleCuts = opModePanel.useTriangleCuts(); ret.usePartitionCuts = opModePanel.usePartitionCuts(); - ret.useHeuristic = opModePanel.useHeuristic(); ret.solCount = opModePanel.getSolCount(); ret.disableMultiThreading = opModePanel.isMultiThreadingDisabled(); return ret; diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ReductionRulesChooser.java b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ReductionRulesChooser.java index cd7a02a091363e6f65a7623bde842944442905b3..4697947ac309f1a3eccfd26eba99622f933c1786 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ReductionRulesChooser.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swing/components/ReductionRulesChooser.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,12 +25,16 @@ import static javax.swing.GroupLayout.DEFAULT_SIZE; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import javax.swing.BoxLayout; import javax.swing.GroupLayout; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SwingConstants; import javax.swing.GroupLayout.Alignment; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; @@ -39,40 +43,54 @@ import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; @SuppressWarnings("serial") public class ReductionRulesChooser extends JPanel{ + private final JCheckBox useAutoConfig; + + private final JSeparator separator; + private final JCheckBox useCRule; private final JCheckBox useCCRule; private final JCheckBox useACRule; private final JCheckBox useHERule; private final JCheckBox usePDRRule; private final JCheckBox useSNRule; - + private final DoubleInputField multFactor; - + private final JPanel SNPanel; - + public ReductionRulesChooser() { //Initialize subcomponents + useAutoConfig = new JCheckBox(LocalizationManager.get("autoConfig")); + useAutoConfig.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + enableRuleSelection(e.getStateChange()== ItemEvent.DESELECTED ? true : false); + } + + }); + separator = new JSeparator(SwingConstants.HORIZONTAL); + //TODO: Localization useCRule = new JCheckBox("Use Clique Rule"); useCCRule = new JCheckBox("Use Critical-Clique Rule"); useACRule = new JCheckBox("Use Almost-Clique Rule"); useHERule = new JCheckBox("Use Heavy-Edge 3 in 1 Rule"); usePDRRule = new JCheckBox("Use Parameter Dependent Reduction Rule"); useSNRule = new JCheckBox("Use Similar Neighborhood Rule"); + multFactor = new DoubleInputField(1, Double.POSITIVE_INFINITY); multFactor.setText("1.0"); + SNPanel = new JPanel(); SNPanel.setLayout(new BoxLayout(SNPanel,BoxLayout.X_AXIS)); + SwingUtil.addAll(SNPanel,new JLabel(LocalizationManager.get("multFactor")),multFactor); - - useSNRule.setSelected(true); - useCRule.setSelected(true); - useCCRule.setSelected(true); - useACRule.setSelected(true); - useHERule.setSelected(true); - usePDRRule.setSelected(true); - + + enableRuleSelection(false); + useAutoConfig.setSelected(true); + useSNRule.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -84,9 +102,11 @@ public class ReductionRulesChooser extends JPanel{ } } }); - - + + SwingUtil.addAll(this, + useAutoConfig, + separator, useCRule, useCCRule, useACRule, @@ -95,23 +115,27 @@ public class ReductionRulesChooser extends JPanel{ useSNRule, SNPanel ); - + //Layout GroupLayout layout = new GroupLayout(this); - + layout.setAutoCreateGaps(true); - + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING,true) + .addComponent(useAutoConfig, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(separator, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(useCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(useCCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(useCCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(useACRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(useHERule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(usePDRRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(useSNRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(SNPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(SNPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) ); - + layout.setVerticalGroup(layout.createSequentialGroup() + .addComponent(useAutoConfig, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(separator, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(useCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(useCCRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(useACRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) @@ -120,12 +144,23 @@ public class ReductionRulesChooser extends JPanel{ .addComponent(useSNRule, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(SNPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) ); - + this.setLayout(layout); - + } - - + + + protected void enableRuleSelection(boolean enable) { + useCRule.setEnabled(enable); + useCCRule.setEnabled(enable); + useACRule.setEnabled(enable); + useHERule.setEnabled(enable); + usePDRRule.setEnabled(enable); + useSNRule.setEnabled(enable); + multFactor.setEnabled(enable); + } + + /** Creates a 6 Bit bitmask representing the currently selected choice of reduction rules. * @return */ @@ -139,7 +174,11 @@ public class ReductionRulesChooser extends JPanel{ ret += (useSNRule.isSelected() ? "1" : "0"); return ret; } - + + public boolean useAutoConfig() { + return useAutoConfig.isSelected(); + } + public double getMultFactor() { if (useSNRule.isSelected()) { return multFactor.getValueAsDouble(); 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 e698fb2f39404732fca7dbb7666d61d02ed7d342..e8e92cf4f5d83908ccd7058653a685c152cc8af6 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 @@ -51,7 +51,7 @@ import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoSolution; import de.hhu.ba.yoshikoWrapper.swing.SwingUtil; -import de.hhu.ba.yoshikoWrapper.tasks.CreateClusterViews; +import de.hhu.ba.yoshikoWrapper.tasks.CreateClusterViewsTask; import de.hhu.ba.yoshikoWrapper.tasks.CreateMetaGraphTask; /** * Swing Component, that represents one solution of a Yoshiko result and displays it @@ -149,7 +149,7 @@ public class SolutionTab extends JPanel { } CyCore.dialogTaskManager.execute( new TaskIterator(1, - new CreateClusterViews( + new CreateClusterViewsTask( selectedClusters ) ) 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 f340ed6b14ed06c4ab631c7362c01711e94894f2..6dcc7d1f1988b7b7e0ec80ccf57d0cd5faddac34 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/taskFactories/CommandTaskFactory.java @@ -3,7 +3,9 @@ package de.hhu.ba.yoshikoWrapper.taskFactories; import org.cytoscape.work.TaskFactory; import org.cytoscape.work.TaskIterator; +import de.hhu.ba.yoshikoWrapper.core.ParameterSet; import de.hhu.ba.yoshikoWrapper.tasks.AlgorithmTask; +import de.hhu.ba.yoshikoWrapper.tasks.CreateClusterViewsTask; public class CommandTaskFactory implements TaskFactory{ @@ -21,7 +23,11 @@ public class CommandTaskFactory implements TaskFactory{ public TaskIterator createTaskIterator() { //We simply switch between the possible commands if (command == YoshikoCommand.CREATE_CLUSTER_VIEW) { - return null; + return new TaskIterator( + new CreateClusterViewsTask( + null + ) + ); } else if (command == YoshikoCommand.CREATE_META_GRAPH) { return null; @@ -31,7 +37,7 @@ public class CommandTaskFactory implements TaskFactory{ new AlgorithmTask( null, 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 c7e2a583e758d986056a7c5d3a28066cf79e15d8..0535700545e8dd0835df9fc31449ddbb00bd38bf 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/AlgorithmTask.java @@ -32,6 +32,7 @@ import org.cytoscape.model.CyNetwork; 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.slf4j.Logger; @@ -41,6 +42,7 @@ import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.core.NetworkParser; import de.hhu.ba.yoshikoWrapper.core.ParameterSet; import de.hhu.ba.yoshikoWrapper.core.StatusInformer; +import de.hhu.ba.yoshikoWrapper.cytoUtil.GraphAnalyzer; import de.hhu.ba.yoshikoWrapper.cytoUtil.NodeMap; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoResult; @@ -54,7 +56,7 @@ import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface; import de.hhu.ba.yoshikoWrapper.swing.components.ResultPanel; -public class AlgorithmTask extends AbstractTask { +public class AlgorithmTask extends AbstractTask implements ObservableTask { //Constants private static final String SOLUTION_COLUMN_PREFIX = "yoshikoSolution_"; //TODO: Make customizable? @@ -77,12 +79,15 @@ public class AlgorithmTask extends AbstractTask { public CyNetwork net; //Temps, pointing to and need to be freed in C++ - private LibraryInput input; - private ClusterEditingSolutions result; - private CoreAlgorithm ca; + private LibraryInput c_input; + private ClusterEditingSolutions c_result; + private CoreAlgorithm c_algorithm; private ResultPanel resultPanel; + private YoshikoResult result; + + /** * Default constructor, creates a new AlgorithmTask * @param statusWindow The Window in which the status-bar is to be shown, can be null @@ -111,7 +116,7 @@ public class AlgorithmTask extends AbstractTask { //Get current network if (net == null) { logger.warn("CoreAlgorithm called on a net that is NULL!"); - throw new Exception("CoreAlgorithm called on a net that is NULL!"); + throw new Exception("CoreAlgorithm called on a net that is NULL!"); //TODO: Localize } //Set time limit @@ -127,8 +132,8 @@ public class AlgorithmTask extends AbstractTask { NodeMap nodeMap = new NodeMap(net); taskMonitor.setProgress(0.1); - //Generate an input instance from the network - input = NetworkParser.parseNetwork( + //Generate an c_input instance from the network + c_input = NetworkParser.parseNetwork( net, nodeMap, parameterSet.weightColumn, @@ -138,11 +143,24 @@ public class AlgorithmTask extends AbstractTask { ); taskMonitor.setProgress(0.2); + boolean containsRealValues = GraphAnalyzer.containsRealValues( + net, + parameterSet.weightColumn, + parameterSet.permanentColumn, + parameterSet.forbiddenColumn, + parameterSet.defaultInsertionCost, + parameterSet.defaultDeletionCost); + + //Suggest reduction rules + if (parameterSet.suggestReduction) { + parameterSet.reductionRulesBitMask = GraphAnalyzer.suggestReductionRules(containsRealValues, parameterSet.useHeuristic); + } + //Set the default value for insertion cost - input.setDefaultInsertionCost(parameterSet.defaultInsertionCost); + c_input.setDefaultInsertionCost(parameterSet.defaultInsertionCost); //Call Yoshiko <<< Algorithm is performed here - ca = LibraryInterface.getRun(input, + c_algorithm = LibraryInterface.getRun(c_input, parameterSet.solCount, parameterSet.reductionRulesBitMask, parameterSet.snrMultFactor, @@ -152,26 +170,26 @@ public class AlgorithmTask extends AbstractTask { ); - ca.registerCplexInformer(new StatusInformer(statusWindow,taskMonitor)); + c_algorithm.registerCplexInformer(new StatusInformer(statusWindow,taskMonitor)); - result = ca.run(); + c_result = c_algorithm.run(); taskMonitor.setProgress(0.9); - checkForInvalidSolutions(result); + checkForInvalidSolutions(c_result); - long numberOfSolutions = result.getNumberOfSolutions(); + long numberOfSolutions = c_result.getNumberOfSolutions(); taskMonitor.setStatusMessage("Found: "+numberOfSolutions+" solutions!"); //TODO: Localize - YoshikoResult yoshikoResult = new YoshikoResult(net,result.getFlags()); + result = new YoshikoResult(net,c_result.getFlags()); //Loop over (multiple) solutions for (long i=0;i<numberOfSolutions;i++) { taskMonitor.setStatusMessage("Processing solution "+(i+1)+" of "+numberOfSolutions); - YoshikoSolution solution = new YoshikoSolution(yoshikoResult,i); + YoshikoSolution solution = new YoshikoSolution(result,i); String columnName = SOLUTION_COLUMN_PREFIX+(i+1); @@ -179,7 +197,7 @@ public class AlgorithmTask extends AbstractTask { net.getDefaultNodeTable().createColumn(columnName, String.class, false); //Fetch number of clusters in the solution - long numberOfClusters = result.getNumberOfClusters(i); + long numberOfClusters = c_result.getNumberOfClusters(i); //Loop over clusters for (long k=0;k<numberOfClusters;k++) { @@ -189,7 +207,7 @@ public class AlgorithmTask extends AbstractTask { taskMonitor.setStatusMessage("Processing clusters "+(k+1)+" of "+numberOfClusters); - IntVector clusterVector = result.getCluster(i, k); + IntVector clusterVector = c_result.getCluster(i, k); long sizeOfCluster = clusterVector.size(); for (int l=0;l<sizeOfCluster;l++) { //Unsafe mismatch int long @@ -205,18 +223,18 @@ public class AlgorithmTask extends AbstractTask { } //Sort clusters by size, descending as the biggest clusters are usually the most relevant solution.clusters.sort(YoshikoCluster.lessThanComparator); - //Register solution with result for further reference - yoshikoResult.addSolution(solution); + //Register solution with c_result for further reference + result.addSolution(solution); } taskMonitor.setProgress(0.99); //At this point the C++ objects can be freed, in case that the algorithm terminates beforehand they need to be cleaned-up elsewhere - ca.delete(); - input.delete(); - result.delete(); + c_algorithm.delete(); + c_input.delete(); + c_result.delete(); //Generate solutionsPanel - resultPanel = new ResultPanel(yoshikoResult); + resultPanel = new ResultPanel(result); //Show solution panel CyCore.registrar.registerService(resultPanel,CytoPanelComponent.class, new Properties()); @@ -231,16 +249,16 @@ public class AlgorithmTask extends AbstractTask { private void checkForInvalidSolutions(ClusterEditingSolutions result) throws Exception { if (result == null) { - //There was no result object generated at all + //There was no c_result object generated at all throw new Exception(LocalizationManager.get("noFeasible")); } if (result.getNumberOfSolutions() == 0) { - //The result object is empty + //The c_result object is empty throw new Exception(LocalizationManager.get("noFeasible")); } if (result.getNumberOfSolutions() == 1) { - //The result doesn't contain any clusters + //The c_result doesn't contain any clusters if (result.getNumberOfClusters(0) == 0) { throw new Exception(LocalizationManager.get("noFeasible")); } @@ -251,21 +269,30 @@ public class AlgorithmTask extends AbstractTask { @Override public void cancel() { //Free C++ resources - if (ca != null) { + if (c_algorithm != null) { System.out.println("Deleting CoreAlgorithm instance!"); - ca.cancel(); - ca.delete(); + c_algorithm.cancel(); + c_algorithm.delete(); } - if (input != null) { - input.delete(); + if (c_input != null) { + c_input.delete(); } - if (result != null) { - result.delete(); + if (c_result != null) { + c_result.delete(); } - //Delete (incomplete) result panel + //Delete (incomplete) c_result panel if (resultPanel != null) { resultPanel.deleteSolution(); } super.cancel(); } + + @Override + public <R> R getResults(Class<? extends R> type) { + //TODO: + if (type.equals(YoshikoResult.class)) { + return (R) (result!=null ? result : null); + } + return null; + } } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViews.java b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViewsTask.java similarity index 92% rename from src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViews.java rename to src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViewsTask.java index a5674a7ab6dff36f5f5e70afee44af3280afb41a..72d6270300e9c7cb0f846599e7681cd24cc4245c 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViews.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/tasks/CreateClusterViewsTask.java @@ -17,10 +17,10 @@ import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.cytoUtil.StyleManager; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster; -public class CreateClusterViews implements Task { +public class CreateClusterViewsTask implements Task { @Tunable - public ArrayList<YoshikoCluster> clusters; + public ArrayList<YoshikoCluster> clusters; //TODO: Make Tunable, reference by ID? private boolean isTerminated; @@ -35,7 +35,7 @@ public class CreateClusterViews implements Task { */ private ArrayList<CySubNetwork> initializedSubNetworks; - public CreateClusterViews(ArrayList<YoshikoCluster> clusters) { + public CreateClusterViewsTask(ArrayList<YoshikoCluster> clusters) { this.clusters = clusters; this.previousView = CyCore.cy.getCurrentNetworkView(); diff --git a/src/main/resources/YoshikoStrings.properties b/src/main/resources/YoshikoStrings.properties index 69c2d91bf4b04128faea4709f51fafbe40b7c513..b20a177a70f2a91e877d6071906459d786118ec7 100644 --- a/src/main/resources/YoshikoStrings.properties +++ b/src/main/resources/YoshikoStrings.properties @@ -26,6 +26,8 @@ about = Yoshiko Cytoscape App aboutButton = About Yoshiko aboutTitle = Yoshiko Plugin Info +autoConfig = Choose reduction rules automatically + clusters = Cluster clusterFound = Clusters found: clusterSize = Cluster Size: