edgeArray = getNetworkEdges(currentNetwork, nodeMap, attribute);
+
+ String basePath = RemoteServer.getBasePath();
+
+ // Get our initial job
+ ClusterJob job = (ClusterJob) executionService.createCyJob("ClusterJob"); //creates a new ClusterJob object
+ // Get the data service
+ CyJobDataService dataService = job.getJobDataService(); //gets the dataService of the execution service
+ // Add our data
+ CyJobData jobData = dataService.addData(null, "nodes", nodeArray);
+ jobData = dataService.addData(jobData, "edges", edgeArray);
+ job.storeClusterData(clusterAttributeName, currentNetwork, clusterManager, createGroups, GROUP_ATTRIBUTE, null, getShortName());
+ // Create our handler
+ NetworkClusterJobHandler jobHandler = new NetworkClusterJobHandler(job, network, context.vizProperties.showUI, context.vizProperties.restoreEdges);
+ job.setJobMonitor(jobHandler);
+ // Submit the job
+ CyJobStatus exStatus = executionService.executeJob(job, basePath, configuration, jobData);
+
+ CyJobStatus.Status status = exStatus.getStatus();
+ System.out.println("Status: " + status);
+
+ if (status == Status.FINISHED) {
+ jobHandler.loadData(job, taskMonitor);
+ } else if (status == Status.RUNNING
+ || status == Status.SUBMITTED
+ || status == Status.QUEUED) {
+ CyJobManager manager = registrar.getService(CyJobManager.class);
+ manager.addJob(job, jobHandler, 5); //this one shows the load button
+
+ } else if (status == Status.ERROR) {
+ monitor.showMessage(TaskMonitor.Level.ERROR, "Job error: " + exStatus.getMessage());
+ } else if (status == Status.UNKNOWN
+ || status == Status.CANCELED
+ || status == Status.FAILED
+ || status == Status.TERMINATED
+ || status == Status.PURGED) {
+ monitor.setStatusMessage("Job status: " + status);
+ }
+
+ // Save our SUIDs in case we get saved and restored
+ SUIDUtil.saveSUIDs(job, currentNetwork, currentNetwork.getNodeList());
+
+ }
+
+}
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/DBScan/DBScanClusterTaskFactory.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/DBScan/DBScanClusterTaskFactory.java
new file mode 100644
index 0000000..14d5784
--- /dev/null
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/DBScan/DBScanClusterTaskFactory.java
@@ -0,0 +1,101 @@
+package edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.DBScan;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.service.util.CyServiceRegistrar;
+import org.cytoscape.task.NetworkTaskFactory;
+import org.cytoscape.work.TaskIterator;
+
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.AbstractClusterTaskFactory;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.MCL.MCLCluster;
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterViz;
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterTaskFactory.ClusterType;
+
+public class DBScanClusterTaskFactory extends AbstractClusterTaskFactory{
+ DBScanContext context = null;
+ final CyServiceRegistrar registrar;
+
+ public DBScanClusterTaskFactory(ClusterManager clusterManager, CyServiceRegistrar registrar) {
+ super(clusterManager);
+ context = new DBScanContext();
+ this.registrar = registrar;
+ }
+
+ public String getName() {return DBScanCluster.NAME;}
+
+ public String getShortName() {return DBScanCluster.SHORTNAME;}
+
+ @Override
+ public String getLongDescription() {
+ return "This function implements the DBScan (Density-Based Spaciel Clustering of Applications with Noise)"+
+ "algorithm for finding community structure. It finds core samples of high density and expands clusters"+
+ "from them. Good for data which contains clusters of similar density."+
+ "see Ester, M., H.P.Kriegel, J. Sander, and X. Xu, "+
+ "A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases with Noise."+
+ "In Proceedings of the 2nd International Conference on Knowledge Discovery and Data Mining, "+
+ "Portland, OR, AAAI Press, pp. 226–231. 1996"+
+ "
"+
+ "The DBSCAN algorithm views clusters as areas of high"+
+ "density separated by areas of low density. Due to this rather"+
+ "generic view, clusters found by DBSCAN can be any shape,"+
+ "as opposed to k-means which assumes that clusters are convex"+
+ "shaped. The central component to the DBSCAN is the concept"+
+ "of core samples, which are samples that are in areas of"+
+ "high density. A cluster is therefore a set of core samples,"+
+ "each close to each other (measured by some distance measure)"+
+ "and a set of non-core samples that are close to a core sample"+
+ "(but are not themselves core samples). There are two parameters"+
+ "to the algorithm, min_samples and eps, which define formally"+
+ "what we mean when we say dense. Higher min_samples or lower"+
+ "eps indicate higher density necessary to form a cluster."+
+ "
More formally, we define a core sample as being a sample"+
+ "in the dataset such that there exist min_samples other samples"+
+ "within a distance of eps, which are defined as neighbors"+
+ "of the core sample. This tells us that the core sample is"+
+ "in a dense area of the vector space. A cluster is a set of"+
+ "core samples that can be built by recursively taking a core"+
+ "sample, finding all of its neighbors that are core samples,"+
+ "finding all of their neighbors that are core samples,"+
+ "and so on. A cluster also has a set of non-core samples,"+
+ "which are samples that are neighbors of a core sample in the"+
+ "cluster but are not themselves core samples. Intuitively,"+
+ "these samples are on the fringes of a cluster."+
+ "
Any core sample is part of a cluster, by definition. Any"+
+ "sample that is not a core sample, and is at least eps in"+
+ "distance from any core sample, is considered an outlier by"+
+ "the algorithm."+
+ "While the parameter min_samples primarily controls how"+
+ "tolerant the algorithm is towards noise (on noisy and large"+
+ "data sets it may be desirable to increase this parameter),"+
+ "the parameter eps is crucial to choose appropriately for the"+
+ "data set and distance function and usually cannot be left"+
+ "at the default value. It controls the local neighborhood"+
+ "of the points. When chosen too small, most data will not be"+
+ "clustered at all (and labeled as -1 for “noise”). When"+
+ "chosen too large, it causes close clusters to be merged"+
+ "into one cluster, and eventually the entire data set to be"+
+ "returned as a single cluster. Some heuristics for choosing"+
+ "this parameter have been discussed in the literature, for"+
+ "example based on a knee in the nearest neighbor distances plot.";
+ }
+
+ @Override
+ public ClusterViz getVisualizer() {
+ return null;
+ }
+
+ @Override
+ public List getTypeList() {
+ return Collections.singletonList(ClusterType.NETWORK);
+ }
+
+ @Override
+ public TaskIterator createTaskIterator() {
+ return new TaskIterator(new DBScanCluster(context, clusterManager, registrar));
+ }
+
+
+}
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/DBScan/DBScanContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/DBScan/DBScanContext.java
new file mode 100644
index 0000000..4c15f0f
--- /dev/null
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/DBScan/DBScanContext.java
@@ -0,0 +1,142 @@
+package edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.DBScan;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.cytoscape.model.CyColumn;
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.model.CyTable;
+import org.cytoscape.work.ContainsTunables;
+import org.cytoscape.work.Tunable;
+import org.cytoscape.work.swing.TunableUIHelper;
+import org.cytoscape.work.util.ListSingleSelection;
+
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterAlgorithmContext;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.ModelUtils;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.AdvancedProperties;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.edgeConverters.EdgeAttributeHandler;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.NetworkVizProperties;
+
+public class DBScanContext implements ClusterAlgorithmContext {
+ CyNetwork network;
+ TunableUIHelper helper;
+
+ //Tunables
+ //
+ private ListSingleSelection attribute ;
+ @Tunable(description = "Attribute", groups={"Source for array data"}, params="displayState=uncollapsed",
+ longDescription = "The column containing the data to be used for the clustering. "+
+ "If no weight column is used, select ```--NONE---```",
+ exampleStringValue = "weight",
+ gravity=1.0)
+ public ListSingleSelection getattribute(){
+ attribute = ModelUtils.updateEdgeAttributeList(network, attribute);
+ return attribute;
+ }
+ public void setattribute(ListSingleSelection attr) { }
+
+ @Tunable(description = "EPS",
+ longDescription = "The maximum distance between two samples for one to be considered as in the neighborhood of the other.",
+ exampleStringValue = "0.5",
+ tooltip = "The maximum distance between two samples for one to be considered as in the neighborhood of the other. This is not a maximum bound on the distances of points within a cluster. This is the most important DBSCAN parameter to choose appropriately for your data set and distance function.",
+ groups = {"DBScan Advanced Settings"}, gravity = 1.0)
+ public double eps = 0.5;
+
+ @Tunable(description = "Minimum Samples",
+ longDescription = "The number of samples (or total weight) in a neighborhood for a point to be considered as a core point. This includes the point itself.",
+ exampleStringValue = "5",
+ tooltip = "The number of samples (or total weight) in a neighborhood for a point to be considered as a core point. This includes the point itself.",
+ groups = {"DBScan Advanced Settings"}, gravity = 2.0)
+ public int min_samples = 5;
+
+ @Tunable(description = "Metric",
+ longDescription = "The metric to use when calculating distance between instances in a feature array.",
+ exampleStringValue = "euclidean",
+ tooltip = "The metric to use when calculating distance between instances in a feature array. It must be one of: - cityblock
- cosine
- euclidean
- l1
- l2
- manhattan
- braycurtis
- canberra
- chebyshev
- correlation
- dice
- hamming
- jaccard
- kulsinski
- mahalanobis
- minkowski
- rogerstanimoto
- russellrao
- seuclidean
- sokalmicherner
- sokalsneath
- sqeuclidean
- yule
",
+ groups = {"DBScan Advanced Settings"}, gravity = 3.0)
+ public ListSingleSelection metric = new ListSingleSelection("cityblock", "cosine", "euclidean", "l1", "l2", "manhattan",
+ "braycurtis", "canberra", "chebyshev", "correlation", "dice",
+ "hamming", "jaccard", "kulsinski", "mahalanobis", "minkowski",
+ "rogerstanimoto", "russellrao", "seuclidean", "sokalmichener",
+ "sokalsneath", "sqeuclidean", "yule");
+
+ @Tunable(description = "Algorithm",
+ longDescription = "The algorithm to be used by the NearestNeighbors module to compute pointwise distances and find nearest neighbors.",
+ tooltip = "The algorithm to be used by the NearestNeighbors module to compute pointwise distances and find nearest neighbors.",
+ exampleStringValue = "auto",
+ groups = {"DBScan Advanced Settings"}, gravity = 4.0)
+ public ListSingleSelection algorithm = new ListSingleSelection("auto", "ball_tree", "kd_tree", "brute");
+
+
+ @Tunable(description = "Leaf size",
+ longDescription = "Leaf size passed to BallTree or cKDTree. This can affect the speed of the construction and query, as well as the memory required to store the tree. The optimal value depends on the nature of the problem.",
+ tooltip = "Leaf size passed to BallTree or cKDTree. This can affect the speed of the construction and query, as well as the memory required to store the tree. The optimal value depends on the nature of the problem.",
+ exampleStringValue = "30",
+ groups = {"DBScan Advanced Settings"}, gravity = 5.0)
+ public int leaf_size = 30;
+
+
+ @Tunable(description = "P",
+ longDescription = "The power of the Minkowski metric to be used to calculate distance between points.",
+
+ tooltip = "The power of the Minkowski metric to be used to calculate distance between points.",
+ exampleStringValue = "2.0",
+ groups = {"DBScan Advanced Settings"}, gravity = 5.0)
+ public double p = 2;
+
+ // We let the back-end handle this
+ // public int n_jobs;
+
+ @Tunable(description = "Synchronous",
+ longDescription = "If ```false``` the algorithm will run in the background after specified wait time",
+ exampleStringValue = "true",
+ tooltip = "If ```false``` the algorithm will run in the background after specified wait time",
+ groups = {"DBScan Advanced Settings"}, gravity = 6.0)
+ public boolean isSynchronous = false;
+
+ @ContainsTunables
+ public AdvancedProperties advancedAttributes;
+
+ @ContainsTunables
+ public NetworkVizProperties vizProperties = new NetworkVizProperties();
+
+ public DBScanContext() {
+ advancedAttributes = new AdvancedProperties("__dbscanCluster", false); //this is the name of the column Integer that is created when click LOAD
+ metric.setSelectedValue("euclidean");
+ }
+
+ public DBScanContext(DBScanContext origin) {
+ if (origin.advancedAttributes != null)
+ advancedAttributes = new AdvancedProperties(origin.advancedAttributes);
+ else
+ advancedAttributes = new AdvancedProperties("__dbscanCluster", false);
+
+ eps = origin.eps;
+ min_samples = origin.min_samples;
+ metric = origin.metric;
+ algorithm = origin.algorithm;
+ leaf_size = origin.leaf_size;
+ p = origin.p;
+
+ }
+
+ public void setNetwork(CyNetwork network) {
+ if (this.network != null && this.network.equals(network))
+ return;
+
+ this.network = network;
+ }
+
+ public CyNetwork getNetwork() { return network; }
+
+ public String getClusterAttribute() { return advancedAttributes.clusterAttribute;}
+
+ public void setUIHelper(TunableUIHelper helper) {
+ this.helper = helper;
+
+ }
+
+}
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FCM/FCMCluster.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FCM/FCMCluster.java
index 37c1a24..b9ca596 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FCM/FCMCluster.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FCM/FCMCluster.java
@@ -124,7 +124,7 @@ public void run( TaskMonitor taskmonitor) {
int[] mostRelevantCluster = new int[network.getNodeList().size()];
- FuzzyNodeCluster.fuzzyClusterCount = 0;
+ FuzzyNodeCluster.reset();
runFCM = new RunFCM(distanceMatrix, context.iterations, context.cNumber,
context.fIndex, context.beta, context.membershipThreshold.getValue(),
context.maxThreads, this.monitor);
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedy.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedy.java
index 851f524..61c0fe8 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedy.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedy.java
@@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.cytoscape.application.CyApplicationManager;
import org.cytoscape.jobs.CyJobData;
@@ -15,20 +16,23 @@
import org.cytoscape.model.CyNetwork;
import org.cytoscape.service.util.CyServiceRegistrar;
import org.cytoscape.work.ContainsTunables;
+import org.cytoscape.work.ProvidesTitle;
import org.cytoscape.work.TaskMonitor;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.NodeCluster;
import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.AbstractNetworkClusterer;
import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.FastGreedy.FastGreedyContext;
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.ui.NewNetworkView;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJob;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobHandler;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.NetworkClusterJobHandler;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.RemoteServer;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobExecutionService;
public class FastGreedy extends AbstractNetworkClusterer {
- public static String NAME = "Fast Greedy";
+ public static String NAME = "Fast Greedy (remote)";
public static String SHORTNAME = "fastgreedy";
final CyServiceRegistrar registrar;
public final static String GROUP_ATTRIBUTE = "__FastGreedyGroups.SUID";
@@ -49,10 +53,12 @@ public FastGreedy(FastGreedyContext context, ClusterManager manager, CyServiceRe
public String getShortName() {return SHORTNAME;}
@Override
+ @ProvidesTitle
public String getName() {return NAME;}
@Override
public void run(TaskMonitor taskMonitor) throws Exception {
+ monitor = taskMonitor;
// Get the execution service
CyJobExecutionService executionService =
registrar.getService(CyJobExecutionService.class, "(title=ClusterJobExecutor)");
@@ -62,6 +68,13 @@ public void run(TaskMonitor taskMonitor) throws Exception {
clusterAttributeName = context.getClusterAttribute();
createGroups = context.advancedAttributes.createGroups;
String attribute = context.getattribute().getSelectedValue();
+
+ HashMap configuration = new HashMap<>();
+ if (context.isSynchronous == true) {
+ configuration.put("waitTime", -1);
+ } else {
+ configuration.put("waitTime", 20);
+ }
HashMap nodeMap = getNetworkNodes(currentNetwork);
List nodeArray = new ArrayList<>();
@@ -82,28 +95,24 @@ public void run(TaskMonitor taskMonitor) throws Exception {
jobData = dataService.addData(jobData, "edges", edgeArray);
job.storeClusterData(clusterAttributeName, currentNetwork, clusterManager, createGroups, GROUP_ATTRIBUTE, null, getShortName());
// Create our handler
- ClusterJobHandler jobHandler = new ClusterJobHandler(job, network);
+ NetworkClusterJobHandler jobHandler = new NetworkClusterJobHandler(job, network, context.vizProperties.showUI, context.vizProperties.restoreEdges);
job.setJobMonitor(jobHandler);
// Submit the job
- CyJobStatus exStatus = executionService.executeJob(job, basePath, null, jobData);
+ CyJobStatus exStatus = executionService.executeJob(job, basePath, configuration, jobData);
CyJobStatus.Status status = exStatus.getStatus();
- System.out.println("Status: " + status);
+
if (status == Status.FINISHED) {
- executionService.fetchResults(job, dataService.getDataInstance());
- if (context.vizProperties.showUI) {
- taskMonitor.showMessage(TaskMonitor.Level.INFO, "Creating network");
- insertTasksAfterCurrentTask(new NewNetworkView(network, clusterManager, true, context.vizProperties.restoreEdges, false));
- }
-
+ jobHandler.loadData(job, taskMonitor);
} else if (status == Status.RUNNING
|| status == Status.SUBMITTED
|| status == Status.QUEUED) {
CyJobManager manager = registrar.getService(CyJobManager.class);
manager.addJob(job, jobHandler, 5); //this one shows the load button
- } else if (status == Status.ERROR
- || status == Status.UNKNOWN
+ } else if (status == Status.ERROR) {
+ monitor.showMessage(TaskMonitor.Level.ERROR, "Job error: " + exStatus.getMessage());
+ } else if (status == Status.UNKNOWN
|| status == Status.CANCELED
|| status == Status.FAILED
|| status == Status.TERMINATED
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedyContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedyContext.java
index a1f674e..2ee0a25 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedyContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedyContext.java
@@ -29,6 +29,13 @@ public ListSingleSelection getattribute(){
}
public void setattribute(ListSingleSelection attr) { }
+ @Tunable(description = "Synchronous",
+ longDescription = "If ```false``` the algorithm will run in the background after specified wait time",
+ exampleStringValue = "true",
+ tooltip = "If ```false``` the algorithm will run in the background after specified wait time",
+ groups = {"FastGreedy Advanced Settings"}, gravity = 6.0)
+ public boolean isSynchronous = false;
+
@ContainsTunables
public AdvancedProperties advancedAttributes;
@@ -46,6 +53,7 @@ public FastGreedyContext(FastGreedyContext origin) {
advancedAttributes = new AdvancedProperties("__fastGreedyCluster", false);
attribute = origin.attribute;
+ isSynchronous = origin.isSynchronous;
}
public void setNetwork(CyNetwork network) {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedyTaskFactory.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedyTaskFactory.java
index 9c8e052..12c7aea 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedyTaskFactory.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/FastGreedy/FastGreedyTaskFactory.java
@@ -26,11 +26,6 @@ public FastGreedyTaskFactory(ClusterManager clusterManager, CyServiceRegistrar r
public String getShortName() {return FastGreedy.SHORTNAME;}
- @Override
- public String getLongDescription() {
- return "";
- }
-
@Override
public ClusterViz getVisualizer() {
return null;
@@ -45,4 +40,11 @@ public List getTypeList() {
public TaskIterator createTaskIterator() {
return new TaskIterator(new FastGreedy(context, clusterManager, registrar));
}
+
+ @Override
+ public String getLongDescription() {
+ return "This function implements the fast greedy modularity optimization algorithm for "+
+ "finding community structure, see A Clauset, MEJ Newman, C Moore: Finding community "+
+ "structure in very large networks, http://www.arxiv.org/abs/cond-mat/0408187 for the details.";
+ }
}
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/Fuzzifier.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/Fuzzifier.java
index da844c6..ccd69cf 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/Fuzzifier.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/Fuzzifier.java
@@ -74,7 +74,7 @@ public class Fuzzifier extends AbstractFuzzyNetworkClusterer{
private boolean ignoreMissing = true;
CyTableFactory tableFactory = null;
CyTableManager tableManager = null;
- private List Clusters = null;
+ private List clusters = null;
private int cNumber;
private String[] attributeArray = new String[1];
@@ -95,6 +95,8 @@ public Fuzzifier(FuzzifierContext context, ClusterManager manager) {
tableManager = clusterManager.getTableManager();
}
context.setNetwork(network);
+ context.edgeAttributeHandler.adjustLoops = false;
+
super.network = network;
}
@@ -117,12 +119,16 @@ public void run( TaskMonitor monitor) {
network = clusterManager.getNetwork();
super.network = network;
- this.Clusters = getClusters();
- this.cNumber = Clusters.size();
-
// Make sure to update the context
context.setNetwork(network);
+ // Update our tunable results
+ clusterAttributeName = context.getClusterAttribute();
+
+ NodeCluster.reset();
+ this.clusters = getClusters();
+ this.cNumber = clusters.size();
+
Long networkID = network.getSUID();
CyTable nodeAttributes = network.getDefaultNodeTable();
@@ -133,11 +139,8 @@ public void run( TaskMonitor monitor) {
return;
}
- // Update our tunable results
- clusterAttributeName = context.getClusterAttribute();
-
- runFuzzifier = new RunFuzzifier(Clusters, distanceMatrix, cNumber,
- context.membershipThreshold.getValue(), context.maxThreads, monitor);
+ runFuzzifier = new RunFuzzifier(clusters, distanceMatrix, cNumber,
+ context.membershipThreshold.getValue(), 0, monitor);
runFuzzifier.setDebug(debug);
@@ -145,8 +148,9 @@ public void run( TaskMonitor monitor) {
monitor.showMessage(TaskMonitor.Level.INFO,"Clustering...");
- List FuzzyClusters = runFuzzifier.run(network, monitor);
- if (FuzzyClusters == null) return; // Canceled?
+ FuzzyNodeCluster.reset();
+ List fuzzyClusters = runFuzzifier.run(network, context, monitor);
+ if (fuzzyClusters == null) return; // Canceled?
monitor.showMessage(TaskMonitor.Level.INFO,"Removing groups");
@@ -158,9 +162,9 @@ public void run( TaskMonitor monitor) {
params = new ArrayList();
context.edgeAttributeHandler.setParams(params);
- List> nodeClusters = createFuzzyGroups(network, FuzzyClusters, GROUP_ATTRIBUTE);
+ List> nodeClusters = createFuzzyGroups(network, fuzzyClusters, GROUP_ATTRIBUTE);
- results = new AbstractClusterResults(network, FuzzyClusters);
+ results = new AbstractClusterResults(network, fuzzyClusters);
monitor.showMessage(TaskMonitor.Level.INFO, "Done. Fuzzifier results:\n"+results);
if (context.vizProperties.showUI) {
@@ -170,12 +174,12 @@ public void run( TaskMonitor monitor) {
context.vizProperties.restoreEdges,
!context.edgeAttributeHandler.selectedOnly));
} else {
- monitor.showMessage(TaskMonitor.Level.INFO, "Done. Fizzifier results:\n"+results);
+ monitor.showMessage(TaskMonitor.Level.INFO, "Done. Fuzzifier results:\n"+results);
}
- System.out.println("Creating fuzzy table");
- createFuzzyTable(FuzzyClusters);
- System.out.println("Done");
+ // System.out.println("Creating fuzzy table");
+ createFuzzyTable(fuzzyClusters);
+ // System.out.println("Done");
}
@@ -196,17 +200,36 @@ public List getClusters(){
if (network == null) return nodeClusters;
List nodeList = network.getNodeList();
- clusterAttributeName = network.getRow(network).get("__clusterAttribute", String.class);
-
- // Save the seed cluster we used
- ModelUtils.createAndSetLocal(network, network, "__fuzzifierSeed",
- clusterAttributeName, String.class, null);
+ String clusterName = network.getRow(network).get("__clusterAttribute", String.class);
+
+ // Special case. If the clusterAttribute is __fuzzifierCluster, then we're repeating this,
+ // so use the __fuzzifierSeed instead
+ if (clusterName.equals(clusterAttributeName)) {
+ // We're reclustering
+ clusterName = network.getRow(network).get("__fuzzifierSeed", String.class);
+
+ // We need to do some resetting
+ if (ModelUtils.hasColumn(network, network.getDefaultNetworkTable(), "__fuzzifierCluster_Table.SUID")) {
+ Long fuzzyTableSUID = network.getRow(network).get("__fuzzifierCluster_Table.SUID", Long.class);
+ if (fuzzyTableSUID != null) {
+ tableManager.deleteTable(fuzzyTableSUID);
+ ModelUtils.deleteColumnLocal(network, CyNetwork.class, "__fuzzifierCluster_Table.SUID");
+ }
+ }
+ } else {
+ // Save the seed cluster we used
+ ModelUtils.createAndSetLocal(network, network, "__fuzzifierSeed",
+ clusterName, String.class, null);
+ }
+
+ if (!ModelUtils.hasColumn(network, network.getDefaultNodeTable(), clusterName))
+ throw new RuntimeException("Can't find cluster attribute: "+clusterName);
for(CyNode node : nodeList){
// System.out.println("Node SUID:"+node.getSUID());
- if (ModelUtils.hasAttribute(network, node, clusterAttributeName)){
+ if (ModelUtils.hasAttribute(network, node, clusterName)){
- Integer cluster = network.getRow(node).get(clusterAttributeName, Integer.class);
+ Integer cluster = network.getRow(node).get(clusterName, Integer.class);
// System.out.println("Cluster for "+node.getSUID()+"--"+cluster);
if (!clusterMap.containsKey(cluster))
clusterMap.put(cluster, new ArrayList());
@@ -216,7 +239,10 @@ public List getClusters(){
}
for (int key : clusterMap.keySet()){
- nodeClusters.add(new NodeCluster(clusterMap.get(key)));
+ if (clusterMap.get(key).size() > context.minClusterSize) {
+ NodeCluster nodeCluster = new NodeCluster(key, clusterMap.get(key));
+ nodeClusters.add(nodeCluster);
+ }
}
// System.out.println("NodeCluster Size : " +nodeClusters.size());
return nodeClusters;
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/FuzzifierContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/FuzzifierContext.java
index ef09024..d9db77d 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/FuzzifierContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/FuzzifierContext.java
@@ -27,10 +27,13 @@ public class FuzzifierContext implements ClusterAlgorithmContext {
public EdgeAttributeHandler edgeAttributeHandler;
@Tunable(description = "Threshold for Fuzzy Membership in a Cluster", groups={"Fuzzifier Advanced Settings"}, params="displayState=collapsed, slider=true",gravity=20.0)
- public BoundedDouble membershipThreshold = new BoundedDouble(0.0, 0.2, 1.0, false, false);
+ public BoundedDouble membershipThreshold = new BoundedDouble(0.0, 0.4, 1.0, false, false);
- @Tunable(description = "Maximum number of threads", groups={"Fuzzifier Advanced Settings"}, gravity=21.0)
- public int maxThreads = 0;
+ // @Tunable(description = "Maximum number of threads", groups={"Fuzzifier Advanced Settings"}, gravity=21.0)
+ // public int maxThreads = 0;
+
+ @Tunable(description = "Minimum cluster size to consider", groups={"Fuzzifier Advanced Settings"}, gravity=22.0)
+ public int minClusterSize = 1;
/*
@Tunable(description = "Distance Metric", groups={"Fuzzifier Advanced Settings"}, gravity=22.0)
@@ -60,7 +63,7 @@ public FuzzifierContext(FuzzifierContext origin) {
membershipThreshold = origin.membershipThreshold;
- maxThreads = origin.maxThreads;
+ // maxThreads = origin.maxThreads;
/*
distanceMetric = new ListSingleSelection(DistanceMetric.VALUE_IS_CORRELATION, DistanceMetric.UNCENTERED_CORRELATION,
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/RunFuzzifier.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/RunFuzzifier.java
index 9a4a104..70fd07b 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/RunFuzzifier.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Fuzzifier/RunFuzzifier.java
@@ -51,7 +51,7 @@ public class RunFuzzifier {
HashMap> groupMap = null;
- private List Clusters = null;
+ private List clusters = null;
private int number_clusters;
private List nodeList= null;
private boolean canceled = false;
@@ -65,11 +65,12 @@ public class RunFuzzifier {
double membershipThreshold = 0;
private boolean debug = false;
private int nThreads = Runtime.getRuntime().availableProcessors()-1;
+ private Map baseMembership;
- public RunFuzzifier (List Clusters, CyMatrix distanceMatrix, int cClusters,
- double membershipThreshold,int maxThreads, TaskMonitor monitor ){
+ public RunFuzzifier (List clusters, CyMatrix distanceMatrix, int cClusters,
+ double membershipThreshold, int maxThreads, TaskMonitor monitor ){
- this.Clusters = Clusters;
+ this.clusters = clusters;
this.distanceMatrix = distanceMatrix;
this.number_clusters = cClusters;
this.monitor = monitor;
@@ -86,6 +87,15 @@ public RunFuzzifier (List Clusters, CyMatrix distanceMatrix, int cC
//monitor.showMessage(TaskMonitor.Level.INFO,"Matrix info: = "+distanceMatrix.printMatrixInfo(matrix));
monitor.showMessage(TaskMonitor.Level.INFO,"Number of Clusters = "+number_clusters);
+ // Create a map to record each node's membership
+ this.baseMembership = new HashMap<>();
+ for (NodeCluster c: clusters) {
+ Integer clusterNumber = c.getClusterNumber()-1;
+ for (CyNode n: c) {
+ baseMembership.put(n, clusterNumber);
+ }
+ }
+
}
public void cancel () { canceled = true; }
@@ -98,91 +108,234 @@ public RunFuzzifier (List Clusters, CyMatrix distanceMatrix, int cC
* @return List of FuzzyNodeCLusters
*/
- public List run(CyNetwork network, TaskMonitor monitor){
-
- Long networkID = network.getSUID();
+ public List run(CyNetwork network, FuzzifierContext context, TaskMonitor monitor){
+
+ /**
+ * Algorithm (transcoded from the R usedist package's dist_to_centroids method:
+ * Given the matrix distMatrix:
+ * d2 = distMatrix ** 2
+ * group_items = list of nodes in each cluster
+ * group_sizes = sizes of each cluster
+ * group_d2s = list of subportions of the d2 for each cluster
+ * within_group_sums = list of sums for each group_d2s
+ * foreach node:
+ * foreach group:
+ * idx1 = group_items[group]
+ * n1 = group_sizes[group]
+ * sum1 = winthin_group_sums[group]
+ * sum12 = sum(d2[idx1, node]) # Note: idx1 is a vector
+ * term1 = sum1 / n1**2
+ * term12 = sum12 / n1
+ * result_squared = term12 - term1
+ * dist[node, group] = sqrt(result_sqared)
+ */
long startTime = System.currentTimeMillis();
int nelements = distanceMatrix.nRows();
nodeList = distanceMatrix.getRowNodes();
+ int max_cluster = Math.max(NodeCluster.getMaxClusterNumber(), number_clusters);
//Matrix to store the temporary cluster membership values of elements
- double [][] ClusterMemberships = new double[nelements][number_clusters];
+ double [][] clusterMemberships = new double[nelements][max_cluster];
- //Initializing all membership values to 0
+ //Initializing all membership values to NaN
for (int i = 0; i < nelements; i++){
- for (int j = 0; j < number_clusters; j++){
- ClusterMemberships[i][j] = 0;
+ for (int j = 0; j < max_cluster; j++){
+ clusterMemberships[i][j] = Double.NaN;
}
}
- // This matrix will store the centroid data
- CyMatrix cData = CyMatrixFactory.makeSmallMatrix(network, number_clusters, nelements);
-
- getFuzzyCenters(cData);
-
- for (CyNode node : nodeList){
- int nodeIndex = nodeList.indexOf(node);
- double sumDistances = 0;
- for (int i = 0 ; i < Clusters.size(); i++){
- sumDistances += cData.doubleValue(i, nodeIndex);
- }
- for(int i = 0 ; i < Clusters.size(); i++){
- ClusterMemberships[nodeIndex][i] = cData.doubleValue(i, nodeIndex)/sumDistances;
- }
- }
-
- HashMap membershipMap = createMembershipMap(ClusterMemberships);
+ monitor.showMessage(TaskMonitor.Level.INFO, "Calculating distances");
+
+ CyMatrix d2 = distanceMatrix.copy();
+ // System.out.println(d2.printMatrix());
+ d2.ops().powScalar(2);
+ // System.out.println(d2.printMatrix());
+ List group_items = clusters;
+
+ int[] group_sizes = get_sizes(group_items);
+ // for (int i = 0; i < group_sizes.length; i++) { System.out.println("Group "+i+" has "+group_sizes[i]+" elements"); }
+ double[] within_group_sums = get_sums(d2, group_items);
+ // for (int i = 0; i < within_group_sums.length; i++) { System.out.println("Group "+i+" has sum "+within_group_sums[i]); }
+ boolean watch = false;
+ for (CyNode node: nodeList) {
+ /* Debugging
+ if (node.getSUID() == 5705)
+ watch = true;
+ else
+ watch = false;
+ */
+ // This part can be done in parallel
+ // get_distance(d2, node_index, group, group_size, clusterMemberships)
+ // clusterMemberships needs to be in a critical section.
+ for (NodeCluster idx1: group_items) {
+ int group = idx1.getClusterNumber()-1;
+ if (watch) System.out.println("group = "+group);
+ int n1 = group_sizes[group];
+ double sum1 = within_group_sums[group];
+ if (sum1 == 0.0d)
+ continue;
+ double sum12 = get_sum(d2, idx1, node, watch);
+ if (watch) System.out.println("sum12 = "+sum12);
+ double term1 = sum1 / Math.pow(n1, 2);
+ if (watch) System.out.println("term1 = "+term1);
+ double term12 = sum12 / n1;
+ if (watch) System.out.println("term12 = "+term12);
+ double result_squared = term12 - term1;
+ // clusterMemberships[nodeList.indexOf(node)][group] = result_squared;
+ if (watch) System.out.println("result_squared = "+result_squared);
+ if (result_squared > 0.0d) {
+ clusterMemberships[nodeList.indexOf(node)][group] = Math.sqrt(result_squared);
+ if (watch) System.out.println("result = "+Math.sqrt(result_squared));
+ // System.out.println("Node "+node+" is "+clusterMemberships[nodeList.indexOf(node)][group]+" away from group "+group);
+ } else {
+ clusterMemberships[nodeList.indexOf(node)][group] = Double.NaN;
+ }
+ }
+ }
+
+ long algTime = System.currentTimeMillis()-startTime;
+ System.out.println("Algorithm took "+((double)algTime)/1000.0+" seconds");
+
+ monitor.showMessage(TaskMonitor.Level.INFO, "Assigning fuzzy membership");
+
+ // OK, at this point, we have a matrix with the squared distance from each node to the
+ // the centroid of each cluster. Now, we need to calculate the proportional
+ // membership, which we do by normalizing all of the distances so that they sum to 1.0
+ for (int node_index = 0; node_index< nelements; node_index++) {
+ double sum = 0.0d;
+ // System.out.println("Node: "+nodeList.get(node_index));
+ for (int cluster_index = 0; cluster_index < max_cluster; cluster_index++) {
+ double v = clusterMemberships[node_index][cluster_index];
+ if (Double.isNaN(v))
+ continue;
+ sum += v;
+ }
+ // System.out.println("Node "+nodeList.get(node_index)+" distances sum to "+sum);
+ for (int cluster_index = 0; cluster_index < max_cluster; cluster_index++) {
+ double v = clusterMemberships[node_index][cluster_index];
+ if (Double.isNaN(v))
+ continue;
+ CyNode node = nodeList.get(node_index);
+ if (sum == 0.0)
+ v = 1.0;
+ else
+ v = v/sum;
+ // if (v < 1.0)
+ // v = 1.0 - v;
+ clusterMemberships[node_index][cluster_index] = v;
+ // System.out.println("Node "+nodeList.get(node_index)+" is "+clusterMemberships[node_index][cluster_index]+" away from group "+cluster_index);
+ }
+ }
+
+ /*
+ long assignTime = System.currentTimeMillis()-algTime;
+ System.out.println("Assigning clusters took "+((double)assignTime)/1000.0+" seconds");
+ */
+
+ monitor.showMessage(TaskMonitor.Level.INFO, "Making cluster map");
+
+ HashMap membershipMap = createMembershipMap(clusterMemberships);
List fuzzyClusters = new ArrayList();
// Adding the nodes which have memberships greater than the threshold to fuzzy node clusters
List fuzzyNodeList;
- for(int i = 0 ; i < number_clusters; i++){
+ for(int i = 0 ; i < max_cluster; i++){
fuzzyNodeList = new ArrayList();
HashMap clusterMembershipMap = new HashMap();
- for( CyNode node: nodeList){
- if (membershipMap.get(node)[i] > membershipThreshold ){
+ for( int node_index = 0; node_index < nodeList.size(); node_index++) {
+ CyNode node = nodeList.get(node_index);
+ double v = clusterMemberships[node_index][i];
+ if (!Double.isNaN(v) && v > membershipThreshold) {
+ fuzzyNodeList.add(node);
+ clusterMembershipMap.put(node, v);
+ } else if (!Double.isNaN(v) && baseMembership.containsKey(node) && baseMembership.get(node) == i) {
+ // Force this to be part of this fuzzy cluster if it's part of the base cluster
fuzzyNodeList.add(node);
- clusterMembershipMap.put(node, membershipMap.get(node)[i]);
- }
+ clusterMembershipMap.put(node, v);
+ }
}
- fuzzyClusters.add(new FuzzyNodeCluster(fuzzyNodeList,clusterMembershipMap));
- }
-
- return fuzzyClusters;
+ if (fuzzyNodeList.size() < context.minClusterSize)
+ continue;
- }
-
- /**
- * The method calculates the centers of fuzzy clusters
- *
- * @param cData matrix to store the data for cluster centers
- */
+ FuzzyNodeCluster fCluster = new FuzzyNodeCluster(fuzzyNodeList,clusterMembershipMap);
+ fCluster.setClusterNumber(i+1); // This will number this the same as the corresponding source cluster
+ fuzzyClusters.add(fCluster);
+ }
- public void getFuzzyCenters(CyMatrix cData){
+ long totalTime = System.currentTimeMillis()-startTime;
+ System.out.println("Total time: "+((double)totalTime)/1000.0+" seconds");
- // To store the sum of memberships(raised to fuzziness index) corresponding to each cluster
- int nelements = distanceMatrix.nRows();
+ return fuzzyClusters;
- for (NodeCluster cluster : Clusters){
- int c = Clusters.indexOf(cluster);
- double numerator = 0;
- Double distance = 0.0;
- int i = 0;
- for (int e = 0; e < nelements; e++) {
- numerator = 0;
- for(CyNode node : cluster){
- i = nodeList.indexOf(node);
- distance = distanceMatrix.doubleValue(i,e);
- numerator += distance;
- }
- cData.setValue(c,e,(numerator/cluster.size()));
- }
- }
}
+ private double get_sum(CyMatrix d2, NodeCluster cluster, CyNode node, boolean watch) {
+ int n_index = nodeList.indexOf(node);
+ if (watch) System.out.println("n_index = "+n_index);
+ double sum = 0.0d;
+ for (CyNode c_node: cluster) {
+ int c_index = nodeList.indexOf(c_node);
+ if (watch) System.out.println("c_index = "+c_index+" node = "+c_node);
+ if (watch) System.out.println("distance = "+d2.doubleValue(n_index, c_index)+" weight = "+(1/d2.doubleValue(n_index, c_index)));
+ sum += d2.doubleValue(n_index,c_index);
+ }
+
+ return sum;
+ }
+
+ private int[] get_sizes(List group_items) {
+ int[] sizes = new int[NodeCluster.getMaxClusterNumber()];
+ for (NodeCluster c: group_items) {
+ sizes[c.getClusterNumber()-1] = c.size();
+ }
+ return sizes;
+ }
+
+ // For each cluster, sum up the distances
+ private double[] get_sums(CyMatrix d2, List group_items) {
+ double[] sums = new double[NodeCluster.getMaxClusterNumber()];
+ List nodes = d2.getRowNodes();
+
+ for (NodeCluster c: group_items) {
+ int cluster_number = c.getClusterNumber()-1;
+ sums[cluster_number] = 0.0d;
+
+ int[] node_indices = node_index(c, nodes);
+ if (node_indices == null)
+ continue;
+
+ for (int i = 0; i < node_indices.length; i++) {
+ for (int j = i+1; j < node_indices.length; j++) {
+ sums[cluster_number] += d2.doubleValue(node_indices[i], node_indices[j]);
+ }
+ }
+ }
+ return sums;
+ }
+
+ private int[] node_index(NodeCluster c, Listnodes) {
+ int[] indices = new int[c.size()];
+ int index = 0;
+ /*
+ System.out.print("cluster number: "+c.getClusterNumber()+", nodes = [");
+ for (CyNode n: nodes) {System.out.print(n+",");}
+ System.out.println("]");
+ */
+ for (CyNode n: c) {
+ int nodeid = nodes.indexOf(n);
+ if (nodeid >= 0) {
+ // System.out.println("n = "+n+", index(n) = "+nodes.indexOf(n));
+ indices[index++] = nodes.indexOf(n);
+ }
+ }
+ if (index == 0) return null;
+
+ return Arrays.copyOf(indices, index);
+ }
+
/**
* Creates a Map from nodes to their respective membership arrays
*
@@ -192,8 +345,7 @@ public void getFuzzyCenters(CyMatrix cData){
public HashMap createMembershipMap(double[][] membershipArray){
HashMap membershipHM = new HashMap();
- List nodeList = distanceMatrix.getRowNodes();
- for ( int i = 0; i configuration = new HashMap<>();
+ if (context.isSynchronous == true) {
+ configuration.put("waitTime", -1);
+ } else {
+ configuration.put("waitTime", 20);
+ }
+
+ configuration.put("trials", context.trials);
HashMap nodeMap = getNetworkNodes(currentNetwork);
List nodeArray = new ArrayList<>();
@@ -95,29 +109,24 @@ public void run(TaskMonitor taskMonitor) throws Exception {
jobData = dataService.addData(jobData, "edges", edgeArray);
job.storeClusterData(clusterAttributeName, currentNetwork, clusterManager, createGroups, GROUP_ATTRIBUTE, null, getShortName());
// Create our handler
- ClusterJobHandler jobHandler = new ClusterJobHandler(job, network);
+ NetworkClusterJobHandler jobHandler = new NetworkClusterJobHandler(job, network, context.vizProperties.showUI, context.vizProperties.restoreEdges);
job.setJobMonitor(jobHandler);
// Submit the job
- CyJobStatus exStatus = executionService.executeJob(job, basePath, null, jobData);
+ CyJobStatus exStatus = executionService.executeJob(job, basePath, configuration, jobData);
CyJobStatus.Status status = exStatus.getStatus();
System.out.println("Status: " + status);
if (status == Status.FINISHED) {
- executionService.fetchResults(job, dataService.getDataInstance());
-
- if (context.vizProperties.showUI) {
- taskMonitor.showMessage(TaskMonitor.Level.INFO, "Creating network");
- insertTasksAfterCurrentTask(new NewNetworkView(network, clusterManager, true, context.vizProperties.restoreEdges, false));
- }
-
+ jobHandler.loadData(job, taskMonitor);
} else if (status == Status.RUNNING
|| status == Status.SUBMITTED
|| status == Status.QUEUED) {
CyJobManager manager = registrar.getService(CyJobManager.class);
manager.addJob(job, jobHandler, 5); //this one shows the load button
- } else if (status == Status.ERROR
- || status == Status.UNKNOWN
+ } else if (status == Status.ERROR) {
+ monitor.showMessage(TaskMonitor.Level.ERROR, "Job error: " + exStatus.getMessage());
+ } else if (status == Status.UNKNOWN
|| status == Status.CANCELED
|| status == Status.FAILED
|| status == Status.TERMINATED
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Infomap/InfomapContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Infomap/InfomapContext.java
index 54625e0..2a987c7 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Infomap/InfomapContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Infomap/InfomapContext.java
@@ -28,6 +28,7 @@ public class InfomapContext implements ClusterAlgorithmContext {
@Tunable(description = "Trials",
longDescription = "The number of attempts to partition the network.",
exampleStringValue = "10",
+ tooltip = "The number of attempts to partition the network.",
groups = {"Infomap Advanced Settings"}, gravity = 1.0)
public int trials = 10;
@@ -43,6 +44,13 @@ public ListSingleSelection getattribute(){
}
public void setattribute(ListSingleSelection attr) { }
+ @Tunable(description = "Synchronous",
+ longDescription = "If ```false``` the algorithm will run in the background after specified wait time",
+ exampleStringValue = "true",
+ tooltip = "If ```false``` the algorithm will run in the background after specified wait time",
+ groups = {"Leiden Advanced Settings"}, gravity = 6.0)
+ public boolean isSynchronous = false;
+
@ContainsTunables
public AdvancedProperties advancedAttributes;
@@ -61,6 +69,7 @@ public InfomapContext(InfomapContext origin) {
trials = origin.trials;
attribute = origin.attribute;
+ isSynchronous = origin.isSynchronous;
}
public void setNetwork(CyNetwork network) {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Infomap/InfomapTaskFactory.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Infomap/InfomapTaskFactory.java
index 58a4cf5..24eac93 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Infomap/InfomapTaskFactory.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Infomap/InfomapTaskFactory.java
@@ -30,8 +30,8 @@ public InfomapTaskFactory(ClusterManager clusterManager, CyServiceRegistrar regi
@Override
public String getLongDescription() {
- return "";
- }
+ return "Find community structure that minimizes the expected description length of a random walker trajectory. Implementation of the InfoMap community detection algorithm.of Martin Rosvall and Carl T. Bergstrom.";
+ }
@Override
public ClusterViz getVisualizer() {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagation.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagation.java
index c027ad7..0874cc8 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagation.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagation.java
@@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.cytoscape.application.CyApplicationManager;
import org.cytoscape.jobs.CyJobData;
@@ -15,19 +16,23 @@
import org.cytoscape.model.CyNetwork;
import org.cytoscape.service.util.CyServiceRegistrar;
import org.cytoscape.work.ContainsTunables;
+import org.cytoscape.work.ProvidesTitle;
import org.cytoscape.work.TaskMonitor;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.NodeCluster;
import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.AbstractNetworkClusterer;
import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.LabelPropagation.LabelPropagationContext;
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.ui.NewNetworkView;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJob;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobExecutionService;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobHandler;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.NetworkClusterJobHandler;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.RemoteServer;
public class LabelPropagation extends AbstractNetworkClusterer {
- public static String NAME = "Label Propagation";
+ public static String NAME = "Label Propagation (remote)";
public static String SHORTNAME = "labelpropagation";
final CyServiceRegistrar registrar;
public final static String GROUP_ATTRIBUTE = "__LabelPropagationGroups.SUID";
@@ -48,10 +53,12 @@ public LabelPropagation(LabelPropagationContext context, ClusterManager manager,
public String getShortName() {return SHORTNAME;}
@Override
+ @ProvidesTitle
public String getName() {return NAME;}
@Override
public void run(TaskMonitor taskMonitor) throws Exception {
+ monitor = taskMonitor;
// Get the execution service
CyJobExecutionService executionService =
registrar.getService(CyJobExecutionService.class, "(title=ClusterJobExecutor)");
@@ -61,6 +68,13 @@ public void run(TaskMonitor taskMonitor) throws Exception {
clusterAttributeName = context.getClusterAttribute();
createGroups = context.advancedAttributes.createGroups;
String attribute = context.getattribute().getSelectedValue();
+
+ HashMap configuration = new HashMap<>();
+ if (context.isSynchronous == true) {
+ configuration.put("waitTime", -1);
+ } else {
+ configuration.put("waitTime", 20);
+ }
HashMap nodeMap = getNetworkNodes(currentNetwork);
List nodeArray = new ArrayList<>();
@@ -81,15 +95,30 @@ public void run(TaskMonitor taskMonitor) throws Exception {
jobData = dataService.addData(jobData, "edges", edgeArray);
job.storeClusterData(clusterAttributeName, currentNetwork, clusterManager, createGroups, GROUP_ATTRIBUTE, null, getShortName());
// Create our handler
- ClusterJobHandler jobHandler = new ClusterJobHandler(job, network);
+ NetworkClusterJobHandler jobHandler = new NetworkClusterJobHandler(job, network, context.vizProperties.showUI, context.vizProperties.restoreEdges);
job.setJobMonitor(jobHandler);
// Submit the job
- CyJobStatus exStatus = executionService.executeJob(job, basePath, null, jobData);
+ CyJobStatus exStatus = executionService.executeJob(job, basePath, configuration, jobData);
CyJobStatus.Status status = exStatus.getStatus();
System.out.println("Status: " + status);
if (status == Status.FINISHED) {
- executionService.fetchResults(job, dataService.getDataInstance());
+ CyJobData data = dataService.getDataInstance();
+ executionService.fetchResults(job, data);
+
+ Map clusterData = job.getClusterData().getAllValues();
+
+ String clusterAttributeName = (String) clusterData.get("clusterAttributeName");
+ Boolean createGroups = (Boolean) clusterData.get("createGroups");
+ String group_attr = (String) clusterData.get("group_attr");
+ List params = (List) clusterData.get("params");
+
+ List nodeClusters = ClusterJobExecutionService.createClusters(data, clusterAttributeName, network); //move this to remote utils
+ System.out.println("NodeClusters: " + nodeClusters);
+
+ AbstractNetworkClusterer.createGroups(network, nodeClusters, group_attr, clusterAttributeName,
+ clusterManager, createGroups, params, SHORTNAME);
+
if (context.vizProperties.showUI) {
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Creating network");
insertTasksAfterCurrentTask(new NewNetworkView(network, clusterManager, true, context.vizProperties.restoreEdges, false));
@@ -101,8 +130,9 @@ public void run(TaskMonitor taskMonitor) throws Exception {
CyJobManager manager = registrar.getService(CyJobManager.class);
manager.addJob(job, jobHandler, 5); //this one shows the load button
- } else if (status == Status.ERROR
- || status == Status.UNKNOWN
+ } else if (status == Status.ERROR) {
+ monitor.showMessage(TaskMonitor.Level.ERROR, "Job error: " + exStatus.getMessage());
+ } else if (status == Status.UNKNOWN
|| status == Status.CANCELED
|| status == Status.FAILED
|| status == Status.TERMINATED
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagationContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagationContext.java
index d17385c..7d58550 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagationContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagationContext.java
@@ -29,6 +29,13 @@ public ListSingleSelection getattribute(){
}
public void setattribute(ListSingleSelection attr) { }
+ @Tunable(description = "Synchronous",
+ longDescription = "If ```false``` the algorithm will run in the background after specified wait time",
+ exampleStringValue = "true",
+ tooltip = "If ```false``` the algorithm will run in the background after specified wait time",
+ groups = {"Label Propagation Advanced Settings"}, gravity = 6.0)
+ public boolean isSynchronous = false;
+
@ContainsTunables
public AdvancedProperties advancedAttributes;
@@ -46,6 +53,7 @@ public LabelPropagationContext(LabelPropagationContext origin) {
advancedAttributes = new AdvancedProperties("__labelPropagationCluster", false);
attribute = origin.attribute;
+ isSynchronous = origin.isSynchronous;
}
public void setNetwork(CyNetwork network) {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagationTaskFactory.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagationTaskFactory.java
index ab8b29e..8e1e0e8 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagationTaskFactory.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LabelPropagation/LabelPropagationTaskFactory.java
@@ -29,7 +29,15 @@ public LabelPropagationTaskFactory(ClusterManager clusterManager, CyServiceRegis
@Override
public String getLongDescription() {
- return "";
+ return "This function implements the community detection method described in: Raghavan, U.N. and Albert, R. and "+
+ "Kumara, S.: Near linear time algorithm to detect community structures in large-scale networks. Phys Rev E "+
+ "76, 036106. (2007). This version extends the original method by the ability to take edge weights into consideration "+
+ "and also by allowing some labels to be fixed."+
+ "
"+
+ "Weights are taken into account as follows: when the new label of node i is determined, the algorithm iterates over "+
+ "all edges incident on node i and calculate the total weight of edges leading to other nodes with label 0, 1, 2, ..., "+
+ "k - 1 (where k is the number of possible labels). The new label of node i will then be the label whose edges "+
+ "(among the ones incident on node i) have the highest total weight";
}
@Override
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVCluster.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVCluster.java
index e6c6035..b51aeb8 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVCluster.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVCluster.java
@@ -1,119 +1,130 @@
package edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.LeadingEigenVector;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
-
- import org.cytoscape.application.CyApplicationManager;
- import org.cytoscape.jobs.CyJobData;
- import org.cytoscape.jobs.CyJobDataService;
- import org.cytoscape.jobs.CyJobExecutionService;
- import org.cytoscape.jobs.CyJobManager;
- import org.cytoscape.jobs.CyJobStatus;
- import org.cytoscape.jobs.SUIDUtil;
- import org.cytoscape.jobs.CyJobStatus.Status;
- import org.cytoscape.model.CyNetwork;
- import org.cytoscape.service.util.CyServiceRegistrar;
- import org.cytoscape.work.ContainsTunables;
- import org.cytoscape.work.TaskMonitor;
-
- import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.AbstractNetworkClusterer;
- import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.LeadingEigenVector.LEVContext;
- import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
- import edu.ucsf.rbvi.clusterMaker2.internal.ui.NewNetworkView;
- import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJob;
- import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobHandler;
- import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.RemoteServer;
-
- public class LEVCluster extends AbstractNetworkClusterer {
-
- public static String NAME = "Leading Eigenvector";
- public static String SHORTNAME = "leadingeigenvector";
- final CyServiceRegistrar registrar;
- public final static String GROUP_ATTRIBUTE = "__LeadingEigenvector.SUID";
-
- @ContainsTunables
- public LEVContext context = null;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.cytoscape.application.CyApplicationManager;
+import org.cytoscape.jobs.CyJobData;
+import org.cytoscape.jobs.CyJobDataService;
+import org.cytoscape.jobs.CyJobExecutionService;
+import org.cytoscape.jobs.CyJobManager;
+import org.cytoscape.jobs.CyJobStatus;
+import org.cytoscape.jobs.SUIDUtil;
+import org.cytoscape.jobs.CyJobStatus.Status;
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.service.util.CyServiceRegistrar;
+import org.cytoscape.work.ContainsTunables;
+import org.cytoscape.work.ProvidesTitle;
+import org.cytoscape.work.TaskMonitor;
+
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.NodeCluster;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.AbstractNetworkClusterer;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.LeadingEigenVector.LEVContext;
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
+import edu.ucsf.rbvi.clusterMaker2.internal.ui.NewNetworkView;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJob;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobExecutionService;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobHandler;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.NetworkClusterJobHandler;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.RemoteServer;
+
+public class LEVCluster extends AbstractNetworkClusterer {
+
+ public static String NAME = "Leading Eigenvector (remote)";
+ public static String SHORTNAME = "leadingeigenvector";
+ final CyServiceRegistrar registrar;
+ public final static String GROUP_ATTRIBUTE = "__LeadingEigenvector.SUID";
+
+ @ContainsTunables
+ public LEVContext context = null;
+
+ public LEVCluster(LEVContext context, ClusterManager manager, CyServiceRegistrar registrar) {
+ super(manager);
+ this.context = context;
+ if (network == null)
+ network = clusterManager.getNetwork();
+ context.setNetwork(network);
+ this.registrar = registrar;
+ }
+
+ @Override
+ public String getShortName() {return SHORTNAME;}
+
+ @Override
+ @ProvidesTitle
+ public String getName() {return NAME;}
+
+ @Override
+ public void run(TaskMonitor taskMonitor) throws Exception {
+ monitor = taskMonitor;
+ // Get the execution service
+ CyJobExecutionService executionService =
+ registrar.getService(CyJobExecutionService.class, "(title=ClusterJobExecutor)");
+ CyApplicationManager appManager = registrar.getService(CyApplicationManager.class);
+ CyNetwork currentNetwork = appManager.getCurrentNetwork(); //gets the network presented in Cytoscape
+
+ clusterAttributeName = context.getClusterAttribute();
+ createGroups = context.advancedAttributes.createGroups;
+ String attribute = context.getattribute().getSelectedValue();
- public LEVCluster(LEVContext context, ClusterManager manager, CyServiceRegistrar registrar) {
- super(manager);
- this.context = context;
- if (network == null)
- network = clusterManager.getNetwork();
- context.setNetwork(network);
- this.registrar = registrar;
+ HashMap configuration = new HashMap<>();
+ if (context.isSynchronous == true) {
+ configuration.put("waitTime", -1);
+ } else {
+ configuration.put("waitTime", 20);
+ }
+
+ HashMap nodeMap = getNetworkNodes(currentNetwork);
+ List nodeArray = new ArrayList<>();
+ for (Long nodeSUID : nodeMap.keySet()) {
+ nodeArray.add(nodeMap.get(nodeSUID));
}
- @Override
- public String getShortName() {return SHORTNAME;}
+ List edgeArray = getNetworkEdges(currentNetwork, nodeMap, attribute);
- @Override
- public String getName() {return NAME;}
+ String basePath = RemoteServer.getBasePath();
- @Override
- public void run(TaskMonitor taskMonitor) throws Exception {
- // Get the execution service
- CyJobExecutionService executionService =
- registrar.getService(CyJobExecutionService.class, "(title=ClusterJobExecutor)");
- CyApplicationManager appManager = registrar.getService(CyApplicationManager.class);
- CyNetwork currentNetwork = appManager.getCurrentNetwork(); //gets the network presented in Cytoscape
+ // Get our initial job
+ ClusterJob job = (ClusterJob) executionService.createCyJob("ClusterJob"); //creates a new ClusterJob object
+ // Get the data service
+ CyJobDataService dataService = job.getJobDataService(); //gets the dataService of the execution service
+ // Add our data
+ CyJobData jobData = dataService.addData(null, "nodes", nodeArray);
+ jobData = dataService.addData(jobData, "edges", edgeArray);
+ job.storeClusterData(clusterAttributeName, currentNetwork, clusterManager, createGroups, GROUP_ATTRIBUTE, null, getShortName());
+ // Create our handler
+ NetworkClusterJobHandler jobHandler = new NetworkClusterJobHandler(job, network, context.vizProperties.showUI, context.vizProperties.restoreEdges);
+ job.setJobMonitor(jobHandler);
+ // Submit the job
+ CyJobStatus exStatus = executionService.executeJob(job, basePath, configuration, jobData);
+
+ CyJobStatus.Status status = exStatus.getStatus();
+ System.out.println("Status: " + status);
- clusterAttributeName = context.getClusterAttribute();
- createGroups = context.advancedAttributes.createGroups;
- String attribute = context.getattribute().getSelectedValue();
-
- HashMap nodeMap = getNetworkNodes(currentNetwork);
- List nodeArray = new ArrayList<>();
- for (Long nodeSUID : nodeMap.keySet()) {
- nodeArray.add(nodeMap.get(nodeSUID));
- }
-
- List edgeArray = getNetworkEdges(currentNetwork, nodeMap, attribute);
-
- String basePath = RemoteServer.getBasePath();
-
- // Get our initial job
- ClusterJob job = (ClusterJob) executionService.createCyJob("ClusterJob"); //creates a new ClusterJob object
- // Get the data service
- CyJobDataService dataService = job.getJobDataService(); //gets the dataService of the execution service
- // Add our data
- CyJobData jobData = dataService.addData(null, "nodes", nodeArray);
- jobData = dataService.addData(jobData, "edges", edgeArray);
- job.storeClusterData(clusterAttributeName, currentNetwork, clusterManager, createGroups, GROUP_ATTRIBUTE, null, getShortName());
- // Create our handler
- ClusterJobHandler jobHandler = new ClusterJobHandler(job, network);
- job.setJobMonitor(jobHandler);
- // Submit the job
- CyJobStatus exStatus = executionService.executeJob(job, basePath, null, jobData);
+ if (status == Status.FINISHED) {
+ jobHandler.loadData(job, taskMonitor);
+ } else if (status == Status.RUNNING
+ || status == Status.SUBMITTED
+ || status == Status.QUEUED) {
+ CyJobManager manager = registrar.getService(CyJobManager.class);
+ manager.addJob(job, jobHandler, 5); //this one shows the load button
- CyJobStatus.Status status = exStatus.getStatus();
- System.out.println("Status: " + status);
- if (status == Status.FINISHED) {
- executionService.fetchResults(job, dataService.getDataInstance());
- if (context.vizProperties.showUI) {
- taskMonitor.showMessage(TaskMonitor.Level.INFO, "Creating network");
- insertTasksAfterCurrentTask(new NewNetworkView(network, clusterManager, true, context.vizProperties.restoreEdges, false));
- }
-
- } else if (status == Status.RUNNING
- || status == Status.SUBMITTED
- || status == Status.QUEUED) {
- CyJobManager manager = registrar.getService(CyJobManager.class);
- manager.addJob(job, jobHandler, 5); //this one shows the load button
-
- } else if (status == Status.ERROR
- || status == Status.UNKNOWN
- || status == Status.CANCELED
- || status == Status.FAILED
- || status == Status.TERMINATED
- || status == Status.PURGED) {
- monitor.setStatusMessage("Job status: " + status);
- }
+ } else if (status == Status.ERROR) {
+ monitor.showMessage(TaskMonitor.Level.ERROR, "Job error: " + exStatus.getMessage());
+ } else if (status == Status.UNKNOWN
+ || status == Status.CANCELED
+ || status == Status.FAILED
+ || status == Status.TERMINATED
+ || status == Status.PURGED) {
+ monitor.setStatusMessage("Job status: " + status);
+ }
- // Save our SUIDs in case we get saved and restored
- SUIDUtil.saveSUIDs(job, currentNetwork, currentNetwork.getNodeList());
+ // Save our SUIDs in case we get saved and restored
+ SUIDUtil.saveSUIDs(job, currentNetwork, currentNetwork.getNodeList());
- }
+ }
- }
+}
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVClusterTaskFactory.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVClusterTaskFactory.java
index f322b96..f55f403 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVClusterTaskFactory.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVClusterTaskFactory.java
@@ -28,7 +28,10 @@ public LEVClusterTaskFactory(ClusterManager clusterManager, CyServiceRegistrar r
@Override
public String getLongDescription() {
- return "";
+ return "Newman's leading eigenvector method for detecting community structure. This is the proper "+
+ "implementation of the recursive, divisive algorithm: each split is done by maximizing the "+
+ "modularity regarding the original network, see MEJ Newman: Finding community structure in networks "+
+ "using the eigenvectors of matrices, Phys Rev E 74:036104 (2006). ";
}
@Override
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVContext.java
index e146088..19657c7 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/LeadingEigenVector/LEVContext.java
@@ -29,6 +29,13 @@ public ListSingleSelection getattribute(){
}
public void setattribute(ListSingleSelection attr) { }
+ @Tunable(description = "Synchronous",
+ longDescription = "If ```false``` the algorithm will run in the background after specified wait time",
+ exampleStringValue = "true",
+ tooltip = "If ```false``` the algorithm will run in the background after specified wait time",
+ groups = {"Leading Eigenvector Advanced Settings"}, gravity = 6.0)
+ public boolean isSynchronous = false;
+
@ContainsTunables
public AdvancedProperties advancedAttributes;
@@ -46,6 +53,7 @@ public LEVContext(LEVContext origin) {
advancedAttributes = new AdvancedProperties("LeadingEigenvectorCluster", false);
attribute = origin.attribute;
+ isSynchronous = origin.isSynchronous;
}
public void setNetwork(CyNetwork network) {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenCluster.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenCluster.java
index 7ee328c..565b8cc 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenCluster.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenCluster.java
@@ -14,6 +14,7 @@
import org.cytoscape.model.CyTable;
import org.cytoscape.service.util.CyServiceRegistrar;
import org.cytoscape.work.ContainsTunables;
+import org.cytoscape.work.ProvidesTitle;
import org.cytoscape.work.TaskMonitor;
import org.json.simple.JSONArray;
import org.cytoscape.jobs.CyJob;
@@ -38,9 +39,10 @@
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobExecutionService;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.RemoteServer;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobHandler;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.NetworkClusterJobHandler;
public class LeidenCluster extends AbstractNetworkClusterer {
- public static String NAME = "Leiden Clusterer";
+ public static String NAME = "Leiden Clusterer (remote)";
public static String SHORTNAME = "leiden";
final CyServiceRegistrar registrar;
public final static String GROUP_ATTRIBUTE = "__LeidenGroups.SUID";
@@ -62,10 +64,12 @@ public LeidenCluster(LeidenContext context, ClusterManager manager, CyServiceReg
public String getShortName() {return SHORTNAME;}
@Override
+ @ProvidesTitle
public String getName() {return NAME;}
@Override
public void run(TaskMonitor taskMonitor) throws Exception {
+ monitor = taskMonitor;
// Get the execution service
CyJobExecutionService executionService =
registrar.getService(CyJobExecutionService.class, "(title=ClusterJobExecutor)");
@@ -75,6 +79,19 @@ public void run(TaskMonitor taskMonitor) throws Exception {
clusterAttributeName = context.getClusterAttribute();
createGroups = context.advancedAttributes.createGroups;
String attribute = context.getattribute().getSelectedValue();
+
+ HashMap configuration = new HashMap<>();
+ if (context.isSynchronous == true) {
+ configuration.put("waitTime", -1);
+ } else {
+ configuration.put("waitTime", 20);
+ }
+
+ // Get the arguments from our context
+ configuration.put("resolution", context.resolution_parameter);
+ configuration.put("beta", context.beta);
+ configuration.put("iterations", context.n_iterations);
+ configuration.put("objective_function", context.objective_function.getSelectedValue());
HashMap nodeMap = getNetworkNodes(currentNetwork);
List nodeArray = new ArrayList<>();
@@ -95,28 +112,25 @@ public void run(TaskMonitor taskMonitor) throws Exception {
jobData = dataService.addData(jobData, "edges", edgeArray);
job.storeClusterData(clusterAttributeName, currentNetwork, clusterManager, createGroups, GROUP_ATTRIBUTE, null, getShortName());
// Create our handler
- ClusterJobHandler jobHandler = new ClusterJobHandler(job, network);
+ NetworkClusterJobHandler jobHandler = new NetworkClusterJobHandler(job, network, context.vizProperties.showUI, context.vizProperties.restoreEdges);
job.setJobMonitor(jobHandler);
// Submit the job
- CyJobStatus exStatus = executionService.executeJob(job, basePath, null, jobData);
+ CyJobStatus exStatus = executionService.executeJob(job, basePath, configuration, jobData);
CyJobStatus.Status status = exStatus.getStatus();
System.out.println("Status: " + status);
+
if (status == Status.FINISHED) {
- executionService.fetchResults(job, dataService.getDataInstance());
- if (context.vizProperties.showUI) {
- taskMonitor.showMessage(TaskMonitor.Level.INFO, "Creating network");
- insertTasksAfterCurrentTask(new NewNetworkView(network, clusterManager, true, context.vizProperties.restoreEdges, false));
- }
-
+ jobHandler.loadData(job, taskMonitor);
} else if (status == Status.RUNNING
|| status == Status.SUBMITTED
|| status == Status.QUEUED) {
CyJobManager manager = registrar.getService(CyJobManager.class);
manager.addJob(job, jobHandler, 5); //this one shows the load button
- } else if (status == Status.ERROR
- || status == Status.UNKNOWN
+ } else if (status == Status.ERROR) {
+ monitor.showMessage(TaskMonitor.Level.ERROR, "Job error: " + exStatus.getMessage());
+ } else if (status == Status.UNKNOWN
|| status == Status.CANCELED
|| status == Status.FAILED
|| status == Status.TERMINATED
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenClusterTaskFactory.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenClusterTaskFactory.java
index 428c3d7..efa31ba 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenClusterTaskFactory.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenClusterTaskFactory.java
@@ -30,7 +30,37 @@ public LeidenClusterTaskFactory(ClusterManager clusterManager, CyServiceRegistra
@Override
public String getLongDescription() {
- return "";
+ return "This function implements the Leiden "+
+ "algorithm for finding community structure, "+
+ "see Traag, V. A., Waltman, L., & van Eck, "+
+ "N. J. (2019). From Louvain to Leiden: guaranteeing "+
+ "well-connected communities. Scientific reports, 9(1), "+
+ "5233. http://dx.doi.org/10.1038/s41598-019-41695-z "+
+ "
"+
+ "It is similar to the multilevel algorithm, often called the "+
+ "Louvain algorithm, but it is faster and yields higher quality "+
+ "solutions. It can optimize both modularity and the Constant Potts "+
+ "Model, which does not suffer from the resolution-limit (see preprint "+
+ "http://arxiv.org/abs/1104.3083). "+
+ "
"+
+ "The Leiden algorithm consists of three phases: (1) local moving of nodes, "+
+ "(2) refinement of the partition and (3) aggregation of the network based "+
+ "on the refined partition, using the non-refined partition to create "+
+ "an initial partition for the aggregate network. In the local move "+
+ "procedure in the Leiden algorithm, only nodes whose neighborhood has "+
+ "changed are visited. The refinement is done by restarting from a singleton "+
+ "partition within each cluster and gradually merging the subclusters. When "+
+ "aggregating, a single cluster may then be represented by several nodes "+
+ "(which are the subclusters identified in the refinement). "+
+ "
"+
+ "The Leiden algorithm provides several guarantees. The Leiden algorithm "+
+ "is typically iterated: the output of one iteration is used as the input "+
+ "for the next iteration. At each iteration all clusters are guaranteed to "+
+ "be connected and well-separated. After an iteration in which nothing has "+
+ "changed, all nodes and some parts are guaranteed to be locally optimally "+
+ "assigned. Finally, asymptotically, all subsets of all clusters are "+
+ "guaranteed to be locally optimally assigned. For more details, please "+
+ "see Traag, Waltman & van Eck (2019). ";
}
@Override
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenContext.java
index 5af27fa..f68e622 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Leiden/LeidenContext.java
@@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import org.cytoscape.model.CyColumn;
@@ -28,6 +29,7 @@ public class LeidenContext implements ClusterAlgorithmContext {
@Tunable(description = "Objective function",
longDescription = "Whether to use the Constant Potts Model (CPM) or modularity. Must be either \"CPM\" or \"modularity\".",
exampleStringValue = "CPM",
+ tooltip = "Whether to use the Constant Potts Model (CPM) or modularity. Must be either 'CPM' or 'modularity'.",
groups = {"Leiden Advanced Settings"}, gravity = 1.0)
public ListSingleSelection objective_function = new ListSingleSelection<>("CPM", "modularity");
@@ -48,21 +50,32 @@ public void setattribute(ListSingleSelection attr) { }
+ "Higher resolutions lead to more smaller communities, "
+ "while lower resolutions lead to fewer larger communities.",
exampleStringValue = "1.0",
+ tooltip = "The resolution parameter to use. Higher resolutions lead to more smaller communities,
"
+ + "while lower resolutions lead to fewer larger communities.",
groups = {"Leiden Advanced Settings"}, gravity = 3.0)
public double resolution_parameter = 1.0;
@Tunable(description = "Beta value",
longDescription = "Parameter affecting the randomness in the Leiden algorithm. This affects only the refinement step of the algorithm.",
exampleStringValue = "0.01",
+ tooltip = "Parameter affecting the randomness in the Leiden algorithm. This affects only the refinement step of the algorithm.",
groups = {"Leiden Advanced Settings"}, gravity = 4.0)
public double beta = 0.01;
@Tunable(description = "Number of iterations",
longDescription = "The number of iterations to iterate the Leiden algorithm. Each iteration may improve the partition further.",
exampleStringValue = "2",
+ tooltip = "The number of iterations to iterate the Leiden algorithm. Each iteration may improve the partition further.",
groups = {"Leiden Advanced Settings"}, gravity = 5.0)
public int n_iterations = 2;
+ @Tunable(description = "Synchronous",
+ longDescription = "If ```false``` the algorithm will run in the background after specified wait time",
+ exampleStringValue = "true",
+ tooltip = "If ```false``` the algorithm will run in the background after specified wait time",
+ groups = {"Leiden Advanced Settings"}, gravity = 6.0)
+ public boolean isSynchronous = false;
+
@ContainsTunables
public AdvancedProperties advancedAttributes;
@@ -84,6 +97,8 @@ public LeidenContext(LeidenContext origin) {
resolution_parameter = origin.resolution_parameter;
beta = origin.beta;
n_iterations = origin.n_iterations;
+ isSynchronous = origin.isSynchronous;
+
}
public void setNetwork(CyNetwork network) {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelCluster.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelCluster.java
index f738676..04db9ba 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelCluster.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelCluster.java
@@ -1,118 +1,129 @@
package edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.Multilevel;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
- import org.cytoscape.application.CyApplicationManager;
- import org.cytoscape.jobs.CyJobData;
- import org.cytoscape.jobs.CyJobDataService;
- import org.cytoscape.jobs.CyJobExecutionService;
- import org.cytoscape.jobs.CyJobManager;
- import org.cytoscape.jobs.CyJobStatus;
- import org.cytoscape.jobs.SUIDUtil;
- import org.cytoscape.jobs.CyJobStatus.Status;
- import org.cytoscape.model.CyNetwork;
- import org.cytoscape.service.util.CyServiceRegistrar;
- import org.cytoscape.work.ContainsTunables;
- import org.cytoscape.work.TaskMonitor;
+import org.cytoscape.application.CyApplicationManager;
+import org.cytoscape.jobs.CyJobData;
+import org.cytoscape.jobs.CyJobDataService;
+import org.cytoscape.jobs.CyJobExecutionService;
+import org.cytoscape.jobs.CyJobManager;
+import org.cytoscape.jobs.CyJobStatus;
+import org.cytoscape.jobs.SUIDUtil;
+import org.cytoscape.jobs.CyJobStatus.Status;
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.service.util.CyServiceRegistrar;
+import org.cytoscape.work.ContainsTunables;
+import org.cytoscape.work.ProvidesTitle;
+import org.cytoscape.work.TaskMonitor;
- import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.AbstractNetworkClusterer;
- import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.Multilevel.MultilevelContext;
- import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
- import edu.ucsf.rbvi.clusterMaker2.internal.ui.NewNetworkView;
- import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJob;
- import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobHandler;
- import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.RemoteServer;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.NodeCluster;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.AbstractNetworkClusterer;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.networkClusterers.Multilevel.MultilevelContext;
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
+import edu.ucsf.rbvi.clusterMaker2.internal.ui.NewNetworkView;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJob;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobExecutionService;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.ClusterJobHandler;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.NetworkClusterJobHandler;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.remoteUtils.RemoteServer;
- public class MultilevelCluster extends AbstractNetworkClusterer {
+public class MultilevelCluster extends AbstractNetworkClusterer {
- public static String NAME = "Multilevel Cluster";
- public static String SHORTNAME = "multilevel";
- final CyServiceRegistrar registrar;
- public final static String GROUP_ATTRIBUTE = "__Multilevel.SUID";
-
- @ContainsTunables
- public MultilevelContext context = null;
-
- public MultilevelCluster(MultilevelContext context, ClusterManager manager, CyServiceRegistrar registrar) {
- super(manager);
- this.context = context;
- if (network == null)
- network = clusterManager.getNetwork();
- context.setNetwork(network);
- this.registrar = registrar;
- }
+ public static String NAME = "Multilevel Cluster (remote)";
+ public static String SHORTNAME = "multilevel";
+ final CyServiceRegistrar registrar;
+ public final static String GROUP_ATTRIBUTE = "__Multilevel.SUID";
+
+ @ContainsTunables
+ public MultilevelContext context = null;
+
+ public MultilevelCluster(MultilevelContext context, ClusterManager manager, CyServiceRegistrar registrar) {
+ super(manager);
+ this.context = context;
+ if (network == null)
+ network = clusterManager.getNetwork();
+ context.setNetwork(network);
+ this.registrar = registrar;
+ }
- @Override
- public String getShortName() {return SHORTNAME;}
+ @Override
+ public String getShortName() {return SHORTNAME;}
- @Override
- public String getName() {return NAME;}
+ @Override
+ @ProvidesTitle
+ public String getName() {return NAME;}
- @Override
- public void run(TaskMonitor taskMonitor) throws Exception {
- // Get the execution service
- CyJobExecutionService executionService =
- registrar.getService(CyJobExecutionService.class, "(title=ClusterJobExecutor)");
- CyApplicationManager appManager = registrar.getService(CyApplicationManager.class);
- CyNetwork currentNetwork = appManager.getCurrentNetwork(); //gets the network presented in Cytoscape
-
- clusterAttributeName = context.getClusterAttribute();
- createGroups = context.advancedAttributes.createGroups;
- String attribute = context.getattribute().getSelectedValue();
-
- HashMap nodeMap = getNetworkNodes(currentNetwork);
- List nodeArray = new ArrayList<>();
- for (Long nodeSUID : nodeMap.keySet()) {
- nodeArray.add(nodeMap.get(nodeSUID));
- }
-
- List edgeArray = getNetworkEdges(currentNetwork, nodeMap, attribute);
-
- String basePath = RemoteServer.getBasePath();
-
- // Get our initial job
- ClusterJob job = (ClusterJob) executionService.createCyJob("ClusterJob"); //creates a new ClusterJob object
- // Get the data service
- CyJobDataService dataService = job.getJobDataService(); //gets the dataService of the execution service
- // Add our data
- CyJobData jobData = dataService.addData(null, "nodes", nodeArray);
- jobData = dataService.addData(jobData, "edges", edgeArray);
- job.storeClusterData(clusterAttributeName, currentNetwork, clusterManager, createGroups, GROUP_ATTRIBUTE, null, getShortName());
- // Create our handler
- ClusterJobHandler jobHandler = new ClusterJobHandler(job, network);
- job.setJobMonitor(jobHandler);
- // Submit the job
- CyJobStatus exStatus = executionService.executeJob(job, basePath, null, jobData);
-
- CyJobStatus.Status status = exStatus.getStatus();
- System.out.println("Status: " + status);
- if (status == Status.FINISHED) {
- executionService.fetchResults(job, dataService.getDataInstance());
- if (context.vizProperties.showUI) {
- taskMonitor.showMessage(TaskMonitor.Level.INFO, "Creating network");
- insertTasksAfterCurrentTask(new NewNetworkView(network, clusterManager, true, context.vizProperties.restoreEdges, false));
- }
+ @Override
+ public void run(TaskMonitor taskMonitor) throws Exception {
+ monitor = taskMonitor;
+ // Get the execution service
+ CyJobExecutionService executionService =
+ registrar.getService(CyJobExecutionService.class, "(title=ClusterJobExecutor)");
+ CyApplicationManager appManager = registrar.getService(CyApplicationManager.class);
+ CyNetwork currentNetwork = appManager.getCurrentNetwork(); //gets the network presented in Cytoscape
+
+ clusterAttributeName = context.getClusterAttribute();
+ createGroups = context.advancedAttributes.createGroups;
+ String attribute = context.getattribute().getSelectedValue();
+
+ HashMap configuration = new HashMap<>();
+ if (context.isSynchronous == true) {
+ configuration.put("waitTime", -1);
+ } else {
+ configuration.put("waitTime", 20);
+ }
- } else if (status == Status.RUNNING
- || status == Status.SUBMITTED
- || status == Status.QUEUED) {
- CyJobManager manager = registrar.getService(CyJobManager.class);
- manager.addJob(job, jobHandler, 5); //this one shows the load button
+ HashMap nodeMap = getNetworkNodes(currentNetwork);
+ List nodeArray = new ArrayList<>();
+ for (Long nodeSUID : nodeMap.keySet()) {
+ nodeArray.add(nodeMap.get(nodeSUID));
+ }
+
+ List edgeArray = getNetworkEdges(currentNetwork, nodeMap, attribute);
- } else if (status == Status.ERROR
- || status == Status.UNKNOWN
- || status == Status.CANCELED
- || status == Status.FAILED
- || status == Status.TERMINATED
- || status == Status.PURGED) {
- monitor.setStatusMessage("Job status: " + status);
- }
+ String basePath = RemoteServer.getBasePath();
+
+ // Get our initial job
+ ClusterJob job = (ClusterJob) executionService.createCyJob("ClusterJob"); //creates a new ClusterJob object
+ // Get the data service
+ CyJobDataService dataService = job.getJobDataService(); //gets the dataService of the execution service
+ // Add our data
+ CyJobData jobData = dataService.addData(null, "nodes", nodeArray);
+ jobData = dataService.addData(jobData, "edges", edgeArray);
+ job.storeClusterData(clusterAttributeName, currentNetwork, clusterManager, createGroups, GROUP_ATTRIBUTE, null, getShortName());
+ // Create our handler
+ NetworkClusterJobHandler jobHandler = new NetworkClusterJobHandler(job, network, context.vizProperties.showUI, context.vizProperties.restoreEdges);
+ job.setJobMonitor(jobHandler);
+ // Submit the job
+ CyJobStatus exStatus = executionService.executeJob(job, basePath, configuration, jobData);
+
+ CyJobStatus.Status status = exStatus.getStatus();
+ System.out.println("Status: " + status);
+
+ if (status == Status.FINISHED) {
+ jobHandler.loadData(job, taskMonitor);
+ } else if (status == Status.RUNNING
+ || status == Status.SUBMITTED
+ || status == Status.QUEUED) {
+ CyJobManager manager = registrar.getService(CyJobManager.class);
+ manager.addJob(job, jobHandler, 5); //this one shows the load button
- // Save our SUIDs in case we get saved and restored
- SUIDUtil.saveSUIDs(job, currentNetwork, currentNetwork.getNodeList());
+ } else if (status == Status.ERROR) {
+ monitor.showMessage(TaskMonitor.Level.ERROR, "Job error: " + exStatus.getMessage());
+ } else if (status == Status.UNKNOWN
+ || status == Status.CANCELED
+ || status == Status.FAILED
+ || status == Status.TERMINATED
+ || status == Status.PURGED) {
+ monitor.setStatusMessage("Job status: " + status);
+ }
+
+ // Save our SUIDs in case we get saved and restored
+ SUIDUtil.saveSUIDs(job, currentNetwork, currentNetwork.getNodeList());
- }
+ }
- }
+}
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelClusterTaskFactory.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelClusterTaskFactory.java
index 4967fdc..feeb4b1 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelClusterTaskFactory.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelClusterTaskFactory.java
@@ -28,7 +28,35 @@ public MultilevelClusterTaskFactory(ClusterManager clusterManager, CyServiceRegi
@Override
public String getLongDescription() {
- return "";
+ return "This function implements the multi-level "+
+ "modularity optimization algorithm for finding "+
+ "community structure, see Blondel, V. D., "+
+ "Guillaume, J.-L., Lambiotte, R., & Lefebvre, "+
+ "E. (2008). Fast unfolding of communities "+
+ "in large networks. Journal of Statistical "+
+ "Mechanics: Theory and Experiment, 10008(10), 6. "+
+ "https://doi.org/10.1088/1742-5468/2008/10/P10008 "+
+ "for the details (preprint: "+
+ "http://arxiv.org/abs/0803.0476). The algorithm "+
+ "is sometimes known as the 'Louvain' algorithm. "+
+ "
"+
+ "The algorithm is based on the modularity measure and a hierarchical "+
+ "approach. Initially, each vertex is assigned to a community on its own. In "+
+ "every step, vertices are re-assigned to communities in a local, greedy "+
+ "way: in a random order, each vertex is moved to the community with which "+
+ "it achieves the highest contribution to modularity. When no vertices "+
+ "can be reassigned, each community is considered a vertex on its own, "+
+ "and the process starts again with the merged communities. The process "+
+ "stops when there is only a single vertex left or when the modularity "+
+ "cannot be increased any more in a step. "+
+ "
"+
+ "The resolution parameter gamma allows finding communities at different "+
+ "resolutions. Higher values of the resolution parameter typically result in "+
+ "more, smaller communities. Lower values typically result in fewer, larger "+
+ "communities. The original definition of modularity is retrieved when "+
+ "setting gamma=1. Note that the returned modularity value is calculated "+
+ "using the indicated resolution parameter. See igraph_modularity() for "+
+ "more details. This function was contributed by Tom Gregorovic. ";
}
@Override
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelContext.java
index 1053a5e..d4cd699 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/Multilevel/MultilevelContext.java
@@ -29,6 +29,13 @@ public ListSingleSelection getattribute(){
}
public void setattribute(ListSingleSelection attr) { }
+ @Tunable(description = "Synchronous",
+ longDescription = "If ```false``` the algorithm will run in the background after specified wait time",
+ exampleStringValue = "true",
+ tooltip = "If ```false``` the algorithm will run in the background after specified wait time",
+ groups = {"Leiden Advanced Settings"}, gravity = 6.0)
+ public boolean isSynchronous = false;
+
@ContainsTunables
public AdvancedProperties advancedAttributes;
@@ -46,6 +53,7 @@ public MultilevelContext(MultilevelContext origin) {
advancedAttributes = new AdvancedProperties("MultilevelCluster", false);
attribute = origin.attribute;
+ isSynchronous = origin.isSynchronous;
}
public void setNetwork(CyNetwork network) {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/RunTransClust.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/RunTransClust.java
index b96aa5f..c19305a 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/RunTransClust.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/RunTransClust.java
@@ -58,7 +58,7 @@ public List run(TaskMonitor monitor, CyNetwork network)
count = 0;
for (int i = 0; i < this.nodes.size(); i++) {
CyNode cyNodeI = this.nodes.get(i);
- es.startPositions[integers2proteins.get(cyNodeI.getSUID())] = count;
+ es.startPositions[integers2proteins.get(ModelUtils.getNodeName(network, cyNodeI))] = count;
for (int j = 0; j < this.nodes.size(); j++) {
CyNode cyNodeJ = this.nodes.get(j);
es.sources[count] = i;
@@ -69,7 +69,7 @@ public List run(TaskMonitor monitor, CyNetwork network)
count++;
}
}
- es.endPositions[integers2proteins.get(cyNodeI.getSUID())] = count-1;
+ es.endPositions[integers2proteins.get(ModelUtils.getNodeName(network, cyNodeI))] = count-1;
}
Semaphore s = new Semaphore(1);
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/TransClustCluster.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/TransClustCluster.java
index 98e81cd..a937d9d 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/TransClustCluster.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/TransClustCluster.java
@@ -144,6 +144,7 @@ public void run(TaskMonitor monitor) {
monitor.showMessage(TaskMonitor.Level.INFO,"Clustering...");
createGroups = context.advancedAttributes.createGroups;
+ clusterAttributeName = context.getClusterAttribute();
//Cluster the nodes
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/TransClusterContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/TransClusterContext.java
index 019d4ee..5a97917 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/TransClusterContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/networkClusterers/TransClust/TransClusterContext.java
@@ -32,7 +32,7 @@ public class TransClusterContext implements ClusterAlgorithmContext {
public int mergeThreshold = 100;
@Tunable(description= "Number of Processors:",groups={"Advanced Tuning Parameters","Parallelization"}, gravity=15.0)
- public int processors = -1;
+ public int processors = 1;
@ContainsTunables
public AdvancedProperties advancedAttributes;
@@ -42,6 +42,7 @@ public class TransClusterContext implements ClusterAlgorithmContext {
public TransClusterContext() {
advancedAttributes = new AdvancedProperties("__transclustCluster", false);
+ processors = Runtime.getRuntime().availableProcessors();
}
public TransClusterContext(TransClusterContext origin) {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/HITS/HITSContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/HITS/HITSContext.java
index 40e7c20..6d4eb63 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/HITS/HITSContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/HITS/HITSContext.java
@@ -1,7 +1,9 @@
package edu.ucsf.rbvi.clusterMaker2.internal.algorithms.ranking.HITS;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.ranking.units.NormalizationContext;
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import org.cytoscape.model.CyNetwork;
+import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.Tunable;
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/HITS/HyperlinkInducedTopicSearch.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/HITS/HyperlinkInducedTopicSearch.java
index 0f8010e..8fcd69b 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/HITS/HyperlinkInducedTopicSearch.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/HITS/HyperlinkInducedTopicSearch.java
@@ -12,17 +12,20 @@
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.api.Rank;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.ClusterUtils;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.ModelUtils;
import org.cytoscape.model.CyEdge;
import org.cytoscape.model.CyNetwork;
import org.cytoscape.model.CyNode;
import org.cytoscape.work.AbstractTask;
import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.ObservableTask;
+import org.cytoscape.work.ProvidesTitle;
import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.Tunable;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class HyperlinkInducedTopicSearch extends AbstractTask implements Rank, ObservableTask {
private ClusterManager manager;
@@ -58,6 +61,7 @@ public String getShortName() {
}
@Override
+ @ProvidesTitle
public String getName() {
return NAME;
}
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAA/MAAContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAA/MAAContext.java
index 2f3c08f..9cd9346 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAA/MAAContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAA/MAAContext.java
@@ -1,9 +1,11 @@
package edu.ucsf.rbvi.clusterMaker2.internal.algorithms.ranking.MAA;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.ranking.units.NormalizationContext;
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.ModelUtils;
import org.cytoscape.model.CyNetwork;
import org.cytoscape.work.Tunable;
+import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.util.ListMultipleSelection;
import java.util.List;
@@ -19,9 +21,13 @@ public class MAAContext {
@Tunable(description = "Edge attributes", groups = "Biomarker information", gravity = 10.0)
public ListMultipleSelection edgeAttributes;
+ @ContainsTunables
+ public NormalizationContext normalizationContext;
+
public MAAContext(ClusterManager manager) {
this.manager = manager;
network = this.manager.getNetwork();
+ normalizationContext = new NormalizationContext(manager, network);
updateContext();
}
@@ -72,6 +78,7 @@ private String getClusterColumnName() {
public void setNetwork(CyNetwork network) {
this.network = network;
+ normalizationContext.setNetwork(network);
}
public CyNetwork getNetwork() {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAA/MultipleAttributeAddition.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAA/MultipleAttributeAddition.java
index d18071c..9396ee0 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAA/MultipleAttributeAddition.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAA/MultipleAttributeAddition.java
@@ -5,14 +5,17 @@
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.api.Rank;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.ClusterUtils;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.ModelUtils;
import org.cytoscape.model.*;
import org.cytoscape.work.AbstractTask;
import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.ObservableTask;
+import org.cytoscape.work.ProvidesTitle;
import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.Tunable;
import java.util.List;
+import java.util.Map;
public class MultipleAttributeAddition extends AbstractTask implements Rank, ObservableTask {
private ClusterManager manager;
@@ -44,6 +47,7 @@ public String getShortName() {
}
@Override
+ @ProvidesTitle
public String getName() {
return NAME;
}
@@ -68,10 +72,22 @@ public void run(TaskMonitor taskMonitor) {
taskMonitor.setProgress(0.6);
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Setting node scores in clusters");
- clusters = ClusterUtils.setNodeScoresInCluster(network, clusters, nodeAttributes, clusterColumnName, false);
+
+ // Begin by doing basic normalization -- in particular handling possible negative values
+ Map nodeMap = null;
+ if (nodeAttributes.size() > 0 && !nodeAttributes.get(0).equals(ModelUtils.NONEATTRIBUTE)) {
+ nodeMap = context.normalizationContext.normalize(nodeAttributes, network.getNodeList());
+ clusters = ClusterUtils.setNodeScoresInCluster(network, clusters, nodeMap, clusterColumnName, false);
+ }
+
taskMonitor.setProgress(0.75);
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Setting edge scores in clusters");
- clusters = ClusterUtils.setEdgeScoresInCluster(network, clusters, edgeAttributes, clusterColumnName, false);
+
+ Map edgeMap = null;
+ if (edgeAttributes.size() > 0 && !edgeAttributes.get(0).equals(ModelUtils.NONEATTRIBUTE)) {
+ edgeMap = context.normalizationContext.normalize(edgeAttributes, network.getEdgeList());
+ clusters = ClusterUtils.setEdgeScoresInCluster(network, clusters, edgeMap, clusterColumnName, false);
+ }
taskMonitor.setProgress(0.80);
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Sorting and ranking clusters");
ClusterUtils.ascendingSort(clusters);
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAM/MAMContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAM/MAMContext.java
index a054bc4..6ed2dc8 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAM/MAMContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAM/MAMContext.java
@@ -1,8 +1,10 @@
package edu.ucsf.rbvi.clusterMaker2.internal.algorithms.ranking.MAM;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.ranking.units.NormalizationContext;
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.ModelUtils;
import org.cytoscape.model.CyNetwork;
+import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.Tunable;
import org.cytoscape.work.util.ListMultipleSelection;
@@ -19,9 +21,13 @@ public class MAMContext {
@Tunable(description = "Edge attributes", groups = "Biomarker information", gravity = 10.0)
public ListMultipleSelection edgeAttributes;
+ @ContainsTunables
+ public NormalizationContext normalizationContext;
+
public MAMContext(ClusterManager manager) {
this.manager = manager;
network = this.manager.getNetwork();
+ normalizationContext = new NormalizationContext(manager, network);
updateContext();
}
@@ -72,6 +78,7 @@ private String getClusterColumnName() {
public void setNetwork(CyNetwork network) {
this.network = network;
+ normalizationContext.setNetwork(network);
}
public CyNetwork getNetwork() {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAM/MultipleAttributeMultiplicative.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAM/MultipleAttributeMultiplicative.java
index c116fcf..bc3fed7 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAM/MultipleAttributeMultiplicative.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/MAM/MultipleAttributeMultiplicative.java
@@ -5,14 +5,17 @@
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.api.Rank;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.ClusterUtils;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.ModelUtils;
import org.cytoscape.model.*;
import org.cytoscape.work.AbstractTask;
import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.ObservableTask;
+import org.cytoscape.work.ProvidesTitle;
import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.Tunable;
import java.util.List;
+import java.util.Map;
public class MultipleAttributeMultiplicative extends AbstractTask implements Rank, ObservableTask {
private ClusterManager manager;
@@ -44,6 +47,7 @@ public String getShortName() {
}
@Override
+ @ProvidesTitle
public String getName() {
return NAME;
}
@@ -68,10 +72,22 @@ public void run(TaskMonitor taskMonitor) {
taskMonitor.setProgress(0.6);
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Setting node scores in clusters");
- clusters = ClusterUtils.setNodeScoresInCluster(network, clusters, nodeAttributes, clusterColumnName, true);
+ // Begin by doing basic normalization -- in particular handling possible negative values
+ Map nodeMap = null;
+ if (nodeAttributes.size() > 0 && !nodeAttributes.get(0).equals(ModelUtils.NONEATTRIBUTE)) {
+ nodeMap = context.normalizationContext.normalize(nodeAttributes, network.getNodeList());
+ clusters = ClusterUtils.setNodeScoresInCluster(network, clusters, nodeMap, clusterColumnName, true);
+ }
+
taskMonitor.setProgress(0.75);
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Setting edge scores in clusters");
- clusters = ClusterUtils.setEdgeScoresInCluster(network, clusters, edgeAttributes, clusterColumnName, true);
+
+ Map edgeMap = null;
+ if (edgeAttributes.size() > 0 && !edgeAttributes.get(0).equals(ModelUtils.NONEATTRIBUTE)) {
+ edgeMap = context.normalizationContext.normalize(edgeAttributes, network.getEdgeList());
+ clusters = ClusterUtils.setEdgeScoresInCluster(network, clusters, edgeMap, clusterColumnName, true);
+ }
+
taskMonitor.setProgress(0.80);
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Sorting and ranking clusters");
ClusterUtils.ascendingSort(clusters);
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/NodeRankingTaskFactory.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/NodeRankingTaskFactory.java
new file mode 100644
index 0000000..00ec04e
--- /dev/null
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/NodeRankingTaskFactory.java
@@ -0,0 +1,69 @@
+package edu.ucsf.rbvi.clusterMaker2.internal.algorithms.ranking;
+
+import java.util.Collections;
+import java.util.List;
+
+//Cytoscape imports
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.work.TaskIterator;
+
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterTaskFactory;
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterTaskFactory.ClusterType;
+import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterViz;
+import edu.ucsf.rbvi.clusterMaker2.internal.api.RankFactory;
+
+public class NodeRankingTaskFactory implements RankFactory {
+ ClusterManager clusterManager;
+
+ public NodeRankingTaskFactory(ClusterManager clusterManager) {
+ this.clusterManager = clusterManager;
+ }
+
+ public String getShortName() {return null; }
+ public String getName() {return "--- Node Ranking Algorithms ---";}
+
+ public ClusterViz getVisualizer() {
+ // return new NewNetworkView(true);
+ return null;
+ }
+
+ public boolean isReady() {
+ return false;
+ }
+
+ public boolean isAvailable(CyNetwork network) {
+ return false;
+ }
+
+ public List getTypeList() {
+ return Collections.singletonList(ClusterType.RANKING);
+ }
+
+ public TaskIterator createTaskIterator() {
+ // Not sure why we need to do this, but it looks like
+ // the tunable stuff "remembers" objects that it's already
+ // processed this tunable. So, we use a copy constructor
+ return null;
+ }
+
+ @Override
+ public Object getContext() {
+ return null;
+ }
+
+ @Override
+ public String getSupportsJSON() { return "false"; }
+
+ @Override
+ public String getLongDescription() { return ""; }
+
+ @Override
+ public String getExampleJSON() { return ""; }
+
+}
+
+
+
+
+
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PR/PR.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PR/PR.java
index a7fd5af..811fc8f 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PR/PR.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PR/PR.java
@@ -13,18 +13,22 @@
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.api.Rank;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.ClusterUtils;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.ModelUtils;
import org.cytoscape.model.CyEdge;
+import org.cytoscape.model.CyIdentifiable;
import org.cytoscape.model.CyNetwork;
import org.cytoscape.model.CyNode;
import org.cytoscape.model.CyTable;
import org.cytoscape.work.AbstractTask;
import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.ObservableTask;
+import org.cytoscape.work.ProvidesTitle;
import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.Tunable;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class PR extends AbstractTask implements Rank, ObservableTask {
private ClusterManager manager;
@@ -36,6 +40,7 @@ public class PR extends AbstractTask implements Rank, ObservableTask {
@ContainsTunables
public PRContext context;
+
private Hypergraph graph;
private HashMap idToNode;
private List nodeList;
@@ -63,6 +68,7 @@ public String getShortName() {
}
@Override
+ @ProvidesTitle
public String getName() {
return NAME;
}
@@ -75,7 +81,7 @@ public Object getContext() {
@Override
public void run(TaskMonitor taskMonitor) {
taskMonitor.setProgress(0.0);
- taskMonitor.setTitle("PRWP with Priors ranking of clusters");
+ taskMonitor.setTitle("PR ranking of clusters");
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Fetching clusters...");
taskMonitor.setProgress(0.1);
List clusters = ClusterUtils.fetchClusters(network);
@@ -92,6 +98,9 @@ public void run(TaskMonitor taskMonitor) {
addEdges();
taskMonitor.setProgress(0.7);
+ // Normalize the scores based on the source node
+ normalizeEdges();
+
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Calculating PageRank scores");
PageRank pageRank = performPageRank();
taskMonitor.setProgress(0.8);
@@ -118,6 +127,21 @@ public R getResults(Class extends R> clzz) {
return results.getResults(clzz);
}
+ private void normalizeEdges() {
+ // The PageRank algorithm requires that edge weights represent a transition probability -- that is,
+ // they must sum to 1. We need to adjust our edges to reflect that
+ for (PRNode node: graph.getVertices()) {
+ double sum = 0d;
+ for (PREdge edge: graph.getOutEdges(node)) {
+ sum += edge.getScore();
+ }
+
+ for (PREdge edge: graph.getOutEdges(node)) {
+ edge.setScore(edge.getScore()/sum);
+ }
+ }
+ }
+
private void insertScores(List clusters, PageRank pageRank) {
for (PRNode node : graph.getVertices()) {
node.setPRScore(pageRank.getVertexScore(node));
@@ -138,12 +162,22 @@ private PageRank performPageRank() {
}
private void addEdges() {
+ Map edgeMap = null;
+ context.normalizationContext.normalize(edgeAttributes, edgeList);
+ if (edgeAttributes.size() > 0 && !edgeAttributes.get(0).equals(ModelUtils.NONEATTRIBUTE))
+ edgeMap = context.normalizationContext.normalize(edgeAttributes, edgeList);
for (CyEdge edge : edgeList) {
PRNode sourceNode = idToNode.get(edge.getSource().getSUID());
PRNode targetNode = idToNode.get(edge.getTarget().getSUID());
PREdge prEdge = new PREdge(edge);
- insertEdgeScore(prEdge, edgeTable, edgeAttributes);
- graph.addEdge(prEdge, new Pair<>(sourceNode, targetNode), EdgeType.DIRECTED);
+ if (edgeMap != null)
+ insertEdgeScore(prEdge, edgeMap.get(edge));
+ else
+ prEdge.setScore(0.0d);
+ if (edge.isDirected())
+ graph.addEdge(prEdge, new Pair<>(sourceNode, targetNode), EdgeType.DIRECTED);
+ else
+ graph.addEdge(prEdge, new Pair<>(sourceNode, targetNode), EdgeType.UNDIRECTED);
}
}
@@ -167,26 +201,12 @@ private void initVariables() {
}
- private void insertEdgeScore(PREdge prEdge, CyTable edgeTable, List edgeAttributes) {
- Double totalEdgeScore = 0.0d;
-
- for (String edgeAttribute : edgeAttributes) {
- double singleEdgeAttributeScore = 0.0d;
+ private void insertEdgeScore(PREdge prEdge, double[] edgeAttrValues) {
+ double totalEdgeScore = 0.0d;
- try { // Double
- singleEdgeAttributeScore = edgeTable.getRow(prEdge.getCyEdge().getSUID())
- .get(edgeAttribute, Double.class, 0.0d);
- } catch (ClassCastException cce) {
- try { // Integer
- singleEdgeAttributeScore = edgeTable.getRow(prEdge.getCyEdge().getSUID())
- .get(edgeAttribute, Integer.class, 0);
- } catch (Exception e) {
- e.printStackTrace();
- }
- } finally {
- totalEdgeScore += singleEdgeAttributeScore;
- }
- }
+ for (double value: edgeAttrValues) {
+ totalEdgeScore += value;
+ }
prEdge.setScore(totalEdgeScore);
}
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PR/PRContext.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PR/PRContext.java
index 83f9bc6..37ce35e 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PR/PRContext.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PR/PRContext.java
@@ -1,8 +1,10 @@
package edu.ucsf.rbvi.clusterMaker2.internal.algorithms.ranking.PR;
+import edu.ucsf.rbvi.clusterMaker2.internal.algorithms.ranking.units.NormalizationContext;
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.ModelUtils;
import org.cytoscape.model.CyNetwork;
+import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.Tunable;
import org.cytoscape.work.util.ListMultipleSelection;
@@ -22,9 +24,13 @@ public class PRContext {
@Tunable(description = "Iterations", groups = "PR factors", gravity = 10.0)
public int iterations = 1000;
+ @ContainsTunables
+ public NormalizationContext normalizationContext;
+
public PRContext(ClusterManager manager) {
this.manager = manager;
network = this.manager.getNetwork();
+ normalizationContext = new NormalizationContext(manager, network);
updateContext();
}
@@ -56,6 +62,7 @@ public String getClusterColumnName() {
public void setNetwork(CyNetwork network) {
this.network = network;
+ normalizationContext.setNetwork(network);
}
public CyNetwork getNetwork() {
diff --git a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PRWP/PRWP.java b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PRWP/PRWP.java
index 5a49b84..b9d138d 100644
--- a/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PRWP/PRWP.java
+++ b/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/algorithms/ranking/PRWP/PRWP.java
@@ -13,18 +13,22 @@
import edu.ucsf.rbvi.clusterMaker2.internal.api.ClusterManager;
import edu.ucsf.rbvi.clusterMaker2.internal.api.Rank;
import edu.ucsf.rbvi.clusterMaker2.internal.utils.ClusterUtils;
+import edu.ucsf.rbvi.clusterMaker2.internal.utils.ModelUtils;
import org.cytoscape.model.CyEdge;
+import org.cytoscape.model.CyIdentifiable;
import org.cytoscape.model.CyNetwork;
import org.cytoscape.model.CyNode;
import org.cytoscape.model.CyTable;
import org.cytoscape.work.AbstractTask;
import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.ObservableTask;
+import org.cytoscape.work.ProvidesTitle;
import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.Tunable;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class PRWP extends AbstractTask implements Rank, ObservableTask {
private ClusterManager manager;
@@ -36,6 +40,7 @@ public class PRWP extends AbstractTask implements Rank, ObservableTask {
@ContainsTunables
public PRWPContext context;
+
private Hypergraph graph;
private HashMap idToNode;
private List nodeList;
@@ -64,6 +69,7 @@ public String getShortName() {
}
@Override
+ @ProvidesTitle
public String getName() {
return NAME;
}
@@ -93,6 +99,14 @@ public void run(TaskMonitor taskMonitor) {
addEdges();
taskMonitor.setProgress(0.7);
+ // Normalize the scores
+ //if (nodeAttributes.size() > 0 && !nodeAttributes.get(0).equals(ModelUtils.NONEATTRIBUTE))
+ // normalizeNodes();
+
+ // Normalize the scores based on the source node
+ if (edgeAttributes.size() > 0 && !edgeAttributes.get(0).equals(ModelUtils.NONEATTRIBUTE))
+ normalizeEdges();
+
taskMonitor.showMessage(TaskMonitor.Level.INFO, "Calculating PageRank scores");
PageRankWithPriors pageRank = performPageRank();
taskMonitor.setProgress(0.8);
@@ -119,6 +133,33 @@ public R getResults(Class extends R> clzz) {
return results.getResults(clzz);
}
+ private void normalizeNodes() {
+ double sum = 0d;
+ for (PRNode node: graph.getVertices()) {
+ sum += node.getScore();
+ }
+
+ for (PRNode node: graph.getVertices()) {
+ node.setScore(node.getScore()/sum);
+ }
+
+ }
+
+ private void normalizeEdges() {
+ // The PageRank algorithm requires that edge weights represent a transition probability -- that is,
+ // they must sum to 1. We need to adjust our edges to reflect that
+ for (PRNode node: graph.getVertices()) {
+ double sum = 0d;
+ for (PREdge edge: graph.getOutEdges(node)) {
+ sum += edge.getScore();
+ }
+
+ for (PREdge edge: graph.getOutEdges(node)) {
+ edge.setScore(edge.getScore()/sum);
+ }
+ }
+ }
+
private void insertScores(List