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.