Author: clopes
Date: 2012-11-08 14:17:35 -0800 (Thu, 08 Nov 2012)
New Revision: 30762

Added:
   
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODEGraph.java
Modified:
   
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/MCODEDiscardResultAction.java
   
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODEAlgorithm.java
   
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODECluster.java
   
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/task/MCODEAnalyzeTask.java
   
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/util/MCODEUtil.java
   
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/view/MCODEResultsPanel.java
   
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/util/MCODEUtilTest.java
Log:
Added a lightweight MCODE Graph object to be used by the algorithm, which no 
longer has to create temporary CySubNetworks--it's a lot faster and consumes 
less resources. Fixed a division by 0 when calculating the cluster score.

Modified: 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/MCODEDiscardResultAction.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/MCODEDiscardResultAction.java
       2012-11-08 22:08:18 UTC (rev 30761)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/MCODEDiscardResultAction.java
       2012-11-08 22:17:35 UTC (rev 30762)
@@ -11,6 +11,7 @@
 import org.cytoscape.application.swing.CytoPanelComponent;
 import org.cytoscape.application.swing.CytoPanelName;
 import org.cytoscape.application.swing.CytoPanelState;
+import org.cytoscape.mcode.internal.model.MCODECluster;
 import org.cytoscape.mcode.internal.util.MCODEUtil;
 import org.cytoscape.mcode.internal.view.MCODEResultsPanel;
 import org.cytoscape.service.util.CyServiceRegistrar;
@@ -62,8 +63,16 @@
                        }
 
                        if (confirmed == JOptionPane.YES_OPTION) {
+                               final MCODECluster[] clusters = 
panel.getClusters();
+                               
                                registrar.unregisterService(panel, 
CytoPanelComponent.class);
                                mcodeUtil.removeNetworkResult(resultId);
+                               
+                               // Dispose all clusters
+                               if (clusters != null) {
+                                       for (final MCODECluster c : clusters)
+                                               c.dispose();
+                               }
                        }
                }
 

Modified: 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODEAlgorithm.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODEAlgorithm.java
   2012-11-08 22:08:18 UTC (rev 30761)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODEAlgorithm.java
   2012-11-08 22:17:35 UTC (rev 30762)
@@ -16,8 +16,6 @@
 import org.cytoscape.model.CyEdge;
 import org.cytoscape.model.CyNetwork;
 import org.cytoscape.model.CyNode;
-import org.cytoscape.model.SavePolicy;
-import org.cytoscape.model.subnetwork.CySubNetwork;
 import org.cytoscape.work.TaskMonitor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -351,19 +349,19 @@
                                                }
 
                                                // Create an input graph for 
the filter and haircut methods
-                                               CySubNetwork clusterNet = 
createClusterNetwork(alCluster, inputNetwork);
+                                               MCODEGraph clusterGraph = 
createClusterGraph(alCluster, inputNetwork);
 
-                                               if (!filterCluster(clusterNet)) 
{
+                                               if 
(!filterCluster(clusterGraph)) {
                                                        if (params.isHaircut())
-                                                               
haircutCluster(clusterNet, alCluster);
+                                                               
haircutCluster(clusterGraph, alCluster);
 
                                                        if (params.isFluff())
                                                                
fluffClusterBoundary(alCluster, nodeSeenHashMap, nodeInfoHashMap);
 
-                                                       clusterNet = 
createClusterNetwork(alCluster, inputNetwork);
-                                                       final double score = 
scoreCluster(clusterNet);
+                                                       clusterGraph = 
createClusterGraph(alCluster, inputNetwork);
+                                                       final double score = 
scoreCluster(clusterGraph);
                                                        
-                                                       MCODECluster 
currentCluster = new MCODECluster(resultId, currentNode, clusterNet, score,
+                                                       MCODECluster 
currentCluster = new MCODECluster(resultId, currentNode, clusterGraph, score,
                                                                        
alCluster, nodeSeenHashMapSnapShot);
                                                        
                                                        
alClusters.add(currentCluster);
@@ -408,12 +406,6 @@
                                        }
                                }
                        }
-                       
-                       // Dispose clusters that were not selected
-                       for (MCODECluster c : alClusters) {
-                               if (!selectedALClusters.contains(c))
-                                       c.dispose();
-                       }
 
                        alClusters = selectedALClusters;
                }
