Author: clopes
Date: 2012-08-15 15:06:58 -0700 (Wed, 15 Aug 2012)
New Revision: 30202

Added:
   
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/AbstractMCODETest.java
   
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/util/
   
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/util/MCODEUtilTest.java
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/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/test/java/org/cytoscape/mcode/internal/model/MCODEAlgorithmTest.java
Log:
MCODE now deletes and disposes unused subnetworks (including the temporary ones 
created during the analysis) and network views.

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-08-15 22:03:16 UTC (rev 30201)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODEAlgorithm.java
   2012-08-15 22:06:58 UTC (rev 30202)
@@ -208,8 +208,8 @@
         * @param inputNetwork The network that will be scored
         * @param resultId Title of the result, used as an identifier in 
various hash maps
         */
-       public void scoreGraph(CyNetwork inputNetwork, int resultId) {
-               String callerID = "MCODEAlgorithm.MCODEAlgorithm";
+       public void scoreGraph(final CyNetwork inputNetwork, final int 
resultId) {
+               final String callerID = "MCODEAlgorithm.MCODEAlgorithm";
 
                if (inputNetwork == null) {
                        logger.error("In " + callerID + ": inputNetwork was 
null.");
@@ -218,7 +218,7 @@
 
                // Initialize
                long msTimeBefore = System.currentTimeMillis();
-               Map<Long, NodeInfo> nodeInfoHashMap = new HashMap<Long, 
NodeInfo>(inputNetwork.getNodeCount());
+               final Map<Long, NodeInfo> nodeInfoHashMap = new HashMap<Long, 
NodeInfo>(inputNetwork.getNodeCount());
 
                // Sort Doubles in descending order
                Comparator<Double> scoreComparator = new Comparator<Double>() {
@@ -233,13 +233,12 @@
                SortedMap<Double, List<Long>> nodeScoreSortedMap = new 
TreeMap<Double, List<Long>>(scoreComparator);
 
                // Iterate over all nodes and calculate MCODE score
-               NodeInfo nodeInfo = null;
                List<Long> al = null;
                int i = 0;
-               List<CyNode> nodes = inputNetwork.getNodeList();
+               final List<CyNode> nodes = inputNetwork.getNodeList();
                
-               for (CyNode n : nodes) {
-                       nodeInfo = calcNodeInfo(inputNetwork, n.getSUID());
+               for (final CyNode n : nodes) {
+                       final NodeInfo nodeInfo = calcNodeInfo(inputNetwork, 
n.getSUID());
                        nodeInfoHashMap.put(n.getSUID(), nodeInfo);
                        double nodeScore = scoreNode(nodeInfo);
                        
@@ -255,9 +254,8 @@
                                nodeScoreSortedMap.put(nodeScore, al);
                        }
 
-                       if (taskMonitor != null) {
-                               taskMonitor.setProgress( (++i / (double) 
nodes.size()) );
-                       }
+                       if (taskMonitor != null)
+                               taskMonitor.setProgress(++i / (double) 
nodes.size());
                        
                        if (cancelled)
                                break;
@@ -282,9 +280,9 @@
         * @param resultSetName Title of the result
         * @return An array containing an MCODECluster object for each cluster.
         */
-       public MCODECluster[] findClusters(CyNetwork inputNetwork, int 
resultId) {
-               SortedMap<Double, List<Long>> nodeScoreSortedMap;
-               Map<Long, NodeInfo> nodeInfoHashMap;
+       public MCODECluster[] findClusters(final CyNetwork inputNetwork, int 
resultId) {
+               final SortedMap<Double, List<Long>> nodeScoreSortedMap;
+               final Map<Long, NodeInfo> nodeInfoHashMap;
 
                // First we check if the network has been scored under this 
result title (i.e. scoring
                // was required due to a scoring parameter change).  If it 
hasn't then we want to use the
@@ -301,7 +299,6 @@
                        nodeInfoHashMap = nodeInfoResultsMap.get(resultId);
                }
 
-               MCODECluster currentCluster;
                String callerID = "MCODEAlgorithm.findClusters";
 
                if (inputNetwork == null) {
@@ -338,8 +335,6 @@
                                currentNode = alNodesWithSameScore.get(j);
 
                                if (!nodeSeenHashMap.containsKey(currentNode)) {
-                                       currentCluster = new MCODECluster();
-                                       
currentCluster.setSeedNode(currentNode);//store the current node as the seed 
node
                                        // We store the current node seen hash 
map for later exploration purposes
                                        Map<Long, Boolean> 
nodeSeenHashMapSnapShot = new HashMap<Long, Boolean>(nodeSeenHashMap);
 
@@ -359,16 +354,17 @@
                                                CySubNetwork clusterNet = 
createClusterNetwork(alCluster, inputNetwork);
 
                                                if (!filterCluster(clusterNet)) 
{
-                                                       if (params.isHaircut()) 
{
+                                                       if (params.isHaircut())
                                                                
haircutCluster(clusterNet, alCluster);
-                                                       }
 
-                                                       if (params.isFluff()) {
+                                                       if (params.isFluff())
                                                                
fluffClusterBoundary(alCluster, nodeSeenHashMap, nodeInfoHashMap);
-                                                       }
 
-                                                       
currentCluster.setALCluster(alCluster);
                                                        clusterNet = 
createClusterNetwork(alCluster, inputNetwork);
+                                                       
+                                                       MCODECluster 
currentCluster = new MCODECluster();
+                                                       
currentCluster.setALCluster(alCluster);
+                                                       
currentCluster.setSeedNode(currentNode);//store the current node as the seed 
node
                                                        
currentCluster.setNetwork(clusterNet);
                                                        
currentCluster.setClusterScore(scoreCluster(currentCluster));
                                                        
currentCluster.setNodeSeenHashMap(nodeSeenHashMapSnapShot);//store the list of 
all the nodes that have already been seen and incorporated in other clusters
@@ -416,17 +412,19 @@
                                        }
                                }
                        }
+                       
+                       // Dispose clusters that were not selected
+                       for (MCODECluster c : alClusters) {
+                               if (!selectedALClusters.contains(c))
+                                       c.dispose();
+                       }
 
                        alClusters = selectedALClusters;
                }
 
-               // Finally convert the arraylist into a fixed array
-               MCODECluster[] clusters = new MCODECluster[alClusters.size()];
-
-               for (int c = 0; c < clusters.length; c++) {
-                       clusters[c] = (MCODECluster) alClusters.get(c);
-               }
-
+               // Finally convert the list into a fixed array
+               MCODECluster[] clusters = alClusters.toArray(new 
MCODECluster[alClusters.size()]);
+               
                long msTimeAfter = System.currentTimeMillis();
                lastFindTime = msTimeAfter - msTimeBefore;
 
@@ -438,14 +436,14 @@
         *
         * @param cluster cluster being explored
         * @param nodeScoreCutoff slider source value
-        * @param inputNetwork network
+        * @param inputNet network
         * @param resultId ID of the result set being explored
         * @return explored cluster
         */
-       public MCODECluster exploreCluster(MCODECluster cluster,
-                                                                          
double nodeScoreCutoff,
-                                                                          
CyNetwork inputNetwork,
-                                                                          int 
resultId) {
+       public MCODECluster exploreCluster(final MCODECluster cluster,
+                                                                          
final double nodeScoreCutoff,
+                                                                          
final CyNetwork inputNet,
+                                                                          
final int resultId) {
                // This method is similar to the finding method with the 
exception of the filtering so that the decrease of the cluster size
                // can produce a single node, also the use of the node seen 
hash map is differentially applied...
                Map<Long, NodeInfo> nodeInfoHashMap = 
nodeInfoResultsMap.get(resultId);
@@ -467,40 +465,38 @@
                                .getMaxDepthFromStart(), nodeInfoHashMap);
 
                // Make sure seed node is part of cluster, if not already in 
there
-               if (!alCluster.contains(seedNode)) {
+               if (!alCluster.contains(seedNode))
                        alCluster.add(seedNode);
-               }
 
                // Create an input graph for the filter and haircut methods
-               CySubNetwork clusterNetwork = createClusterNetwork(alCluster, 
inputNetwork);
+               CySubNetwork clusterNet = createClusterNetwork(alCluster, 
inputNet);
 
-               if (params.isHaircut()) {
-                       haircutCluster(clusterNetwork, alCluster);
-               }
+               if (params.isHaircut())
+                       haircutCluster(clusterNet, alCluster);
 
-               if (params.isFluff()) {
+               if (params.isFluff())
                        fluffClusterBoundary(alCluster, nodeSeenHashMap, 
nodeInfoHashMap);
-               }
 
+               clusterNet = createClusterNetwork(alCluster, inputNet);
+               
+               cluster.setNetwork(clusterNet);
                cluster.setALCluster(alCluster);
-               clusterNetwork = createClusterNetwork(alCluster, inputNetwork);
-               cluster.setNetwork(clusterNetwork);
                cluster.setClusterScore(scoreCluster(cluster));
                
                return cluster;
        }
 
-       private CySubNetwork createClusterNetwork(List<Long> alCluster, 
CyNetwork inputNetwork) {
-               Set<CyNode> nodes = new HashSet<CyNode>();
+       private CySubNetwork createClusterNetwork(final List<Long> alCluster, 
final CyNetwork inputNet) {
+               final Set<CyNode> nodes = new HashSet<CyNode>();
 
-               for (Long id : alCluster) {
-                       CyNode n = inputNetwork.getNode(id);
+               for (final Long id : alCluster) {
+                       CyNode n = inputNet.getNode(id);
                        nodes.add(n);
                }
 
-               CySubNetwork outputNetwork = 
mcodeUtil.createSubNetwork(inputNetwork, nodes, SavePolicy.DO_NOT_SAVE);
+               CySubNetwork outputNet = mcodeUtil.createSubNetwork(inputNet, 
nodes, SavePolicy.DO_NOT_SAVE);
 
-               return outputNetwork;
+               return outputNet;
        }
 
        /**
@@ -548,11 +544,10 @@
         * @param nodeId    The SUID of the node in the input network to score
         * @return A NodeInfo object containing node information required for 
the algorithm
         */
-       private NodeInfo calcNodeInfo(CyNetwork inputNetwork, Long nodeId) {
+       private NodeInfo calcNodeInfo(final CyNetwork inputNetwork, final Long 
nodeId) {
                final Long[] neighborhood;
+               final String callerID = "MCODEAlgorithm.calcNodeInfo";
 
-               String callerID = "MCODEAlgorithm.calcNodeInfo";
-
                if (inputNetwork == null) {
                        logger.error("In " + callerID + ": gpInputGraph was 
null.");
                        return null;
@@ -595,7 +590,7 @@
                }
                
                // extract neighborhood subgraph
-               CySubNetwork neighborhoodNet = 
mcodeUtil.createSubNetwork(inputNetwork, neighbors, SavePolicy.DO_NOT_SAVE);
+               final CySubNetwork neighborhoodNet = 
mcodeUtil.createSubNetwork(inputNetwork, neighbors, SavePolicy.DO_NOT_SAVE);
                
                if (neighborhoodNet == null) {
                        // this shouldn't happen
@@ -604,12 +599,11 @@
                }
 
                // Calculate the node information for each node
-               NodeInfo nodeInfo = new NodeInfo();
+               final NodeInfo nodeInfo = new NodeInfo();
 
                // Density
-               if (neighborhoodNet != null) {
+               if (neighborhoodNet != null)
                        nodeInfo.density = calcDensity(neighborhoodNet, 
params.isIncludeLoops());
-               }
                
                nodeInfo.numNodeNeighbors = neighborhood.length;
 
@@ -622,9 +616,8 @@
                
                // Calculate the core density - amplifies the density of 
heavily interconnected regions and attenuates
                // that of less connected regions
-               if (kCore != null) {
+               if (kCore != null)
                        nodeInfo.coreDensity = calcDensity(kCore, 
params.isIncludeLoops());
-               }
 
                // Record neighbor array for later use in cluster detection step
                nodeInfo.nodeNeighbors = neighborhood;
@@ -776,10 +769,9 @@
         * @param clusterNetwork The cluster to check if it passes the filter
         * @return true if cluster should be filtered, false otherwise
         */
-       private boolean filterCluster(CySubNetwork clusterNetwork) {
-               if (clusterNetwork == null) {
+       private boolean filterCluster(final CySubNetwork clusterNetwork) {
+               if (clusterNetwork == null)
                        return true;
-               }
 
                // filter if the cluster does not satisfy the user specified 
k-core
                CySubNetwork kCore = getKCore(clusterNetwork, 
params.getKCore());
@@ -794,17 +786,17 @@
         * @param cluster        The cluster node ID list (in the original 
graph)
         * @return true
         */
-       private boolean haircutCluster(CySubNetwork clusterNetwork, List<Long> 
cluster) {
+       private boolean haircutCluster(final CySubNetwork clusterNetwork, final 
List<Long> cluster) {
                // get 2-core
-               CySubNetwork kCore = getKCore(clusterNetwork, 2);
+               final CySubNetwork kCore = getKCore(clusterNetwork, 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 
gpInputGraph node indices
-                       for (CyNode n : kCore.getNodeList()) {
+                       
+                       // must add back the nodes in a way that preserves node 
indices
+                       for (CyNode n : kCore.getNodeList())
                                cluster.add(n.getSUID());
-                       }
                }
                
                return true;
@@ -819,7 +811,7 @@
         *                     possible edges.
         * @return The density of the network
         */
-       public double calcDensity(CySubNetwork network, boolean includeLoops) {
+       private double calcDensity(final CySubNetwork network, final boolean 
includeLoops) {
                String callerID = "MCODEAlgorithm.calcDensity";
 
                if (network == null) {
@@ -861,65 +853,60 @@
        /**
         * Find a k-core of a network. A k-core is a subgraph of minimum degree 
k
         *
-        * @param inputNetwork The input network
+        * @param inputNet 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
         */
-       public CySubNetwork getKCore(CySubNetwork inputNetwork, int k) {
+       private CySubNetwork getKCore(final CySubNetwork inputNet, int k) {
                String callerID = "MCODEAlgorithm.getKCore";
 
-               if (inputNetwork == null) {
+               if (inputNet == null) {
                        logger.error("In " + callerID + ": inputNetwork was 
null.");
                        return null;
                }
 
                // filter all nodes with degree less than k until convergence
                boolean firstLoop = true;
-               CySubNetwork outputNetwork = null;
+               CySubNetwork outputNet = inputNet;
 
                while (true && !cancelled) {
                        int numDeleted = 0;
-                       List<Long> alCoreNodeIndices = new 
ArrayList<Long>(inputNetwork.getNodeCount());
-                       List<CyNode> nodes = inputNetwork.getNodeList();
+                       List<Long> alCoreNodeIndices = new 
ArrayList<Long>(outputNet.getNodeCount());
+                       List<CyNode> nodes = outputNet.getNodeList();
 
                        for (CyNode n : nodes) {
-                               int degree = 
inputNetwork.getAdjacentEdgeList(n, CyEdge.Type.ANY).size();
+                               int degree = outputNet.getAdjacentEdgeList(n, 
CyEdge.Type.ANY).size();
 
-                               if (degree >= k) {
+                               if (degree >= k)
                                        alCoreNodeIndices.add(n.getSUID()); 
//contains all nodes with degree >= k
-                               } else {
+                               else
                                        numDeleted++;
-                               }
                        }
 
                        if (numDeleted > 0 || firstLoop) {
                                Set<CyNode> outputNodes = new HashSet<CyNode>();
 
                                for (Long index : alCoreNodeIndices) {
-                                       CyNode n = inputNetwork.getNode(index);
+                                       CyNode n = outputNet.getNode(index);
                                        outputNodes.add(n);
                                }
                                
-                               outputNetwork = 
mcodeUtil.createSubNetwork(inputNetwork.getRootNetwork(), outputNodes,
-                                               SavePolicy.DO_NOT_SAVE);
+                               outputNet = 
mcodeUtil.createSubNetwork(outputNet.getRootNetwork(), outputNodes, 
SavePolicy.DO_NOT_SAVE);
                                
-                               if (outputNetwork.getNodeCount() == 0) {
+                               if (outputNet.getNodeCount() == 0)
                                        return null;
-                               }
 
-                               // Iterate again, but with a new k-core input 
graph
-                               inputNetwork = outputNetwork;
-
-                               if (firstLoop) {
+                               // Iterate again, but with a new k-core input 
graph...
+                               
+                               if (firstLoop)
                                        firstLoop = false;
-                               }
                        } else {
                                // stop the loop
                                break;
                        }
                }
 
-               return outputNetwork;
+               return outputNet;
        }
 
        /**
@@ -930,8 +917,8 @@
         *         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]
         */
-       public Object[] getHighestKCore(CySubNetwork network) {
-               String callerID = "MCODEAlgorithm.getHighestKCore";
+       private Object[] getHighestKCore(final CySubNetwork network) {
+               final String callerID = "MCODEAlgorithm.getHighestKCore";
 
                if (network == null) {
                        logger.error("In " + callerID + ": network was null.");
@@ -939,16 +926,15 @@
                }
 
                int i = 1;
-               CySubNetwork curNet = null, prevNet = null;
+               CySubNetwork curNet = network, prevNet = null;
 
-               while ((curNet = getKCore(network, i)) != null) {
-                       network = curNet;
+               while ((curNet = getKCore(curNet, i)) != null) {
                        prevNet = curNet;
                        i++;
                }
-
+               
                Integer k = i - 1;
-               Object[] returnArray = new Object[2];
+               final Object[] returnArray = new Object[2];
                returnArray[0] = k;
                returnArray[1] = prevNet; //in the last iteration, curNet is 
null (loop termination condition)
 

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-08-15 22:03:16 UTC (rev 30201)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/model/MCODECluster.java
     2012-08-15 22:06:58 UTC (rev 30202)
@@ -48,7 +48,7 @@
 public class MCODECluster {
 
        private List<Long> alCluster;
-       private CyNetworkView view; // keeps track of layout so that layout 
process doesn't have to be repeated unecessarily
+       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
@@ -72,7 +72,7 @@
                return clusterName;
        }
 
-       public void setClusterName(String clusterName) {
+       public void setClusterName(final String clusterName) {
                this.clusterName = clusterName;
        }
 
@@ -80,7 +80,10 @@
                return view;
        }
 
-       public void setView(CyNetworkView view) {
+       public void setView(final CyNetworkView view) {
+               if (this.view != null)
+                       this.view.dispose();
+               
                this.view = view;
        }
 
@@ -88,7 +91,11 @@
                return network;
        }
 
-       public void setNetwork(CySubNetwork network) {
+       public void setNetwork(final CySubNetwork network) {
+               if (view != null && view.getModel().equals(this.network))
+                       view.dispose();
+               
+               dispose(this.network);
                this.network = network;
        }
 
@@ -96,7 +103,7 @@
                return clusterScore;
        }
 
-       public void setClusterScore(double clusterScore) {
+       public void setClusterScore(final double clusterScore) {
                this.clusterScore = clusterScore;
        }
 
@@ -104,7 +111,7 @@
                return alCluster;
        }
 
-       public void setALCluster(List<Long> alCluster) {
+       public void setALCluster(final List<Long> alCluster) {
                this.alCluster = alCluster;
        }
 
@@ -132,4 +139,17 @@
                this.rank = rank;
                this.clusterName = "Cluster " + (rank + 1);
        }
+       
+       public void dispose() {
+               if (view != null)
+                       view.dispose();
+               dispose(network);
+       }
+       
+       private static void dispose(final CySubNetwork net) {
+               if (net != null) {
+                       net.getRootNetwork().removeSubNetwork(net);
+                       net.dispose();
+               }
+       }
 }

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-08-15 22:03:16 UTC (rev 30201)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/task/MCODEAnalyzeTask.java
  2012-08-15 22:06:58 UTC (rev 30202)
@@ -149,7 +149,7 @@
                } catch (Exception e) {
                        throw new Exception("Error while executing the MCODE 
analysis", e);
                } finally {
-                       mcodeUtil.removeUnusedSubNetworks(network, clusters);
+                       mcodeUtil.disposeUnusedSubNetworks(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-08-15 22:03:16 UTC (rev 30201)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/main/java/org/cytoscape/mcode/internal/util/MCODEUtil.java
 2012-08-15 22:06:58 UTC (rev 30202)
@@ -129,6 +129,7 @@
  * * Description: Utilities for MCODE
  */
 
+// TODO refactor: remove circular dependencies
 /**
  * Utilities for MCODE
  */
@@ -161,7 +162,7 @@
 
        private int currentResultId;
        
-       private Set<CySubNetwork> subNetworks;
+       private Map<CyRootNetwork, Set<CySubNetwork>> createdSubNetworks;
        
        private static final Logger logger = 
LoggerFactory.getLogger(MCODEUtil.class);
 
@@ -209,26 +210,39 @@
                currentParameters = new MCODECurrentParameters();
                networkAlgorithms = new HashMap<Long, MCODEAlgorithm>();
                networkResults = new HashMap<Long, Set<Integer>>();
-               subNetworks = new HashSet<CySubNetwork>();
+               createdSubNetworks = new HashMap<CyRootNetwork, 
Set<CySubNetwork>>();
        }       
        
-       public void removeUnusedSubNetworks(CyNetwork network, MCODECluster[] 
clusters) {
-               Map<CySubNetwork, Boolean> clusterNetworks = new 
HashMap<CySubNetwork, Boolean>();
+       public void disposeUnusedSubNetworks(final CyNetwork network, final 
MCODECluster[] clusters) {
+               final Map<CySubNetwork, Boolean> clusterNetworks = new 
HashMap<CySubNetwork, Boolean>();
                
                if (clusters != null && clusters.length > 0) {
                        for (MCODECluster c : clusters)
                                clusterNetworks.put(c.getNetwork(), 
Boolean.TRUE);
                }
                
-               CyRootNetwork rootNet = rootNetworkMgr.getRootNetwork(network);
+               final CyRootNetwork rootNet = 
rootNetworkMgr.getRootNetwork(network);
+               final Set<CySubNetwork> snSet = createdSubNetworks.get(rootNet);
                
-               for (CySubNetwork sn : subNetworks) {
-                       // Only remove the subnetwork if it is not registered
-                       if (!clusterNetworks.containsKey(sn) && 
!networkMgr.networkExists(sn.getSUID()))
-                               rootNet.removeSubNetwork(sn);
+               if (snSet != null) {
+                       final Set<CySubNetwork> disposedSet = new 
HashSet<CySubNetwork>();
+                       
+                       for (final CySubNetwork sn : snSet) {
+                               // 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);
+                                               }
+                                       } catch (Exception e) {
+                                               logger.error("Error disposing: 
" + sn);
+                                       }
+                               }
+                       }
+                       
+                       snSet.removeAll(disposedSet);
                }
-               
-               subNetworks.clear();
        }
 
        public MCODECurrentParameters getCurrentParameters() {
@@ -274,34 +288,28 @@
 
        public boolean removeNetworkResult(final int resultId) {
                boolean removed = false;
-               Long networkToRemove = null;
+               Long networkId = null;
 
                for (Entry<Long, Set<Integer>> entries : 
networkResults.entrySet()) {
                        Set<Integer> ids = entries.getValue();
 
                        if (ids.remove(resultId)) {
-                               if (ids.isEmpty()) {
-                                       networkToRemove = entries.getKey();
-                               }
+                               if (ids.isEmpty())
+                                       networkId = entries.getKey();
 
                                removed = true;
                                break;
                        }
                }
 
-               if (networkToRemove != null) {
-                       removeNetworkResults(networkToRemove);
-               }
+               if (networkId != null)
+                       networkResults.remove(networkId);
 
                this.getCurrentParameters().removeResultParams(resultId);
 
                return removed;
        }
 
-       public Set<Integer> removeNetworkResults(final long suid) {
-               return networkResults.remove(suid);
-       }
-
        /**
         * Convert a network to an image.  This is used by the 
MCODEResultsPanel.
         * 
@@ -491,8 +499,17 @@
                }
                
                final CySubNetwork subNet = root.addSubNetwork(nodes, edges, 
policy);
-               subNetworks.add(subNet);
                
+               // Save it for later disposal
+               Set<CySubNetwork> snSet = createdSubNetworks.get(root);
+               
+               if (snSet == null) {
+                       snSet = new HashSet<CySubNetwork>();
+                       createdSubNetworks.put(root, snSet);
+               }
+               
+               snSet.add(subNet);
+               
                return subNet;
        }
 
@@ -807,4 +824,13 @@
 
                return props;
        }
+       
+       public static void dispose(final CyNetwork net) {
+               if (net != null) {
+                       if (net instanceof CySubNetwork)
+                               ((CySubNetwork) 
net).getRootNetwork().removeSubNetwork((CySubNetwork) net);
+                       
+                       net.dispose();
+               }
+       }
 }

Added: 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/AbstractMCODETest.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/AbstractMCODETest.java
                              (rev 0)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/AbstractMCODETest.java
      2012-08-15 22:06:58 UTC (rev 30202)
@@ -0,0 +1,62 @@
+package org.cytoscape.mcode.internal;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.cytoscape.ding.NetworkViewTestSupport;
+import org.cytoscape.mcode.internal.model.MCODEAlgorithm;
+import org.cytoscape.mcode.internal.model.MCODECluster;
+import org.cytoscape.mcode.internal.model.MCODEParameterSet;
+import org.cytoscape.mcode.internal.util.MCODEUtil;
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.model.CyNode;
+
+public abstract class AbstractMCODETest {
+
+       protected MCODEAlgorithm alg;
+       protected MCODEUtil mcodeUtil;
+       protected final NetworkViewTestSupport netViewTestSupport;
+
+       public AbstractMCODETest() {
+               netViewTestSupport = new NetworkViewTestSupport();
+       }
+
+       protected MCODECluster[] findClusters(CyNetwork net, int resultId) {
+               return findClusters(net, resultId, new MCODEParameterSet());
+       }
+
+       protected MCODECluster[] findClusters(CyNetwork net, int resultId, 
MCODEParameterSet params) {
+               mcodeUtil.getCurrentParameters().setParams(params, resultId, 
net.getSUID());
+               alg = new MCODEAlgorithm(net.getSUID(), mcodeUtil);
+               alg.scoreGraph(net, resultId);
+               
+               return alg.findClusters(net, resultId);
+       }
+
+       protected CyNetwork createCompleteGraph(int totalNodes) {
+               CyNetwork net = netViewTestSupport.getNetwork();
+               
+               for (int i = 0; i < totalNodes; i++) {
+                       net.addNode();
+               }
+               
+               List<CyNode> nodes = net.getNodeList();
+               
+               for (int i = 0; i < totalNodes; i++) {
+                       CyNode src = nodes.get(i);
+                       
+                       for (int j = 0; j < totalNodes; j++) {
+                               CyNode tgt = nodes.get(j);
+                               
+                               if (src != tgt && !net.containsEdge(src, tgt))
+                                       net.addEdge(src, tgt, false);
+                       }
+               }
+               
+               assertEquals((totalNodes*(totalNodes-1))/2, net.getEdgeCount());
+               
+               return net;
+       }
+
+}
\ No newline at end of file

Modified: 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/model/MCODEAlgorithmTest.java
===================================================================
--- 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/model/MCODEAlgorithmTest.java
       2012-08-15 22:03:16 UTC (rev 30201)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/model/MCODEAlgorithmTest.java
       2012-08-15 22:06:58 UTC (rev 30202)
@@ -1,13 +1,13 @@
 package org.cytoscape.mcode.internal.model;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
-import java.util.List;
-
 import org.cytoscape.application.CyApplicationManager;
 import org.cytoscape.application.swing.CySwingApplication;
 import org.cytoscape.ding.NetworkViewTestSupport;
 import org.cytoscape.event.CyEventHelper;
+import org.cytoscape.mcode.internal.AbstractMCODETest;
 import org.cytoscape.mcode.internal.util.MCODEUtil;
 import org.cytoscape.model.CyNetwork;
 import org.cytoscape.model.CyNetworkManager;
@@ -65,15 +65,14 @@
 /**
  * Test for the MCODE algorithm
  */
-public class MCODEAlgorithmTest {
+public class MCODEAlgorithmTest extends AbstractMCODETest {
 
-       MCODEAlgorithm alg;
        CyNetwork networkSmall;
-       MCODEUtil mcodeUtil;
        
        @Mock RenderingEngineFactory<CyNetwork> rendererFactory;
        @Mock CyRootNetworkManager rootNetMgr;
        @Mock CyApplicationManager appMgr;
+       @Mock CyNetworkManager netMgr;
        @Mock CyNetworkViewManager netViewMgr;
        @Mock VisualMappingManager vmMgr;
        @Mock VisualStyleFactory styleFactory;
@@ -83,7 +82,7 @@
        @Mock FileUtil fileUtil;
        
        NetworkViewTestSupport netViewTestSupport;
-       CyNetworkManager netMgr;
+       
        CyNetworkViewFactory netViewFactory;
 
        @Before
@@ -159,46 +158,9 @@
                assertNotNull(c.getSeedNode());
                
                // TODO: fix
-               // check scores of the nodes
+               // check scores of all nodes
 //             for (CyNode n : cn.getNodeList()) {
 //                     assertEquals(13.345, alg.getNodeScore(n.getSUID(), 
resultId), 0.001);
 //             }
        }
-       
-       private MCODECluster[] findClusters(CyNetwork net, int resultId) {
-               return findClusters(net, resultId, new MCODEParameterSet());
-       }
-       
-       private MCODECluster[] findClusters(CyNetwork net, int resultId, 
MCODEParameterSet params) {
-               mcodeUtil.getCurrentParameters().setParams(params, resultId, 
net.getSUID());
-               alg = new MCODEAlgorithm(net.getSUID(), mcodeUtil);
-               alg.scoreGraph(net, resultId);
-               
-               return alg.findClusters(net, resultId);
-       }
-
-       private CyNetwork createCompleteGraph(int totalNodes) {
-               CyNetwork net = netViewTestSupport.getNetwork();
-               
-               for (int i = 0; i < totalNodes; i++) {
-                       net.addNode();
-               }
-               
-               List<CyNode> nodes = net.getNodeList();
-               
-               for (int i = 0; i < totalNodes; i++) {
-                       CyNode src = nodes.get(i);
-                       
-                       for (int j = 0; j < totalNodes; j++) {
-                               CyNode tgt = nodes.get(j);
-                               
-                               if (src != tgt && !net.containsEdge(src, tgt))
-                                       net.addEdge(src, tgt, false);
-                       }
-               }
-               
-               assertEquals((totalNodes*(totalNodes-1))/2, net.getEdgeCount());
-               
-               return net;
-       }
 }

Added: 
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
                             (rev 0)
+++ 
csplugins/trunk/toronto/clopes/mcode/src/test/java/org/cytoscape/mcode/internal/util/MCODEUtilTest.java
     2012-08-15 22:06:58 UTC (rev 30202)
@@ -0,0 +1,105 @@
+package org.cytoscape.mcode.internal.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.cytoscape.application.CyApplicationManager;
+import org.cytoscape.application.swing.CySwingApplication;
+import org.cytoscape.event.CyEventHelper;
+import org.cytoscape.mcode.internal.AbstractMCODETest;
+import org.cytoscape.mcode.internal.model.MCODECluster;
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.model.CyNetworkManager;
+import org.cytoscape.model.subnetwork.CyRootNetwork;
+import org.cytoscape.model.subnetwork.CyRootNetworkManager;
+import org.cytoscape.util.swing.FileUtil;
+import org.cytoscape.view.model.CyNetworkViewFactory;
+import org.cytoscape.view.model.CyNetworkViewManager;
+import org.cytoscape.view.presentation.RenderingEngineFactory;
+import org.cytoscape.view.vizmap.VisualMappingFunctionFactory;
+import org.cytoscape.view.vizmap.VisualMappingManager;
+import org.cytoscape.view.vizmap.VisualStyleFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Copyright (c) 2004 Memorial Sloan-Kettering Cancer Center
+ * *
+ * * Code written by: Gary Bader
+ * * Authors: Gary Bader, Ethan Cerami, Chris Sander
+ * *
+ * * This library is free software; you can redistribute it and/or modify it
+ * * under the terms of the GNU Lesser General Public License as published
+ * * by the Free Software Foundation; either version 2.1 of the License, or
+ * * any later version.
+ * *
+ * * This library is distributed in the hope that it will be useful, but
+ * * WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF
+ * * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  The software and
+ * * documentation provided hereunder is on an "as is" basis, and
+ * * Memorial Sloan-Kettering Cancer Center
+ * * has no obligations to provide maintenance, support,
+ * * updates, enhancements or modifications.  In no event shall the
+ * * Memorial Sloan-Kettering Cancer Center
+ * * be liable to any party for direct, indirect, special,
+ * * incidental or consequential damages, including lost profits, arising
+ * * out of the use of this software and its documentation, even if
+ * * Memorial Sloan-Kettering Cancer Center
+ * * has been advised of the possibility of such damage.  See
+ * * the GNU Lesser General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU Lesser General Public License
+ * * along with this library; if not, write to the Free Software Foundation,
+ * * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * *
+ * * User: Gary Bader
+ * * Date: Jul 9, 2004
+ * * Time: 11:57:55 AM
+ * * Description  JUnit testing for MCODE
+ */
+
+/**
+ * Test for the MCODE algorithm
+ */
+public class MCODEUtilTest extends AbstractMCODETest {
+
+       CyNetwork networkSmall;
+       @Mock RenderingEngineFactory<CyNetwork> rendererFactory;
+       @Mock CyRootNetworkManager rootNetMgr;
+       @Mock CyApplicationManager appMgr;
+       @Mock CyNetworkManager netMgr;
+       @Mock CyNetworkViewManager netViewMgr;
+       @Mock VisualMappingManager vmMgr;
+       @Mock VisualStyleFactory styleFactory;
+       @Mock VisualMappingFunctionFactory vmfFactory;
+       @Mock CySwingApplication swingApp;
+       @Mock CyEventHelper evtHelper;
+       @Mock FileUtil fileUtil;
+       
+       CyNetworkViewFactory netViewFactory;
+
+       @Before
+       public void setUp() throws Exception {
+               MockitoAnnotations.initMocks(this);
+               rootNetMgr = netViewTestSupport.getRootNetworkFactory();
+               netViewFactory = netViewTestSupport.getNetworkViewFactory();
+               
+               mcodeUtil = new MCODEUtil(rendererFactory, netViewFactory, 
rootNetMgr, appMgr, netMgr, netViewMgr,
+                               styleFactory, vmMgr, swingApp, evtHelper, 
vmfFactory, vmfFactory, fileUtil);
+       }
+       
+       @Test
+       public void testDisposeUnnusedNetworks() {
+               final CyNetwork net = createCompleteGraph(16);
+               final CyRootNetwork rn = 
netViewTestSupport.getRootNetworkFactory().getRootNetwork(net);
+               int originalNetCount = rn.getSubNetworkList().size(); 
+               int resultId = 1;
+               MCODECluster[] clusters = findClusters(net, resultId);
+               assertEquals(1, clusters.length);
+               
+               mcodeUtil.disposeUnusedSubNetworks(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