diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/Core.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/Core.java index 89b5f2675e5dc4fb406185476f75ada0c9c864fc..7fb128424d4b5922e08200058cf02885a9048315 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/Core.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/Core.java @@ -23,6 +23,8 @@ public class Core { public static void performYoshiko( int timeLimit, CyColumn weightColumn, + CyColumn permanentColumn, + CyColumn forbiddenColumn, double insertionCostDefault, double deletionCostDefault ) @@ -45,6 +47,8 @@ public class Core { currentNetwork, nodeMap, weightColumn, + permanentColumn, + forbiddenColumn, deletionCostDefault ); @@ -55,7 +59,6 @@ public class Core { SWIGTYPE_p_ysk__ClusterEditingSolutions solutions = LibraryInterface.processLibraryInput(input); - long numberOfSolutions = LibraryInterface.ClusterEditingSolutions_getNumberOfSolutions(solutions); System.out.println("Found: "+numberOfSolutions+" solutions!"); double modificationCost = LibraryInterface.ClusterEditingSolutions_getTotalCost(solutions); @@ -63,6 +66,7 @@ public class Core { for (long i=0;i<numberOfSolutions;i++) { System.out.println("Processing solution "+(i+1)+" of "+numberOfSolutions); String columnName = "YOSHIKO_SOLUTION_"+(i+1); + currentNetwork.getDefaultNodeTable().deleteColumn(columnName); currentNetwork.getDefaultNodeTable().createColumn(columnName, String.class, false); long numberOfClusters = LibraryInterface.ClusterEditingSolutions_getNumberOfClusters(solutions, i); for (long k=0;k<numberOfClusters;k++) { diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java index 2776e294cda04c6800bf857f43c3a9bbc1af6527..cebd4e4e29532894f70e63993ed5a2d7c760cdf1 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java @@ -21,6 +21,8 @@ public class NetworkParser { CyNetwork net, NodeMap nodeMap, CyColumn weightColumn, + CyColumn permanentColumn, + CyColumn forbiddenColumn, double deletionCostDefault ) { @@ -36,30 +38,53 @@ public class NetworkParser { //Loop over edges for (CyEdge e : edges) { + CyRow edgeEntry = net.getRow(e); - //Set to default cost + + //Parse editing costs double weight = deletionCostDefault; if (weightColumn != null){ + System.out.println("Using column: "+weightColumn.getName()); try { //Find out if the weights are double or int @SuppressWarnings("unchecked") Class<? extends Number> weightType = (Class<? extends Number>) weightColumn.getType(); - logger.info("Column has type: "+weightType.getName()); - weight = (double)edgeEntry.get(weightColumn.getName(), weightType); + logger.debug("Column has type: "+weightType.getName()); + if (weightType == Integer.class) { + weight = (int)edgeEntry.get(weightColumn.getName(), weightType); + } + else if(weightType == Double.class) { + weight = (double)edgeEntry.get(weightColumn.getName(), weightType); + } } catch(Exception ex) { + ex.printStackTrace(); //Invalid entry (no entry) logger.info("No valid edit costs defined for: "+edgeEntry.get("name", String.class)+", falling back to default value!"); } } + + //Parse Forbidden/Permanent markers + boolean forbidden = false; + boolean permanent = false; + if (permanentColumn != null) { + permanent = (boolean)edgeEntry.get(permanentColumn.getName(), boolean.class); + } + if (forbiddenColumn != null) { + forbidden = (boolean)edgeEntry.get(forbiddenColumn.getName(), boolean.class); + } logger.debug("Found Edge: "+edgeEntry.get("name", String.class)+ " with weight:"+weight); - LibraryInterface.LibraryInput_addEdge(generatedInput, + LibraryInterface.LibraryInput_addEdge( + generatedInput, nodeMap.get(e.getSource()), - nodeMap.get(e.getTarget()) - , weight); + nodeMap.get(e.getTarget()), + weight, + permanent, + forbidden + ); } } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ColumnMapper.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ColumnMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..f04fffb9510e66654e989f2464cc84d3fa61ef90 --- /dev/null +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ColumnMapper.java @@ -0,0 +1,121 @@ +package de.hhu.ba.yoshikoWrapper.gui; + + +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; + +import org.cytoscape.application.CyApplicationManager; +import org.cytoscape.model.CyColumn; +import org.cytoscape.model.CyNetwork; + +import de.hhu.ba.yoshikoWrapper.core.Core; + +@SuppressWarnings("serial") //will never be serialized +public class ColumnMapper extends ComfortPanel{ + + //Symbolic links + private CyApplicationManager cy; + + //Swing components + private JComboBox<CyColumn> editingCostMapper; + private JComboBox<CyColumn> permanentMapper; + private JComboBox<CyColumn> forbiddenMapper; + + private JCheckBox useMappingCost; + private JCheckBox useMappingPerm; + private JCheckBox useMappingForb; + + public ColumnMapper() { + cy = Core.getApplicationManager(); + + //SWING COMPONENTS + editingCostMapper = new JComboBox<CyColumn>(); + permanentMapper = new JComboBox<CyColumn>(); + forbiddenMapper = new JComboBox<CyColumn>(); + + useMappingCost = new JCheckBox("Map modification costs"); + useMappingPerm = new JCheckBox("Map edges as permanent"); + useMappingForb = new JCheckBox("Map edges as forbidden"); + + useMappingCost.setToolTipText( + "When you use this value you can assign a column in the edge table to represent the modification costs that are to be paid for deleting an edge." + +"You can also assign negative values if you have a complete graph to represent insertion costs." + +"Note: Any missing values are assumed to be the default values" + ); + this.addAll(useMappingCost,editingCostMapper,useMappingPerm,permanentMapper,useMappingForb,forbiddenMapper); + //Initial call to get table values + updateValues(); + //Add a focus listener to update values + this.addFocusListener (new FocusListener() { + + @Override + public void focusGained(FocusEvent e) { + updateValues(); + } + + @Override + public void focusLost(FocusEvent e) {} + + }); + + } + + public void updateValues() { + + CyNetwork net = cy.getCurrentNetwork(); + + if (net != null) { //Check if a network is loaded + + //Clear entries + editingCostMapper.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); + } + } + + forbiddenMapper.removeAllItems(); + for (CyColumn c : net.getDefaultEdgeTable().getColumns()){ + //Only add columns with boolean values + if (c.getType() == Boolean.class) { + editingCostMapper.addItem(c); + } + } + + permanentMapper.removeAllItems(); + for (CyColumn c : net.getDefaultEdgeTable().getColumns()){ + //Only add columns with boolean values + if (c.getType() == Boolean.class) { + permanentMapper.addItem(c); + } + } + + } + } + + public CyColumn getEditingCostColumn() { + if (useMappingCost.isSelected()) { + return editingCostMapper.getItemAt(editingCostMapper.getSelectedIndex()); + } + return null; + } + + public CyColumn getForbiddenColumn() { + if (useMappingForb.isSelected()) { + return forbiddenMapper.getItemAt(forbiddenMapper.getSelectedIndex()); + } + return null; + } + + public CyColumn getPermanentColumn() { + if (useMappingPerm.isSelected()) { + return permanentMapper.getItemAt(permanentMapper.getSelectedIndex()); + } + return null; + } + +} diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/EditCostPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/EditCostPanel.java index 54bd7474f9f96bb176f22c7e141df7d8f15b1a60..22456af30debbd9f33f794c0b89f8ec005e27e4c 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/EditCostPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/EditCostPanel.java @@ -10,16 +10,15 @@ import org.cytoscape.model.CyColumn; public class EditCostPanel extends ComfortPanel { //SWING COMPONENTS - private ModificationCostMapper modCostMapper; + private ColumnMapper columnMapper; private DoubleInputField icField; private DoubleInputField dcField; private JLabel icLabel; private JLabel dcLabel; public EditCostPanel() { - //Initialize components - modCostMapper = new ModificationCostMapper(); + columnMapper = new ColumnMapper(); icField = new DoubleInputField(Double.NEGATIVE_INFINITY,0); dcField = new DoubleInputField(0,Double.POSITIVE_INFINITY); icField.setText("-1.0"); @@ -28,7 +27,7 @@ public class EditCostPanel extends ComfortPanel { dcLabel = new JLabel("Deletion Cost:"); icLabel.setLabelFor(icField); dcLabel.setLabelFor(dcField); - this.addAll(modCostMapper,icField,dcField,icLabel,dcLabel); + this.addAll(columnMapper,icField,dcField,icLabel,dcLabel); // this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); @@ -37,7 +36,15 @@ public class EditCostPanel extends ComfortPanel { //SETTER / GETTER public CyColumn getWeightColumn() { - return modCostMapper.getValue(); + return columnMapper.getEditingCostColumn(); + } + + public CyColumn getPermanentColumn() { + return columnMapper.getPermanentColumn(); + } + + public CyColumn getForbiddenColumn() { + return columnMapper.getForbiddenColumn(); } public double getDefaultInsertionCost() { @@ -47,5 +54,7 @@ public class EditCostPanel extends ComfortPanel { public double getDefaultDeletionCost() { return dcField.getValueAsDouble(); } + + } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java index df06a396d5ba02c37be745d6988c335d077954d3..a403598585aba4b6504901daf6c6716b100a2fe5 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java @@ -1,5 +1,6 @@ package de.hhu.ba.yoshikoWrapper.gui; +import java.text.DecimalFormat; import java.text.NumberFormat; import javax.swing.text.NumberFormatter; @@ -19,7 +20,7 @@ public class FormatHelper { } public static NumberFormatter getDoubleFormatter(double minValue, double maxValue) { - NumberFormat format = NumberFormat.getInstance(); + NumberFormat format = DecimalFormat.getInstance(); NumberFormatter formatter = new NumberFormatter(format); formatter.setValueClass(Double.class); formatter.setMinimum(minValue); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java index f870b9c5e3f945b27aa46eaa258c0c16dbf949b5..ff42424796102328cd159325577432127b49a4dc 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java @@ -100,6 +100,8 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent { Core.performYoshiko( timeLimitSetter.getTimeLimit(), ecPanel.getWeightColumn(), + ecPanel.getPermanentColumn(), + ecPanel.getForbiddenColumn(), ecPanel.getDefaultInsertionCost(), ecPanel.getDefaultDeletionCost() ); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ModificationCostMapper.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ModificationCostMapper.java deleted file mode 100644 index fb110698557223cfcd19a9f27362d30190c745a3..0000000000000000000000000000000000000000 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ModificationCostMapper.java +++ /dev/null @@ -1,76 +0,0 @@ -package de.hhu.ba.yoshikoWrapper.gui; - - -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; - -import javax.swing.JCheckBox; -import javax.swing.JComboBox; - -import org.cytoscape.application.CyApplicationManager; -import org.cytoscape.model.CyColumn; -import org.cytoscape.model.CyNetwork; -import org.cytoscape.model.events.ColumnCreatedEvent; -import org.cytoscape.model.events.ColumnDeletedListener; - -import de.hhu.ba.yoshikoWrapper.core.Core; - -@SuppressWarnings("serial") //will never be serialized -public class ModificationCostMapper extends ComfortPanel{ - - //Symbolic links - private CyApplicationManager cy; - - //Swing components - private JComboBox<CyColumn> tableFields; - private JCheckBox useMapping; - - public ModificationCostMapper() { - tableFields = new JComboBox<CyColumn>(); - useMapping = new JCheckBox("Map modification costs"); - useMapping.setToolTipText( - "When you use this value you can assign a column in the edge table to represent the modification costs that are to be paid for deleting an edge." - +"You can also assign negative values if you have a complete graph to represent insertion costs." - +"Note: Any missing values are assumed to be the default values" - ); - cy = Core.getApplicationManager(); - this.addAll(useMapping,tableFields); - //Initial call to get table values - updateValues(); - //Add a focus listener to update values - tableFields.addFocusListener (new FocusListener() { - - @Override - public void focusGained(FocusEvent e) { - updateValues(); - } - - @Override - public void focusLost(FocusEvent e) {} - - }); - - } - - public void updateValues() { - //Clear entries - tableFields.removeAllItems(); - CyNetwork net = cy.getCurrentNetwork(); - if (net != null) { //Check if a network is loaded - for (CyColumn c : net.getDefaultEdgeTable().getColumns()){ - //Only add columns with numeric values - if (c.getType() == Integer.class || c.getType() == Double.class) { - tableFields.addItem(c); - } - } - } - } - - public CyColumn getValue() { - if (useMapping.isSelected()) { - return tableFields.getItemAt(tableFields.getSelectedIndex()); - } - return null; - } - -} diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ReductionRulesChooser.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ReductionRulesChooser.java index 12273280c21033b3c82980575e73b1befab49d08..6fd2b9706b5a4903f36877c8d953cff5f9d6e8fb 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ReductionRulesChooser.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ReductionRulesChooser.java @@ -2,6 +2,7 @@ package de.hhu.ba.yoshikoWrapper.gui; import java.awt.Component; +import javax.swing.BoxLayout; import javax.swing.JCheckBox; @SuppressWarnings("serial") @@ -15,6 +16,7 @@ public class ReductionRulesChooser extends ComfortPanel{ private JCheckBox useSNRule; public ReductionRulesChooser() { + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); //Initialize subcomponents useCRule = new JCheckBox("Use Clique Rule"); useCCRule = new JCheckBox("Use Critical-Clique Rule");