@@ -464,25 +456,25 @@
                        alCluster.add(seedNode);
 
                // Create an input graph for the filter and haircut methods
-               CySubNetwork clusterNet = createClusterNetwork(alCluster, 
inputNet);
+               MCODEGraph clusterGraph = createClusterGraph(alCluster, 
inputNet);
 
                if (params.isHaircut())
-                       haircutCluster(clusterNet, alCluster);
+                       haircutCluster(clusterGraph, alCluster);
 
                if (params.isFluff())
                        fluffClusterBoundary(alCluster, nodeSeenHashMap, 
nodeInfoHashMap);
 
-               clusterNet = createClusterNetwork(alCluster, inputNet);
-               final double score = scoreCluster(clusterNet);
+               clusterGraph = createClusterGraph(alCluster, inputNet);
+               final double score = scoreCluster(clusterGraph);
                
-               final MCODECluster newCluster = new MCODECluster(resultId, 
seedNode, clusterNet, score, alCluster,
+               final MCODECluster newCluster = new MCODECluster(resultId, 
seedNode, clusterGraph, score, alCluster,
                                nodeSeenHashMap);
                newCluster.setRank(cluster.getRank());
                
                return newCluster;
        }
 
-       private CySubNetwork createClusterNetwork(final List<Long> alCluster, 
final CyNetwork inputNet) {
+       private MCODEGraph createClusterGraph(final List<Long> alCluster, final 
CyNetwork inputNet) {
                final Set<CyNode> nodes = new HashSet<CyNode>();
 
                for (final Long id : alCluster) {
@@ -490,11 +482,11 @@
                        nodes.add(n);
                }
 
-               CySubNetwork outputNet = mcodeUtil.createSubNetwork(inputNet, 
nodes, SavePolicy.DO_NOT_SAVE);
+               final MCODEGraph clusterGraph = mcodeUtil.createGraph(inputNet, 
nodes);
 
-               return outputNet;
+               return clusterGraph;
        }
-
+       
        /**
         * Score node using the formula from original MCODE paper.
         * This formula selects for larger, denser cores.
@@ -517,15 +509,15 @@
         * Score a cluster.  Currently this ranks larger, denser clusters 
higher, although
         * in the future other scoring functions could be created
         *
-        * @param clusterNet
+        * @param clusterGraph
         * @return The score of the cluster
         */
-       public double scoreCluster(final CySubNetwork clusterNet) {
+       public double scoreCluster(final MCODEGraph clusterGraph) {
                int numNodes = 0;
                double density = 0.0, score = 0.0;
 
-               numNodes = clusterNet.getNodeCount();
-               density = calcDensity(clusterNet, params.isIncludeLoops());
+               numNodes = clusterGraph.getNodeCount();
+               density = calcDensity(clusterGraph, params.isIncludeLoops());
                score = density * numNodes;
 
                return score;
@@ -586,11 +578,11 @@
                }
                
                // extract neighborhood subgraph
-               final CySubNetwork neighborhoodNet = 
mcodeUtil.createSubNetwork(inputNetwork, neighbors, SavePolicy.DO_NOT_SAVE);
+               final MCODEGraph neighborhoodGraph = 
mcodeUtil.createGraph(inputNetwork, neighbors);
                
-               if (neighborhoodNet == null) {
+               if (neighborhoodGraph == null) {
                        // this shouldn't happen
-                       logger.error("In " + callerID + ": gpNodeNeighborhood 
was null.");
+                       logger.error("In " + callerID + ": neighborhoodGraph 
was null.");
                        return null;
                }
 
@@ -598,16 +590,16 @@
                final NodeInfo nodeInfo = new NodeInfo();
 
                // Density
-               if (neighborhoodNet != null)
-                       nodeInfo.density = calcDensity(neighborhoodNet, 
params.isIncludeLoops());
+               if (neighborhoodGraph != null)
+                       nodeInfo.density = calcDensity(neighborhoodGraph, 
params.isIncludeLoops());
                
                nodeInfo.numNodeNeighbors = neighborhood.length;
 
                // Calculate the highest k-core
                Integer k = null;
-               Object[] returnArray = getHighestKCore(neighborhoodNet);
+               Object[] returnArray = getHighestKCore(neighborhoodGraph);
                k = (Integer) returnArray[0];
-               CySubNetwork kCore = (CySubNetwork) returnArray[1];
+               MCODEGraph kCore = (MCODEGraph) returnArray[1];
                nodeInfo.coreLevel = k.intValue();
                
                // Calculate the core density - amplifies the density of 
heavily interconnected regions and attenuates
@@ -762,15 +754,15 @@
        /**
         * Checks if the cluster needs to be filtered according to heuristics 
in this method
         *
-        * @param clusterNetwork The cluster to check if it passes the filter
+        * @param clusterGraph The cluster to check if it passes the filter
         * @return true if cluster should be filtered, false otherwise
         */
-       private boolean filterCluster(final CySubNetwork clusterNetwork) {
-               if (clusterNetwork == null)
+       private boolean filterCluster(final MCODEGraph clusterGraph) {
+               if (clusterGraph == null)
                        return true;
 
                // filter if the cluster does not satisfy the user specified 
k-core
-               CySubNetwork kCore = getKCore(clusterNetwork, 
params.getKCore());
+               MCODEGraph kCore = getKCore(clusterGraph, params.getKCore());
 
                return kCore == null;
        }
@@ -778,20 +770,20 @@
        /**
         * Gives the cluster a haircut (removed singly connected nodes by 
taking a 2-core)
         *
-        * @param clusterNetwork The cluster network
-        * @param cluster        The cluster node ID list (in the original 
graph)
+        * @param clusterGraph The cluster network
+        * @param cluster      The cluster node ID list (in the original graph)
         * @return true
         */
-       private boolean haircutCluster(final CySubNetwork clusterNetwork, final 
List<Long> cluster) {
+       private boolean haircutCluster(final MCODEGraph clusterGraph, final 
List<Long> cluster) {
                // get 2-core
-               final CySubNetwork kCore = getKCore(clusterNetwork, 2);
+               final MCODEGraph kCore = getKCore(clusterGraph, 2);
 
                if (kCore != null) {
                        // clear the cluster and add all 2-core nodes back into 
it
                        cluster.clear();
                        
                        // must add back the nodes in a way that preserves node 
indices
-                       for (CyNode n : kCore.getNodeList())
+                       for (final CyNode n : kCore.getNodeList())
                                cluster.add(n.getSUID());
                }
                
@@ -802,21 +794,21 @@
         * Calculate the density of a network
         * The density is defined as the number of edges/the number of possible 
edges
         *
-        * @param network The input graph to calculate the density of
+        * @param graph The input graph to calculate the density of
         * @param includeLoops Include the possibility of loops when 
determining the number of
         *                     possible edges.
         * @return The density of the network
         */
-       private double calcDensity(final CySubNetwork network, final boolean 
includeLoops) {
+       private double calcDensity(final MCODEGraph graph, final boolean 
includeLoops) {
                String callerID = "MCODEAlgorithm.calcDensity";
 
-               if (network == null) {
+               if (graph == null) {
                        logger.error("In " + callerID + ": network was null.");
                        return (-1.0);
                }
 
-               int nodeCount = network.getNodeCount();
-               int actualEdgeNum = getMergedEdgeCount(network, includeLoops);
+               int nodeCount = graph.getNodeCount();
+               int actualEdgeNum = getMergedEdgeCount(graph, includeLoops);
                int possibleEdgeNum = 0;
                
                if (includeLoops)
@@ -824,15 +816,15 @@
                else
                        possibleEdgeNum = (nodeCount * (nodeCount - 1)) / 2;
 
-               double density = (double) actualEdgeNum / (double) 
possibleEdgeNum;
+               double density = possibleEdgeNum != 0 ? ((double) actualEdgeNum 
/ (double) possibleEdgeNum) : 0;
 
                return density;
        }
 
-       private int getMergedEdgeCount(CySubNetwork network, boolean 
includeLoops) {
+       private int getMergedEdgeCount(final MCODEGraph graph, final boolean 
includeLoops) {
                Set<String> suidPairs = new HashSet<String>();
                
-               for (CyEdge e : network.getEdgeList()) {
+               for (CyEdge e : graph.getEdgeList()) {
                        Long id1 = e.getSource().getSUID();
                        Long id2 = e.getTarget().getSUID();
                        
@@ -849,29 +841,29 @@
        /**
         * Find a k-core of a network. A k-core is a subgraph of minimum degree 
k
         *
-        * @param inputNet The input network
-        * @param k            The k of the k-core to find e.g. 4 will find a 
4-core
+        * @param inputGraph The input network
+        * @param k          The k of the k-core to find e.g. 4 will find a 
4-core
         * @return Returns a subgraph with the core, if any was found at given k
         */
-       private CySubNetwork getKCore(final CySubNetwork inputNet, int k) {
+       private MCODEGraph getKCore(final MCODEGraph inputGraph, final int k) {
                String callerID = "MCODEAlgorithm.getKCore";
 
-               if (inputNet == null) {
+               if (inputGraph == null) {
                        logger.error("In " + callerID + ": inputNetwork was 
null.");
                        return null;
                }
 
                // filter all nodes with degree less than k until convergence
                boolean firstLoop = true;
-               CySubNetwork outputNet = inputNet;
+               MCODEGraph outputGraph = inputGraph;
 
                while (true && !cancelled) {
                        int numDeleted = 0;
-                       List<Long> alCoreNodeIndices = new 
ArrayList<Long>(outputNet.getNodeCount());
-                       List<CyNode> nodes = outputNet.getNodeList();
+                       final List<Long> alCoreNodeIndices = new 
ArrayList<Long>(outputGraph.getNodeCount());
+                       final List<CyNode> nodes = outputGraph.getNodeList();
 
                        for (CyNode n : nodes) {
-                               int degree = outputNet.getAdjacentEdgeList(n, 
CyEdge.Type.ANY).size();
+                               int degree = outputGraph.getAdjacentEdgeList(n, 
CyEdge.Type.ANY).size();
 
                                if (degree >= k)
                                        alCoreNodeIndices.add(n.getSUID()); 
//contains all nodes with degree >= k
@@ -883,13 +875,13 @@
                                Set<CyNode> outputNodes = new HashSet<CyNode>();
 
                                for (Long index : alCoreNodeIndices) {
-                                       CyNode n = outputNet.getNode(index);
+                                       CyNode n = outputGraph.getNode(index);
                                        outputNodes.add(n);
                                }
                                
-                               outputNet = 
mcodeUtil.createSubNetwork(outputNet.getRootNetwork(), outputNodes, 
SavePolicy.DO_NOT_SAVE);
+                               outputGraph = 
mcodeUtil.createGraph(outputGraph.getRootNetwork(), outputNodes);
                                
-                               if (outputNet.getNodeCount() == 0)
+                               if (outputGraph.getNodeCount() == 0)
                                        return null;
 
                                // Iterate again, but with a new k-core input 
graph...
@@ -902,37 +894,37 @@
                        }
                }
 
-               return outputNet;
+               return outputGraph;
        }
 
        /**
         * Find the highest k-core in the input network.
         *
-        * @param network The input network
+        * @param graph The input graph
         * @return Returns the k-value and the core as an Object array.
         *         The first object is the highest k value i.e. objectArray[0]
-        *         The second object is the highest k-core as a CyNetwork i.e. 
objectArray[1]
+        *         The second object is the highest k-core as a MCODEGraph i.e. 
objectArray[1]
         */
-       private Object[] getHighestKCore(final CySubNetwork network) {
+       private Object[] getHighestKCore(final MCODEGraph graph) {
                final String callerID = "MCODEAlgorithm.getHighestKCore";
 
-               if (network == null) {
+               if (graph == null) {
                        logger.error("In " + callerID + ": network was null.");
                        return (null);
                }
 
                int i = 1;
-               CySubNetwork curNet = network, prevNet = null;
+               MCODEGraph curGraph = graph, prevGraph = null;
 
-               while ((curNet = getKCore(curNet, i)) != null) {
-                       prevNet = curNet;
+               while ((curGraph = getKCore(curGraph, i)) != null) {
+                       prevGraph = curGraph;
                        i++;
                }
                
                Integer k = i - 1;
                final Object[] returnArray = new Object[2];
                returnArray[0] = k;
-               returnArray[1] = prevNet; //in the last iteration, curNet is 
null (loop termination condition)
+               returnArray[1] = prevGraph; //in the last iteration, curGraph 
is null (loop termination condition)
 
                return returnArray;
        }

Modified: 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODECluster.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODECluster.java
     2012-11-08 22:08:18 UTC (rev 30761)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODECluster.java
     2012-11-08 22:17:35 UTC (rev 30762)
@@ -48,8 +48,8 @@
 public class MCODECluster {
 
        private List<Long> alCluster;
+       private MCODEGraph graph;
        private CyNetworkView view; // keeps track of layout so that layout 
process doesn't have to be repeated unnecessarily
-       private CySubNetwork network;
        private Long seedNode;
        private Map<Long, Boolean> nodeSeenHashMap; // stores the nodes that 
have already been included in higher ranking clusters
        private double score;
@@ -60,18 +60,18 @@
 
        public MCODECluster(final int resultId,
                                                final Long seedNode,
-                                               final CySubNetwork network,
+                                               final MCODEGraph graph,
                                                final double score,
                                                final List<Long> alCluster,
                                                final Map<Long, Boolean> 
nodeSeenHashMap) {
                assert seedNode != null;
-               assert network != null;
+               assert graph != null;
                assert alCluster != null;
                assert nodeSeenHashMap != null;
                
                this.resultId = resultId;
                this.seedNode = seedNode;
-               this.network = network;
+               this.graph = graph;
                this.score = score;
                this.alCluster = alCluster;
                this.nodeSeenHashMap = nodeSeenHashMap;
@@ -90,6 +90,10 @@
                this.name = name;
        }
 
+       public MCODEGraph getGraph() {
+               return graph;
+       }
+       
        public synchronized CyNetworkView getView() {
                return view;
        }
@@ -104,7 +108,7 @@
        }
 
        public synchronized CySubNetwork getNetwork() {
-               return network;
+               return graph.getSubNetwork();
        }
 
        public double getScore() {
@@ -142,8 +146,7 @@
                if (view != null)
                        view.dispose();
                
-               network.getRootNetwork().removeSubNetwork(network);
-               network.dispose();
+               graph.dispose();
                
                disposed = true;
        }
@@ -153,6 +156,12 @@
                return "MCODECluster [clusterName=" + name + ", clusterScore=" 
+ score + 
                                ", rank=" + rank + ", resultId=" + resultId + 
", disposed=" + disposed + "]";
        }
+       
+       @Override
+       protected void finalize() throws Throwable {
+               dispose();
+               super.finalize();
+       }
 
        private void throwExceptionIfDisposed() {
                if (isDisposed())

Added: 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODEGraph.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODEGraph.java
                               (rev 0)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODEGraph.java
       2012-11-08 22:17:35 UTC (rev 30762)
@@ -0,0 +1,171 @@
+package org.cytoscape.mcode.internal.model;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.cytoscape.mcode.internal.util.MCODEUtil;
+import org.cytoscape.model.CyEdge;
+import org.cytoscape.model.CyEdge.Type;
+import org.cytoscape.model.CyNode;
+import org.cytoscape.model.SavePolicy;
+import org.cytoscape.model.subnetwork.CyRootNetwork;
+import org.cytoscape.model.subnetwork.CySubNetwork;
+
+public class MCODEGraph {
+
+       private final CyRootNetwork rootNetwork;
+       private final Set<CyNode> nodes;
+       private final Set<CyEdge> edges;
+       private final Map<Long, CyNode> nodeMap;
+       private final Map<Long, CyEdge> edgeMap;
+       private CySubNetwork subNetwork;
+       private MCODEUtil mcodeUtil;
+       private boolean disposed;
+
+       public MCODEGraph(final CyRootNetwork rootNetwork,
+                                         final Collection<CyNode> nodes,
+                                         final Collection<CyEdge> edges,
+                                         final MCODEUtil mcodeUtil) {
+               if (rootNetwork == null)
+                       throw new NullPointerException("rootNetwork is null!");
+               if (nodes == null)
+                       throw new NullPointerException("nodes is null!");
+               if (edges == null)
+                       throw new NullPointerException("edges is null!");
+
+               this.mcodeUtil = mcodeUtil;
+               this.rootNetwork = rootNetwork;
+               this.nodes = Collections.synchronizedSet(new 
HashSet<CyNode>(nodes.size()));
+               this.edges = Collections.synchronizedSet(new 
HashSet<CyEdge>(edges.size()));
+               this.nodeMap = Collections.synchronizedMap(new HashMap<Long, 
CyNode>(nodes.size()));
+               this.edgeMap = Collections.synchronizedMap(new HashMap<Long, 
CyEdge>(edges.size()));
+
+               for (CyNode n : nodes)
+                       addNode(n);
+               for (CyEdge e : edges)
+                       addEdge(e);
+       }
+
+       public boolean addNode(CyNode node) {
+               if (nodes.contains(node))
+                       return false;
+               
+               node = rootNetwork.getNode(node.getSUID());
+
+               if (nodes.add(node)) {
+                       nodeMap.put(node.getSUID(), node);
+                       return true;
+               }
+
+               return false;
+       }
+
+       public boolean addEdge(CyEdge edge) {
+               if (edges.contains(edge))
+                       return false;
+
+               if (nodes.contains(edge.getSource()) && 
nodes.contains(edge.getTarget())) {
+                       edge = rootNetwork.getEdge(edge.getSUID());
+
+                       if (edges.add(edge)) {
+                               edgeMap.put(edge.getSUID(), edge);
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       public int getNodeCount() {
+               return nodes.size();
+       }
+
+       public int getEdgeCount() {
+               return edges.size();
+       }
+
+       public List<CyNode> getNodeList() {
+               return new ArrayList<CyNode>(nodes);
+       }
+
+       public List<CyEdge> getEdgeList() {
+               return new ArrayList<CyEdge>(edges);
+       }
+
+       public boolean containsNode(final CyNode node) {
+               return nodes.contains(node);
+       }
+
+       public boolean containsEdge(final CyEdge edge) {
+               return edges.contains(edge);
+       }
+
+       public CyNode getNode(final long index) {
+               return nodeMap.get(index);
+       }
+
+       public CyEdge getEdge(final long index) {
+               return edgeMap.get(index);
+       }
+
+       public List<CyEdge> getAdjacentEdgeList(final CyNode node, final Type 
edgeType) {
+               List<CyEdge> rootList = rootNetwork.getAdjacentEdgeList(node, 
edgeType);
+               List<CyEdge> list = new ArrayList<CyEdge>(rootList.size());
+
+               for (CyEdge e : rootList) {
+                       if (containsEdge(e))
+                               list.add(e);
+               }
+
+               return list;
+       }
+
+       public List<CyEdge> getConnectingEdgeList(final CyNode source, final 
CyNode target, final Type edgeType) {
+               List<CyEdge> rootList = 
rootNetwork.getConnectingEdgeList(source, target, edgeType);
+               List<CyEdge> list = new ArrayList<CyEdge>(rootList.size());
+
+               for (CyEdge e : rootList) {
+                       if (containsEdge(e))
+                               list.add(e);
+               }
+
+               return list;
+       }
+
+       public CyRootNetwork getRootNetwork() {
+               return rootNetwork;
+       }
+
+       public synchronized CySubNetwork getSubNetwork() {
+               if (!disposed && subNetwork == null)
+                       subNetwork = mcodeUtil.createSubNetwork(rootNetwork, 
nodes, SavePolicy.DO_NOT_SAVE);
+
+               return subNetwork;
+       }
+
+       public synchronized boolean isDisposed() {
+               return disposed;
+       }
+       
+       public synchronized void dispose() {
+               if (disposed) return;
+               
+               if (subNetwork != null) {
+                       mcodeUtil.destroy(subNetwork);
+                       subNetwork = null;
+               }
+               
+               nodes.clear();
+               edges.clear();
+               nodeMap.clear();
+               edgeMap.clear();
+               
+               disposed  = true;
+       }
+}
\ No newline at end of file

Modified: 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/task/MCODEAnalyzeTask.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/task/MCODEAnalyzeTask.java
  2012-11-08 22:08:18 UTC (rev 30761)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/task/MCODEAnalyzeTask.java
  2012-11-08 22:17:35 UTC (rev 30762)
@@ -149,7 +149,7 @@
                } catch (Exception e) {
                        throw new Exception("Error while executing the MCODE 
analysis", e);
                } finally {
-                       mcodeUtil.disposeUnusedSubNetworks(network, clusters);
+                       mcodeUtil.destroyUnusedNetworks(network, clusters);
                        
                        if (listener != null) {
                                listener.handleEvent(new 
AnalysisCompletedEvent(success, clusters, imageList));

Modified: 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/util/MCODEUtil.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/util/MCODEUtil.java
 2012-11-08 22:08:18 UTC (rev 30761)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/util/MCODEUtil.java
 2012-11-08 22:17:35 UTC (rev 30762)
@@ -61,6 +61,7 @@
 import org.cytoscape.mcode.internal.model.MCODEAlgorithm;
 import org.cytoscape.mcode.internal.model.MCODECluster;
 import org.cytoscape.mcode.internal.model.MCODECurrentParameters;
+import org.cytoscape.mcode.internal.model.MCODEGraph;
 import org.cytoscape.mcode.internal.util.layout.SpringEmbeddedLayouter;
 import org.cytoscape.mcode.internal.view.MCODELoader;
 import org.cytoscape.mcode.internal.view.MCODEMainPanel;
@@ -171,7 +172,7 @@
        private Map<CyRootNetwork, Set<CySubNetwork>> createdSubNetworks;
        
        private static final Logger logger = 
LoggerFactory.getLogger(MCODEUtil.class);
-
+       
        public MCODEUtil(final RenderingEngineFactory<CyNetwork> 
renderingEngineFactory,
                                         final CyNetworkViewFactory 
networkViewFactory,
                                         final CyRootNetworkManager 
rootNetworkMgr,
@@ -219,7 +220,7 @@
                createdSubNetworks = new HashMap<CyRootNetwork, 
Set<CySubNetwork>>();
        }       
        
-       public void disposeUnusedSubNetworks(final CyNetwork network, final 
MCODECluster[] clusters) {
+       public synchronized void destroyUnusedNetworks(final CyNetwork network, 
final MCODECluster[] clusters) {
                final Map<CySubNetwork, Boolean> clusterNetworks = new 
HashMap<CySubNetwork, Boolean>();
                
                if (clusters != null && clusters.length > 0) {
@@ -237,12 +238,10 @@
                                // Only remove the subnetwork if it is not 
registered
                                if (!clusterNetworks.containsKey(sn) && 
!networkMgr.networkExists(sn.getSUID())) {
                                        try {
-                                               if 
(rootNet.containsNetwork(sn)) {
-                                                       dispose(sn);
-                                                       disposedSet.add(sn);
-                                               }
+                                               destroy(sn);
+                                               disposedSet.add(sn);
                                        } catch (Exception e) {
-                                               logger.error("Error disposing: 
" + sn);
+                                               logger.error("Error disposing: 
" + sn, e);
                                        }
                                }
                        }
@@ -251,6 +250,17 @@
                }
        }
 
+       public void destroy(final CySubNetwork net) {
+               if (net != null) {
+                       final CyRootNetwork rootNet = 
rootNetworkMgr.getRootNetwork(net);
+                       
+                       if (rootNet.containsNetwork(net)) {
+                               rootNet.removeSubNetwork(net);
+                               net.dispose();
+                       }
+               }
+       }
+       
        public MCODECurrentParameters getCurrentParameters() {
                return currentParameters;
        }
@@ -311,8 +321,8 @@
                if (networkId != null)
                        networkResults.remove(networkId);
 
-               this.getCurrentParameters().removeResultParams(resultId);
-
+               getCurrentParameters().removeResultParams(resultId);
+               
                return removed;
        }
 
@@ -477,8 +487,7 @@
 
                                        if (clusterView.getNodeViews().size() > 
0) {
                                                cluster.setView(clusterView);
-                                       } else {
-System.out.println("\t>> no node views--nodes: " + 
clusterView.getModel().getNodeCount() + " | " + net.getNodeCount());}// TODO: 
delete
+                                       }
                                } catch (Exception ex) {
                                        throw new RuntimeException(ex);
                                }
@@ -491,6 +500,26 @@
                return image;
        }
 
+       public MCODEGraph createGraph(final CyNetwork net, final 
Collection<CyNode> nodes) {
+               final CyRootNetwork root = rootNetworkMgr.getRootNetwork(net);
+               final Set<CyEdge> edges = new HashSet<CyEdge>();
+
+               for (final CyNode n : nodes) {
+                       final Set<CyEdge> adjacentEdges = new 
HashSet<CyEdge>(net.getAdjacentEdgeList(n, CyEdge.Type.ANY));
+
+                       // Get only the edges that connect nodes that belong to 
the subnetwork:
+                       for (final CyEdge e : adjacentEdges) {
+                               if (nodes.contains(e.getSource()) && 
nodes.contains(e.getTarget())) {
+                                       edges.add(e);
+                               }
+                       }
+               }
+
+               final MCODEGraph graph = new MCODEGraph(root, nodes, edges, 
this); // TODO remove circular dependency MCODEUtil/MCODEGraph
+
+               return graph;
+       }
+       
        public CySubNetwork createSubNetwork(final CyNetwork net, final 
Collection<CyNode> nodes, final SavePolicy policy) {
                final CyRootNetwork root = rootNetworkMgr.getRootNetwork(net);
                final Set<CyEdge> edges = new HashSet<CyEdge>();
@@ -901,13 +930,4 @@
 
                return props;
        }
-       
-       public static void dispose(final CyNetwork net) {
-               if (net != null) {
-                       if (net instanceof CySubNetwork)
-                               ((CySubNetwork) 
net).getRootNetwork().removeSubNetwork((CySubNetwork) net);
-                       
-                       net.dispose();
-               }
-       }
 }

Modified: 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/view/MCODEResultsPanel.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/view/MCODEResultsPanel.java
 2012-11-08 22:08:18 UTC (rev 30761)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/view/MCODEResultsPanel.java
 2012-11-08 22:17:35 UTC (rev 30762)
@@ -163,13 +163,13 @@
         * @param clusterImages A list of images of the found clusters
         * @param resultId Title of this result as determined by 
MCODESCoreAndFindAction
         */
-       public MCODEResultsPanel(MCODECluster[] clusters,
-                                                        MCODEAlgorithm alg,
-                                                        MCODEUtil mcodeUtil,
-                                                        CyNetwork network,
-                                                        CyNetworkView 
networkView,
-                                                        Image[] clusterImages,
-                                                        int resultId,
+       public MCODEResultsPanel(final MCODECluster[] clusters,
+                                                        final MCODEAlgorithm 
alg,
+                                                        final MCODEUtil 
mcodeUtil,
+                                                        final CyNetwork 
network,
+                                                        final CyNetworkView 
networkView,
+                                                        final Image[] 
clusterImages,
+                                                        final int resultId,
                                                         final 
MCODEDiscardResultAction discardResultAction) {
                setLayout(new BorderLayout());
 
@@ -219,6 +219,14 @@
                return networkView;
        }
        
+       public MCODECluster[] getClusters() {
+               return clusters;
+       }
+
+       public CyNetwork getNetwork() {
+               return network;
+       }
+
        public int getSelectedClusterRow() {
                return clusterBrowserPanel.getSelectedRow();
        }
@@ -1050,6 +1058,9 @@
                        if (futureLoader != null && !futureLoader.isDone()) {
                                drawer.stop();
                                futureLoader.cancel(false);
+                               
+                               if (!oldCluster.equals(clusters[clusterRow]))
+                                       oldCluster.dispose();
                        }
                        
                        final Runnable command = new Runnable() {
@@ -1068,7 +1079,7 @@
                                        drawPlaceHolder = newALCluster.size() > 
300;
                                        
                                        // And compare the old and new
-                                       if (!newALCluster.equals(oldALCluster)) 
{
+                                       if (!newALCluster.equals(oldALCluster)) 
{ // TODO
                                                // If the cluster has changed, 
then we conduct all non-rate-limiting steps:
                                                // Update the cluster array
                                                clusters[clusterRow] = 
newCluster;
@@ -1084,12 +1095,12 @@
                                                boolean layoutNecessary = 
newALCluster.size() > oldALCluster.size();
                                                // Draw Graph and select the 
cluster in the view in a separate thread so that it can be
                                                // interrupted by the slider 
movement
-                                               if (!newCluster.isDisposed())
+                                               if (!newCluster.isDisposed()) {
                                                        
drawer.drawGraph(newCluster, layoutNecessary, drawPlaceHolder);
-                                               
-                                               // Prevent memory leaks
-                                               oldCluster.dispose();
+                                                       oldCluster.dispose();
+                                               }
                                        }
+                                       
mcodeUtil.destroyUnusedNetworks(network, clusters);// TODO
                    }
                };
                

Modified: 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/util/MCODEUtilTest.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/util/MCODEUtilTest.java
     2012-11-08 22:08:18 UTC (rev 30761)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/util/MCODEUtilTest.java
     2012-11-08 22:17:35 UTC (rev 30762)
@@ -98,7 +98,7 @@
                MCODECluster[] clusters = findClusters(net, resultId);
                assertEquals(1, clusters.length);
                
-               mcodeUtil.disposeUnusedSubNetworks(net, clusters);
+               mcodeUtil.destroyUnusedNetworks(net, clusters);
                
                assertEquals(originalNetCount + clusters.length, 
rn.getSubNetworkList().size());
        }

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to