diff --git a/AutoAnnotate/pom.xml b/AutoAnnotate/pom.xml
index 2dbab89..24ae650 100644
--- a/AutoAnnotate/pom.xml
+++ b/AutoAnnotate/pom.xml
@@ -5,7 +5,7 @@
AutoAnnotate
org.baderlab.autoannotate
org.baderlab.autoannotate
- 3.3.0
+ 3.4.0
AutoAnnotate
diff --git a/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/ApplicationModule.java b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/ApplicationModule.java
index ca0b50f..6de3ff8 100644
--- a/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/ApplicationModule.java
+++ b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/ApplicationModule.java
@@ -9,6 +9,7 @@
import org.baderlab.autoannotate.internal.task.CollapseAllTaskFactory;
import org.baderlab.autoannotate.internal.task.CollapseTask;
import org.baderlab.autoannotate.internal.task.CreateAnnotationSetTask;
+import org.baderlab.autoannotate.internal.task.CreateSubnetworkTask;
import org.baderlab.autoannotate.internal.task.LayoutAnnotationSetTaskFactory;
import org.baderlab.autoannotate.internal.task.LayoutClustersTaskFactory;
import org.baderlab.autoannotate.internal.task.RunClusterMakerTaskFactory;
@@ -87,6 +88,7 @@ protected void configure() {
installFactory(RemoveAllAnnotationsTask.Factory.class);
installFactory(CreateAnnotationSetTask.Factory.class);
installFactory(CreateClusterTask.Factory.class);
+ installFactory(CreateSubnetworkTask.Factory.class);
}
private void installFactory(Class> factoryInterface) {
diff --git a/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/CytoscapeServiceModule.java b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/CytoscapeServiceModule.java
index f81db41..2f3bbd0 100644
--- a/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/CytoscapeServiceModule.java
+++ b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/CytoscapeServiceModule.java
@@ -19,6 +19,7 @@
import org.cytoscape.model.CyNetworkTableManager;
import org.cytoscape.model.CyTableFactory;
import org.cytoscape.model.CyTableManager;
+import org.cytoscape.model.subnetwork.CyRootNetworkManager;
import org.cytoscape.service.util.CyServiceRegistrar;
import org.cytoscape.session.CySessionManager;
import org.cytoscape.util.swing.FileUtil;
@@ -75,6 +76,7 @@ protected void configure() {
bindService(CyTableManager.class);
bindService(CyTableFactory.class);
bindService(FileUtil.class);
+ bindService(CyRootNetworkManager.class);
bindService(DialogTaskManager.class);
TypeLiteral> synchronousManager = new TypeLiteral>(){};
diff --git a/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/CreateAnnotationSetTask.java b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/CreateAnnotationSetTask.java
index 54c91a3..3298710 100644
--- a/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/CreateAnnotationSetTask.java
+++ b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/CreateAnnotationSetTask.java
@@ -26,8 +26,11 @@
import org.baderlab.autoannotate.internal.model.io.CreationParameter;
import org.baderlab.autoannotate.internal.util.ResultObserver;
import org.cytoscape.model.CyNetwork;
+import org.cytoscape.model.CyNetworkManager;
import org.cytoscape.model.CyNode;
import org.cytoscape.view.model.CyNetworkView;
+import org.cytoscape.view.model.View;
+import org.cytoscape.view.presentation.property.BasicVisualLexicon;
import org.cytoscape.work.AbstractTask;
import org.cytoscape.work.TaskIterator;
import org.cytoscape.work.TaskManager;
@@ -41,8 +44,10 @@
public class CreateAnnotationSetTask extends AbstractTask {
@Inject private RunClusterMakerTaskFactory.Factory clusterMakerFactoryFactory;
+ @Inject private CreateSubnetworkTask.Factory subnetworkTaskFactory;
@Inject private Provider labelManagerProvider;
@Inject private LayoutClustersTaskFactory.Factory layoutTaskFactoryFactory;
+ @Inject private CyNetworkManager networkManager;
@Inject private @Named("sync") TaskManager,?> syncTaskManager;
@Inject private ModelManager modelManager;
@@ -170,11 +175,30 @@ private boolean needClusterEdgeAttribute() {
private Map> runClusterMaker(Optional cutoff) {
- RunClusterMakerTaskFactory clusterMakerTaskFactory = clusterMakerFactoryFactory.create(params, cutoff.orElse(null));
+ CyNetworkView networkView = params.getNetworkView();
+ CyNetwork network = networkView.getModel();
+ boolean hasHidden = hasHiddenNodes(networkView);
+ if(hasHidden) {
+ Collection visibleNodes = getVisibleNodes(networkView);
+ CreateSubnetworkTask subnetworkTask = subnetworkTaskFactory.create(network, visibleNodes);
+ ResultObserver observer = new ResultObserver<>(subnetworkTask, CyNetwork.class);
+ syncTaskManager.execute(new TaskIterator(subnetworkTask), observer);
+ network = observer.getResults().get();
+ networkManager.addNetwork(network, false);
+ }
+
+ RunClusterMakerTaskFactory clusterMakerTaskFactory =
+ clusterMakerFactoryFactory.create(network, params.getClusterAlgorithm(), params.getClusterMakerEdgeAttribute(), cutoff.orElse(null));
RunClusterMakerResultObserver clusterResultObserver = new RunClusterMakerResultObserver();
TaskIterator tasks = clusterMakerTaskFactory.createTaskIterator(clusterResultObserver);
syncTaskManager.execute(tasks);
- return clusterResultObserver.getResult();
+ Map> result = clusterResultObserver.getResult();
+
+ if(hasHidden) {
+ networkManager.destroyNetwork(network);
+ }
+
+ return result;
}
@@ -215,7 +239,8 @@ private String createName(NetworkViewSet networkViewSet) {
private Map> computeClustersFromColumn() {
String attribute = params.getClusterDataColumn();
- CyNetwork network = params.getNetworkView().getModel();
+ CyNetworkView networkView = params.getNetworkView();
+ CyNetwork network = networkView.getModel();
Map> clusters = new HashMap<>();
@@ -227,6 +252,9 @@ private Map> computeClustersFromColumn() {
}
for(CyNode node : network.getNodeList()) {
+ if(isHidden(node, networkView))
+ continue;
+
List> list;
if(isList)
list = network.getRow(node).getList(attribute, type);
@@ -234,18 +262,12 @@ private Map> computeClustersFromColumn() {
list = Collections.singletonList(network.getRow(node).get(attribute, type));
for(Object o : list) {
- if(o == null)
- continue;
- String key = String.valueOf(o).trim();
- if(key.isEmpty())
- continue;
-
- Collection cluster = clusters.get(key);
- if(cluster == null) {
- cluster = new HashSet<>();
- clusters.put(key, cluster);
+ if(o != null) {
+ String key = String.valueOf(o).trim();
+ if(!key.isEmpty()) {
+ clusters.computeIfAbsent(key, k -> new HashSet<>()).add(node);
+ }
}
- cluster.add(node);
}
}
return clusters;
@@ -274,12 +296,38 @@ private void limitClusters(Map> clusters, int maxClust
}
private Collection getUnclusteredNodes(Map> clusters) {
- CyNetwork network = params.getNetworkView().getModel();
+ CyNetworkView networkView = params.getNetworkView();
+ CyNetwork network = networkView.getModel();
Set nodes = new HashSet<>(network.getNodeList());
for(Collection cluster : clusters.values()) {
nodes.removeAll(cluster);
}
+
+ // filter out hidden nodes
+ nodes.removeIf(node -> isHidden(node, networkView));
return nodes;
}
+
+
+ private static boolean isHidden(View nodeView) {
+ if(nodeView == null)
+ return false;
+ return nodeView.getVisualProperty(BasicVisualLexicon.NODE_VISIBLE) == Boolean.FALSE;
+ }
+
+ private static boolean isHidden(CyNode node, CyNetworkView networkView) {
+ View nodeView = networkView.getNodeView(node);
+ return isHidden(nodeView);
+ }
+ private static boolean hasHiddenNodes(CyNetworkView view) {
+ return view.getNodeViews().stream().anyMatch(CreateAnnotationSetTask::isHidden);
+ }
+
+ private static Collection getVisibleNodes(CyNetworkView view) {
+ return view.getNodeViews().stream()
+ .filter(nv -> !isHidden(nv))
+ .map(nv -> nv.getModel())
+ .collect(Collectors.toList());
+ }
}
diff --git a/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/CreateSubnetworkTask.java b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/CreateSubnetworkTask.java
new file mode 100644
index 0000000..4da51e0
--- /dev/null
+++ b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/CreateSubnetworkTask.java
@@ -0,0 +1,159 @@
+package org.baderlab.autoannotate.internal.task;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.cytoscape.model.CyColumn;
+import org.cytoscape.model.CyEdge;
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.model.CyNode;
+import org.cytoscape.model.CyRow;
+import org.cytoscape.model.CyTable;
+import org.cytoscape.model.VirtualColumnInfo;
+import org.cytoscape.model.subnetwork.CyRootNetworkManager;
+import org.cytoscape.model.subnetwork.CySubNetwork;
+import org.cytoscape.work.AbstractTask;
+import org.cytoscape.work.ObservableTask;
+import org.cytoscape.work.TaskMonitor;
+
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+
+public class CreateSubnetworkTask extends AbstractTask implements ObservableTask {
+
+ @Inject private CyRootNetworkManager rootNetMgr;
+
+ private final CyNetwork parentNetwork;
+ private final Collection nodes;
+ private CySubNetwork resultNetwork;
+
+
+ public interface Factory {
+ CreateSubnetworkTask create(CyNetwork parentNetwork, Collection nodes);
+ }
+
+ @Inject
+ public CreateSubnetworkTask(@Assisted CyNetwork parentNetwork, @Assisted Collection nodes) {
+ this.parentNetwork = parentNetwork;
+ this.nodes = nodes;
+ }
+
+ @Override
+ public void run(TaskMonitor tm) {
+ if (parentNetwork == null) {
+ tm.showMessage(TaskMonitor.Level.ERROR, "Source network must be specified.");
+ return;
+ }
+
+ tm.setProgress(0.2);
+
+ // create subnetwork and add selected nodes and appropriate edges
+ final CySubNetwork newNet = rootNetMgr.getRootNetwork(parentNetwork).addSubNetwork();
+
+ //We need to cpy the columns to local tables, since copying them to default table will duplicate the virtual columns.
+ addColumns(parentNetwork.getTable(CyNode.class, CyNetwork.LOCAL_ATTRS), newNet.getTable(CyNode.class, CyNetwork.LOCAL_ATTRS));
+ addColumns(parentNetwork.getTable(CyEdge.class, CyNetwork.LOCAL_ATTRS), newNet.getTable(CyEdge.class, CyNetwork.LOCAL_ATTRS) );
+ addColumns(parentNetwork.getTable(CyNetwork.class, CyNetwork.LOCAL_ATTRS), newNet.getTable(CyNetwork.class, CyNetwork.LOCAL_ATTRS));
+
+ tm.setProgress(0.3);
+
+ for(CyNode node : nodes) {
+ newNet.addNode(node);
+ cloneRow(parentNetwork.getRow(node), newNet.getRow(node));
+ //Set rows and edges to not selected state to avoid conflicts with table browser
+ newNet.getRow(node).set(CyNetwork.SELECTED, false);
+ }
+
+ tm.setProgress(0.4);
+
+ for (final CyEdge edge : getEdges(parentNetwork, nodes)) {
+ newNet.addEdge(edge);
+ cloneRow(parentNetwork.getRow(edge), newNet.getRow(edge));
+ //Set rows and edges to not selected state to avoid conflicts with table browser
+ newNet.getRow(edge).set(CyNetwork.SELECTED, false);
+ }
+
+ tm.setProgress(0.5);
+
+ newNet.getRow(newNet).set(CyNetwork.NAME, getNetworkName());
+
+ resultNetwork = newNet;
+ tm.setProgress(1.0);
+ }
+
+ private void addColumns(CyTable parentTable, CyTable subTable) {
+ List colsToAdd = new ArrayList();
+
+ for (CyColumn col: parentTable.getColumns())
+ if (subTable.getColumn(col.getName()) == null)
+ colsToAdd.add( col );
+
+ for (CyColumn col: colsToAdd) {
+ VirtualColumnInfo colInfo = col.getVirtualColumnInfo();
+ if (colInfo.isVirtual())
+ addVirtualColumn(col, subTable);
+ else
+ copyColumn(col, subTable);
+ }
+ }
+
+ private void addVirtualColumn (CyColumn col, CyTable subTable){
+ VirtualColumnInfo colInfo = col.getVirtualColumnInfo();
+ CyColumn checkCol= subTable.getColumn(col.getName());
+
+ if (checkCol == null)
+ subTable.addVirtualColumn(col.getName(), colInfo.getSourceColumn(), colInfo.getSourceTable(),
+ colInfo.getTargetJoinKey(), col.isImmutable());
+
+ else
+ if (!checkCol.getVirtualColumnInfo().isVirtual() ||
+ !checkCol.getVirtualColumnInfo().getSourceTable().equals(colInfo.getSourceTable()) ||
+ !checkCol.getVirtualColumnInfo().getSourceColumn().equals(colInfo.getSourceColumn()))
+ subTable.addVirtualColumn(col.getName(), colInfo.getSourceColumn(), colInfo.getSourceTable(),
+ colInfo.getTargetJoinKey(), col.isImmutable());
+ }
+
+ private void copyColumn(CyColumn col, CyTable subTable) {
+ if (List.class.isAssignableFrom(col.getType()))
+ subTable.createListColumn(col.getName(), col.getListElementType(), false);
+ else
+ subTable.createColumn(col.getName(), col.getType(), false);
+ }
+
+ private void cloneRow(final CyRow from, final CyRow to) {
+ for (final CyColumn column : from.getTable().getColumns()){
+ if (!column.getVirtualColumnInfo().isVirtual())
+ to.set(column.getName(), from.getRaw(column.getName()));
+ }
+ }
+
+ private String getNetworkName() {
+ return "AutoAnnotate_Temp";
+ }
+
+ /**
+ * Returns all edges that connect the selected nodes.
+ */
+ private static Set getEdges(CyNetwork net, Collection nodes) {
+ Set edges = new HashSet();
+
+ for (final CyNode n1 : nodes) {
+ for (final CyNode n2 : nodes)
+ edges.addAll(net.getConnectingEdgeList(n1, n2, CyEdge.Type.ANY));
+ }
+
+ return edges;
+ }
+
+ @Override
+ public R getResults(Class extends R> type) {
+ if(CyNetwork.class.equals(type)) {
+ return type.cast(resultNetwork);
+ }
+ return null;
+ }
+
+}
diff --git a/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/RunClusterMakerTaskFactory.java b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/RunClusterMakerTaskFactory.java
index 0e8d4d5..fc00e13 100644
--- a/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/RunClusterMakerTaskFactory.java
+++ b/AutoAnnotate/src/main/java/org/baderlab/autoannotate/internal/task/RunClusterMakerTaskFactory.java
@@ -1,11 +1,10 @@
package org.baderlab.autoannotate.internal.task;
-import java.util.Objects;
-
import javax.annotation.Nullable;
import org.baderlab.autoannotate.internal.model.ClusterAlgorithm;
import org.cytoscape.command.CommandExecutorTaskFactory;
+import org.cytoscape.model.CyNetwork;
import org.cytoscape.model.CyTable;
import org.cytoscape.work.TaskFactory;
import org.cytoscape.work.TaskIterator;
@@ -19,16 +18,21 @@ public class RunClusterMakerTaskFactory implements TaskFactory {
@Inject private CommandExecutorTaskFactory commandTaskFactory;
- private final AnnotationSetTaskParamters params;
+ private final ClusterAlgorithm algorithm;
+ private final CyNetwork network;
+ private final String edgeAttribute;
private final Double cutoff;
public static interface Factory {
- RunClusterMakerTaskFactory create(AnnotationSetTaskParamters params, @Nullable Double cutoff);
+ RunClusterMakerTaskFactory create(CyNetwork network, ClusterAlgorithm algorithm, @Nullable String edgeAttribute, @Nullable Double cutoff);
}
@AssistedInject
- public RunClusterMakerTaskFactory(@Assisted AnnotationSetTaskParamters params, @Assisted @Nullable Double cutoff) {
- this.params = Objects.requireNonNull(params);
+ public RunClusterMakerTaskFactory(@Assisted CyNetwork network, @Assisted ClusterAlgorithm algorithm,
+ @Assisted @Nullable String edgeAttribute, @Assisted @Nullable Double cutoff) {
+ this.network = network;
+ this.algorithm = algorithm;
+ this.edgeAttribute = edgeAttribute;
this.cutoff = cutoff;
}
@@ -43,26 +47,24 @@ public TaskIterator createTaskIterator(TaskObserver taskObserver) {
* MKTODO if the command gets any more complex then create a ClusterMakerCommandBuilder
*/
public String getClusterCommand() {
- ClusterAlgorithm alg = params.getClusterAlgorithm();
String columnName = getColumnName();
+ String command = algorithm.getCommandName();
+ Long suid = network.getSUID();
- String command = alg.getCommandName();
- Long suid = params.getNetworkView().getModel().getSUID();
+ StringBuilder sb = new StringBuilder("cluster ").append(command)
+ .append(" network=\"SUID:").append(suid).append('"')
+ .append(" clusterAttribute=\"").append(columnName).append('"');
+ if(algorithm.isEdgeAttributeRequired())
+ sb.append(" attribute=\"").append(edgeAttribute).append('"');
+ if(algorithm.isEdgeAttributeRequired() && cutoff != null)
+ sb.append(" edgeCutOff=\"").append(cutoff).append('"');
- if(alg.isEdgeAttributeRequired() && cutoff != null) {
- return String.format("cluster %s network=\"SUID:%d\" clusterAttribute=\"%s\" attribute=\"%s\" edgeCutOff=\"%s\"", command, suid, columnName, params.getClusterMakerEdgeAttribute(), cutoff);
- }
- else if(alg.isEdgeAttributeRequired()) {
- return String.format("cluster %s network=\"SUID:%d\" clusterAttribute=\"%s\" attribute=\"%s\"", command, suid, columnName, params.getClusterMakerEdgeAttribute());
- }
- else {
- return String.format("cluster %s network=\"SUID:%d\" clusterAttribute=\"%s\"", command, suid, columnName);
- }
+ return sb.toString();
}
private String getColumnName() {
- CyTable table = params.getNetworkView().getModel().getDefaultNodeTable();
- final String originalName = params.getClusterAlgorithm().getColumnName();
+ CyTable table = network.getDefaultNodeTable();
+ final String originalName = algorithm.getColumnName();
String name = originalName;
int suffix = 2;
@@ -74,7 +76,10 @@ private String getColumnName() {
public String getNetworkCommand() {
- return "cluster getnetworkcluster algorithm=" + params.getClusterAlgorithm().getCommandName();
+ return new StringBuilder("cluster getnetworkcluster")
+ .append(" network=\"SUID:").append(network.getSUID()).append('"')
+ .append(" algorithm=").append(algorithm.getCommandName())
+ .toString();
}