diff --git a/pom.xml b/pom.xml index 477aafb5707e5e418c432049e7607bddcfca23ea..e253b54b5d68ef31abc25ff496d06925eefd82e6 100644 --- a/pom.xml +++ b/pom.xml @@ -24,8 +24,8 @@ <artifactId>maven-compiler-plugin</artifactId> <version>3.0</version> <configuration> - <source>1.6</source> - <target>1.6</target> + <source>1.8</source> + <target>1.8</target> <optimize>true</optimize> <showWarnings>true</showWarnings> <showDeprecation>true</showDeprecation> 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 e00c591e94797e2febaebbeb268c211c1be63dda..89b5f2675e5dc4fb406185476f75ada0c9c864fc 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/Core.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/Core.java @@ -2,9 +2,12 @@ package de.hhu.ba.yoshikoWrapper.core; //TODO: ADD LOGGER SYSTEM import org.cytoscape.application.CyApplicationManager; +import org.cytoscape.model.CyColumn; import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNode; +import org.slf4j.Logger; +import de.hhu.ba.yoshikoWrapper.logging.YoshikoLogger; import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface; import de.hhu.ba.yoshikoWrapper.swig.SWIGTYPE_p_std__vectorT_int_t; import de.hhu.ba.yoshikoWrapper.swig.SWIGTYPE_p_yskInput__LibraryInput; @@ -12,22 +15,47 @@ import de.hhu.ba.yoshikoWrapper.swig.SWIGTYPE_p_ysk__ClusterEditingSolutions; public class Core { - private static CyApplicationManager cy; + //Symbolic links + private static CyApplicationManager cy; + private static Logger logger = YoshikoLogger.getInstance().getLogger(); - public static void performYoshiko(int timeLimit) { + public static void performYoshiko( + int timeLimit, + CyColumn weightColumn, + double insertionCostDefault, + double deletionCostDefault + ) + { + //Get current network CyNetwork currentNetwork = cy.getCurrentNetwork(); if (currentNetwork == null) { - //TODO + logger.warn("There is no network loaded. You need to load a network first!"); return; } + //Set time limit LibraryInterface.setTimeLimit(timeLimit); - + + //Create a node map to identify nodes and eges in the solution NodeMap nodeMap = new NodeMap(currentNetwork); - SWIGTYPE_p_yskInput__LibraryInput input = NetworkParser.parseNetwork(currentNetwork,nodeMap); + //Generate an input instance from the network + SWIGTYPE_p_yskInput__LibraryInput input = NetworkParser.parseNetwork( + currentNetwork, + nodeMap, + weightColumn, + deletionCostDefault + ); + + //Set the default value for insertion cost + LibraryInterface.LibraryInput_setDefaultInsertionCost(input, insertionCostDefault); + + //Call Yoshiko <<< Algorithm is performed here 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); 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 7602223b14ad08acd1309505b127fae91c80795a..f5f3e92229f6f11e75aa5569dbc805b5875b71eb 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/NetworkParser.java @@ -2,35 +2,54 @@ package de.hhu.ba.yoshikoWrapper.core; 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; import de.hhu.ba.yoshikoWrapper.swig.LibraryInterface; import de.hhu.ba.yoshikoWrapper.swig.SWIGTYPE_p_yskInput__LibraryInput; public class NetworkParser { - //**TODO MAKE DYNAMIC - private static String weightIndex = "Weight"; - + //Symbolic Links + private static Logger logger = YoshikoLogger.getInstance().getLogger(); - - - public static SWIGTYPE_p_yskInput__LibraryInput parseNetwork(CyNetwork net,NodeMap nodeMap) { + public static SWIGTYPE_p_yskInput__LibraryInput parseNetwork( + CyNetwork net, + NodeMap nodeMap, + CyColumn weightColumn, + double deletionCostDefault + ) + { + //Create an empty instance / fetch C++ object pointer SWIGTYPE_p_yskInput__LibraryInput generatedInput = LibraryInterface.new_LibraryInput(); - if (net != null){ + if (net != null){ + //Create an empty full graph with a given size LibraryInterface.LibraryInput_setSize(generatedInput, net.getNodeCount()); + //Fetch edges List<CyEdge> edges = net.getEdgeList(); - Class<?> weightType = net.getDefaultEdgeTable().getColumn(weightIndex).getType(); - System.out.println("Column has type:"+weightType.getName()); + + //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()); + //Loop over edges for (CyEdge e : edges) { CyRow edgeEntry = net.getRow(e); - double weight = 0.0; - if (weightType == Integer.class) { - weight = (double)edgeEntry.get(weightIndex, Integer.class); + double weight = deletionCostDefault; + try { + weight = (double)edgeEntry.get(weightColumn.getName(), weightType); } - System.out.println("Found Edge: "+edgeEntry.get("name", String.class)+ "with weight:"+weight); + catch(Exception ex) { + //Invalid entry (no entry) + logger.info("No valid edit costs defined for: "+edgeEntry.get("name", String.class)+", falling back to default value!"); + } + + logger.debug("Found Edge: "+edgeEntry.get("name", String.class)+ "with weight:"+weight); LibraryInterface.LibraryInput_addEdge(generatedInput, nodeMap.get(e.getSource()), diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/DoubleInputField.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/DoubleInputField.java index aea51813d9a33391133ae3390dc8f7eadac3bf8b..80e89e20be5714c8c8a13cf52f6eba603fe83563 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/DoubleInputField.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/DoubleInputField.java @@ -13,7 +13,7 @@ public class DoubleInputField extends JFormattedTextField{ this.setColumns(8); } - public int getTimeLimit() { - return Integer.parseInt(getText()); + public double getValueAsDouble() { + return Double.parseDouble(getText()); } } 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 d131859a83dc17ea639add21c47b6fad3efa752f..54bd7474f9f96bb176f22c7e141df7d8f15b1a60 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/EditCostPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/EditCostPanel.java @@ -1,6 +1,10 @@ package de.hhu.ba.yoshikoWrapper.gui; +import javax.swing.BorderFactory; import javax.swing.JLabel; +import javax.swing.border.EtchedBorder; + +import org.cytoscape.model.CyColumn; @SuppressWarnings("serial") //Will never be serialized public class EditCostPanel extends ComfortPanel { @@ -13,14 +17,35 @@ public class EditCostPanel extends ComfortPanel { private JLabel dcLabel; public EditCostPanel() { + + //Initialize components modCostMapper = new ModificationCostMapper(); - icField = new DoubleInputField(0,Double.NEGATIVE_INFINITY); + icField = new DoubleInputField(Double.NEGATIVE_INFINITY,0); dcField = new DoubleInputField(0,Double.POSITIVE_INFINITY); + icField.setText("-1.0"); + dcField.setText("1.0"); icLabel = new JLabel("Insertion Cost:"); dcLabel = new JLabel("Deletion Cost:"); icLabel.setLabelFor(icField); dcLabel.setLabelFor(dcField); this.addAll(modCostMapper,icField,dcField,icLabel,dcLabel); + + // + this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); + } + + //SETTER / GETTER + + public CyColumn getWeightColumn() { + return modCostMapper.getValue(); + } + + public double getDefaultInsertionCost() { + return icField.getValueAsDouble(); + } + + 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 770d241c3bf5523b33b3485339a1def29f354495..df06a396d5ba02c37be745d6988c335d077954d3 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/FormatHelper.java @@ -21,7 +21,7 @@ public class FormatHelper { public static NumberFormatter getDoubleFormatter(double minValue, double maxValue) { NumberFormat format = NumberFormat.getInstance(); NumberFormatter formatter = new NumberFormatter(format); - formatter.setValueClass(Integer.class); + formatter.setValueClass(Double.class); formatter.setMinimum(minValue); formatter.setMaximum(maxValue); formatter.setAllowsInvalid(false); 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 403ceb434d38d05b4666fe5239aef9ed34ac1281..f870b9c5e3f945b27aa46eaa258c0c16dbf949b5 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/MainPanel.java @@ -97,7 +97,12 @@ public class MainPanel extends ComfortPanel implements CytoPanelComponent { @Override public void actionPerformed(ActionEvent e) { if (YoshikoLoader.isLibraryLoaded()){ - Core.performYoshiko(timeLimitSetter.getTimeLimit()); + Core.performYoshiko( + timeLimitSetter.getTimeLimit(), + ecPanel.getWeightColumn(), + 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 index 78c74b132d987aa541c512b7c4e09926df50fec9..fb110698557223cfcd19a9f27362d30190c745a3 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ModificationCostMapper.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/ModificationCostMapper.java @@ -10,11 +10,13 @@ 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 { +public class ModificationCostMapper extends ComfortPanel{ //Symbolic links private CyApplicationManager cy; @@ -36,8 +38,7 @@ public class ModificationCostMapper extends ComfortPanel { //Initial call to get table values updateValues(); //Add a focus listener to update values - //TODO: This might be a bit inelegant but there is no way to get a callback from CS when a table changes values - tableFields.addFocusListener(new FocusListener() { + tableFields.addFocusListener (new FocusListener() { @Override public void focusGained(FocusEvent e) { @@ -57,7 +58,10 @@ public class ModificationCostMapper extends ComfortPanel { CyNetwork net = cy.getCurrentNetwork(); if (net != null) { //Check if a network is loaded for (CyColumn c : net.getDefaultEdgeTable().getColumns()){ - tableFields.addItem(c); + //Only add columns with numeric values + if (c.getType() == Integer.class || c.getType() == Double.class) { + tableFields.addItem(c); + } } } } 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 e87817e26c40e022a279327dd52f622d1a80a1b0..f56afd8bdced6a150e4a94d555dfe4b40776de0c 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterface.java @@ -93,10 +93,6 @@ public class LibraryInterface { LibraryInterfaceJNI.delete_LibraryInput(SWIGTYPE_p_yskInput__LibraryInput.getCPtr(self)); } - public static void LibraryInput_setSize(SWIGTYPE_p_yskInput__LibraryInput self, long id) { - LibraryInterfaceJNI.LibraryInput_setSize(SWIGTYPE_p_yskInput__LibraryInput.getCPtr(self), id); - } - public static void LibraryInput_addEdge(SWIGTYPE_p_yskInput__LibraryInput self, long sourceID, long targetID, double cost) { LibraryInterfaceJNI.LibraryInput_addEdge__SWIG_0(SWIGTYPE_p_yskInput__LibraryInput.getCPtr(self), sourceID, targetID, cost); } @@ -105,6 +101,14 @@ public class LibraryInterface { LibraryInterfaceJNI.LibraryInput_addEdge__SWIG_1(SWIGTYPE_p_yskInput__LibraryInput.getCPtr(self), sourceID, targetID, cost, permanent, forbidden); } + public static void LibraryInput_setSize(SWIGTYPE_p_yskInput__LibraryInput self, long id) { + LibraryInterfaceJNI.LibraryInput_setSize(SWIGTYPE_p_yskInput__LibraryInput.getCPtr(self), id); + } + + public static void LibraryInput_setDefaultInsertionCost(SWIGTYPE_p_yskInput__LibraryInput self, double cost) { + LibraryInterfaceJNI.LibraryInput_setDefaultInsertionCost(SWIGTYPE_p_yskInput__LibraryInput.getCPtr(self), cost); + } + public static String getVersionString() { return LibraryInterfaceJNI.getVersionString(); } 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 2ed424470bdf7d750edba86d06739cc5bbb82178..8332626738495dffb9f5e66702299f8fd10f0d18 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/swig/LibraryInterfaceJNI.java @@ -29,9 +29,10 @@ public class LibraryInterfaceJNI { public final static native void delete_ClusterEditingSolutions(long jarg1); public final static native long new_LibraryInput(); public final static native void delete_LibraryInput(long jarg1); - public final static native void LibraryInput_setSize(long jarg1, long jarg2); public final static native void LibraryInput_addEdge__SWIG_0(long jarg1, long jarg2, long jarg3, double jarg4); public final static native void LibraryInput_addEdge__SWIG_1(long jarg1, long jarg2, long jarg3, double jarg4, boolean jarg5, boolean jarg6); + public final static native void LibraryInput_setSize(long jarg1, long jarg2); + public final static native void LibraryInput_setDefaultInsertionCost(long jarg1, double jarg2); public final static native String getVersionString(); public final static native long processLibraryInput(long jarg1); public final static native void setTimeLimit(int jarg1);