Author: scooter
Date: 2011-07-08 23:02:08 -0700 (Fri, 08 Jul 2011)
New Revision: 26128

Added:
   
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmedoid/
   
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmedoid/KMCluster.java
   
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmedoid/KMedoidCluster.java
Modified:
   
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmeans/KCluster.java
   
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmeans/KMeansCluster.java
Log:
Added kmedoid


Modified: 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmeans/KCluster.java
===================================================================
--- 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmeans/KCluster.java
  2011-07-08 23:35:01 UTC (rev 26127)
+++ 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmeans/KCluster.java
  2011-07-09 06:02:08 UTC (rev 26128)
@@ -155,9 +155,11 @@
 
                // Sort the appropriate list (Nodes or Attributes)
                Integer rowOrder[] = matrix.indexSort(clusters, 
clusters.length);
+               /*
     for (int i = 0; i < rowOrder.length; i++) {
       // logger.debug(""+i+": "+matrix.getRowLabel(rowOrder[i].intValue()));
     }
+               */
 
                // Update the network attributes
                EisenCluster.updateAttributes(matrix, attrList, 
weightAttributes, rowOrder, "kmeans", false, false);
@@ -338,7 +340,7 @@
        return ifound;
        }
 
-       private void getClusterMeans(int nClusters, Matrix data, Matrix cdata, 
int[] clusterid) {
+       public static void getClusterMeans(int nClusters, Matrix data, Matrix 
cdata, int[] clusterid) {
 
                double[][]cmask = new double[nClusters][cdata.nColumns()];
 

Modified: 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmeans/KMeansCluster.java
===================================================================
--- 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmeans/KMeansCluster.java
     2011-07-08 23:35:01 UTC (rev 26127)
+++ 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmeans/KMeansCluster.java
     2011-07-09 06:02:08 UTC (rev 26128)
@@ -160,7 +160,7 @@
                // Whether or not to only cluster selected nodes/edges
                clusterProperties.add(new Tunable("selectedOnly",
                                                  "Only use selected 
nodes/edges for cluster",
-                                                 Tunable.BOOLEAN, new 
Boolean(true)));
+                                                 Tunable.BOOLEAN, new 
Boolean(false)));
 
                // Whether or not to cluster attributes as well as nodes
                clusterProperties.add(new Tunable("clusterAttributes",

Added: 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmedoid/KMCluster.java
===================================================================
--- 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmedoid/KMCluster.java
                                (rev 0)
+++ 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmedoid/KMCluster.java
        2011-07-09 06:02:08 UTC (rev 26128)
@@ -0,0 +1,315 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2008 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package clusterMaker.algorithms.kmedoid;
+
+import java.awt.GridLayout;
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Random;
+import javax.swing.JPanel;
+
+// Cytoscape imports
+import cytoscape.Cytoscape;
+import cytoscape.CyNode;
+import cytoscape.data.CyAttributes;
+import cytoscape.layout.Tunable;
+import cytoscape.logger.CyLogger;
+import cytoscape.task.TaskMonitor;
+import cytoscape.groups.CyGroup;
+import cytoscape.groups.CyGroupManager;
+
+// clusterMaker imports
+import clusterMaker.ClusterMaker;
+import clusterMaker.algorithms.kmeans.KCluster;
+import clusterMaker.algorithms.hierarchical.DistanceMetric;
+import clusterMaker.algorithms.hierarchical.EisenCluster;
+import clusterMaker.algorithms.hierarchical.Matrix;
+
+public class KMCluster {
+       CyLogger logger;
+       TaskMonitor monitor;
+       String weightAttributes[] = null;
+       DistanceMetric metric;
+       boolean createGroups = false;
+       boolean ignoreMissing = false;
+       boolean selectedOnly = false;
+       boolean debug = true;
+       Random random = null;
+
+       public KMCluster(String weightAttributes[], DistanceMetric metric, 
CyLogger log, TaskMonitor monitor) {
+               this.logger = log;
+               this.weightAttributes = weightAttributes;
+               this.metric = metric;
+               this.monitor = monitor;
+               resetAttributes();
+       }
+
+       public void setCreateGroups(boolean val) { createGroups = val; }
+       public void setIgnoreMissing(boolean val) { ignoreMissing = val; }
+       public void setSelectedOnly(boolean val) { selectedOnly = val; }
+       public void setDebug(boolean val) { debug = val; }
+
+       public String cluster(int nClusters, int nIterations, boolean 
transpose) {
+               String keyword = "GENE";
+               if (transpose) keyword = "ARRY";
+               debug = true;
+
+               for (int att = 0; att < weightAttributes.length; att++)
+                       if (debug)
+                               logger.debug("Attribute: 
'"+weightAttributes[att]+"'");
+
+               if (monitor != null) 
+                       monitor.setStatus("Creating distance matrix");
+
+               // Create the matrix
+               Matrix matrix = new Matrix(weightAttributes, transpose, 
ignoreMissing, selectedOnly);
+               logger.info("cluster matrix has "+matrix.nRows()+" rows");
+
+               // Create a weight vector of all ones (we don't use individual 
weighting, yet)
+               matrix.setUniformWeights();
+
+               int[] clusters = new int[matrix.nRows()];
+
+               if (monitor != null) 
+                       monitor.setStatus("Clustering...");
+
+               // Cluster
+               int ifound = kmedoid(nClusters, nIterations, matrix, metric, 
clusters);
+
+               HashMap<String,List<CyNode>> groupMap = new 
HashMap<String,List<CyNode>>();
+               ArrayList<String> attrList = new 
ArrayList<String>(matrix.nRows());
+               // Create the attribute list
+               for (int cluster = 0; cluster < nClusters; cluster++) {
+                       List<CyNode> memberList = new ArrayList<CyNode>();
+                       for (int i = 0; i < matrix.nRows(); i++) {
+                               if (clusters[i] == cluster) {
+                                       
attrList.add(matrix.getRowLabel(i)+"\t"+cluster);
+                                       if (debug)
+                                               
logger.debug(matrix.getRowLabel(i)+"\t"+cluster);
+                                       memberList.add(matrix.getRowNode(i));
+                               }
+                       }
+                       groupMap.put("Cluster_"+cluster, memberList);
+               }
+
+               if (!matrix.isTransposed()) {
+                       if (monitor != null) 
+                               monitor.setStatus("Creating groups");
+
+                       List<String> groupNames = new ArrayList<String>();
+
+                       if (createGroups) {
+                               // Create our groups
+                               CyGroup group = null;
+                               for (String clusterName: groupMap.keySet()) {
+                                       List<CyNode> memberList = 
groupMap.get(clusterName);
+                                       groupNames.add(clusterName);
+
+                                       if (debug)
+                                               logger.debug("Creating group: 
"+clusterName);
+
+                                       // Create the group
+                                       group = 
CyGroupManager.createGroup(clusterName, memberList, null);
+                                       if (group != null) 
+                                               
CyGroupManager.setGroupViewer(group, "namedSelection", 
Cytoscape.getCurrentNetworkView(), false);
+                               }
+                               CyGroupManager.setGroupViewer(group, 
"namedSelection", Cytoscape.getCurrentNetworkView(), true);
+                       }
+
+                       CyAttributes netAttr = Cytoscape.getNetworkAttributes();
+                       String netID = 
Cytoscape.getCurrentNetwork().getIdentifier();
+                       netAttr.setListAttribute(netID, 
ClusterMaker.GROUP_ATTRIBUTE, groupNames);
+               }
+
+               // Sort the appropriate list (Nodes or Attributes)
+               Integer rowOrder[] = matrix.indexSort(clusters, 
clusters.length);
+               /*
+    for (int i = 0; i < rowOrder.length; i++) {
+      logger.debug(""+i+": "+matrix.getRowLabel(rowOrder[i].intValue()));
+    }
+               */
+
+               // Update the network attributes
+               EisenCluster.updateAttributes(matrix, attrList, 
weightAttributes, rowOrder, "kmedoid", false, false);
+
+               return "Complete";
+       }
+
+       public void resetAttributes() {
+               // Update the network attribute "HierarchicalCluster" and make 
it hidden
+               CyAttributes netAttr = Cytoscape.getNetworkAttributes();
+               String netID = Cytoscape.getCurrentNetwork().getIdentifier();
+
+               // See if we have any old groups in this network
+               if (netAttr.hasAttribute(netID, ClusterMaker.GROUP_ATTRIBUTE)) {
+                       List<String>clList = 
(List<String>)netAttr.getListAttribute(netID, ClusterMaker.GROUP_ATTRIBUTE);
+                       for (String groupName: clList) {
+                               CyGroup group = 
CyGroupManager.findGroup(groupName);
+                               if (group != null)
+                                       CyGroupManager.removeGroup(group);
+                       }
+                       netAttr.deleteAttribute(netID, 
ClusterMaker.GROUP_ATTRIBUTE);
+               }
+
+               // Clear of the other attributes
+               if (netAttr.hasAttribute(netID, 
ClusterMaker.ARRAY_ORDER_ATTRIBUTE))
+                       netAttr.deleteAttribute(netID, 
ClusterMaker.ARRAY_ORDER_ATTRIBUTE);
+               if (netAttr.hasAttribute(netID, 
ClusterMaker.NODE_ORDER_ATTRIBUTE))
+                       netAttr.deleteAttribute(netID, 
ClusterMaker.NODE_ORDER_ATTRIBUTE);
+               if (netAttr.hasAttribute(netID, 
ClusterMaker.CLUSTER_ATTR_ATTRIBUTE))
+                       netAttr.deleteAttribute(netID, 
ClusterMaker.CLUSTER_ATTR_ATTRIBUTE);
+               if (netAttr.hasAttribute(netID, 
ClusterMaker.CLUSTER_NODE_ATTRIBUTE))
+                       netAttr.deleteAttribute(netID, 
ClusterMaker.CLUSTER_NODE_ATTRIBUTE);
+               if (netAttr.hasAttribute(netID, 
ClusterMaker.CLUSTER_EDGE_ATTRIBUTE))
+                       netAttr.deleteAttribute(netID, 
ClusterMaker.CLUSTER_EDGE_ATTRIBUTE);
+               if (netAttr.hasAttribute(netID, 
ClusterMaker.CLUSTER_TYPE_ATTRIBUTE))
+                       netAttr.deleteAttribute(netID, 
ClusterMaker.CLUSTER_TYPE_ATTRIBUTE);
+       }
+
+       public int kmedoid(int nClusters, int nIterations, Matrix matrix, 
DistanceMetric metric, int[] clusterId) {
+
+               if (monitor != null)
+                       monitor.setPercentCompleted(0);
+
+               int iteration = 0;
+
+               // Start by calculating the pairwise distances
+               double[][] distances = new 
double[matrix.nRows()][matrix.nRows()];
+               for (int i = 0; i < matrix.nRows(); i++) {
+                       for (int j = i; j < matrix.nRows(); j++) {
+                               distances[i][j] = metric.getMetric(matrix, 
matrix, matrix.getWeights(), i, j);
+                       }
+               }
+
+               int[] centers = chooseRandomElementsAsCenters(matrix, 
nClusters);
+               int[] oldCenters = null;
+               // outputCenters(centers);
+
+               while (centersChanged(oldCenters, centers)) {
+                       oldCenters = centers;
+                       // outputClusterId(clusterId);
+                       assignPointsToClosestCenter(oldCenters, distances, 
clusterId);
+                       centers = calculateCenters(nClusters, matrix, metric, 
clusterId);
+                       // outputCenters(centers);
+
+                       if (iteration++ >= nIterations) break;
+               }
+
+               // System.out.println("ifound = "+ifound+", error = "+error);
+       return 1;
+       }
+
+       private int[] chooseRandomElementsAsCenters(Matrix matrix, int 
nClusters) {
+               int[] centers = new int[nClusters];
+
+               for (int i = 0; i < nClusters; i++) {
+                       centers[i] = (int) Math.floor(Math.random() * 
matrix.nRows());
+               }
+               return centers;
+       }
+
+       private void assignPointsToClosestCenter(int[] centers, double[][] 
distances, int[] clusterId) {
+               for (int row = 0; row < distances.length; row++) {
+                       double minDistance = Double.MAX_VALUE;
+                       for (int cluster = 0; cluster < centers.length; 
cluster++) {
+                               double distance = 
distances[row][centers[cluster]];
+                               if (distance < minDistance) {
+                                       clusterId[row] = cluster;
+                                       minDistance = distance;
+                               }
+                       }
+               }
+       } 
+
+       private int[] calculateCenters(int nClusters, Matrix matrix, 
DistanceMetric metric, int[] clusterId) {
+               int[] newCenters = new int[nClusters];
+               Matrix cData = new Matrix(nClusters, matrix.nRows());
+
+               // Calculate all of the cluster centers
+               KCluster.getClusterMeans(nClusters, matrix, cData, clusterId);
+
+               // For each cluster, find the closest row
+               for (int cluster = 0; cluster < nClusters; cluster++) {
+                       newCenters[cluster] = findMedoid(matrix, cData, 
cluster, clusterId);
+               }
+               return newCenters;
+       }
+
+       private int findMedoid(Matrix matrix, Matrix cdata, int cluster, int[] 
clusterid) {
+               double minDistance = Double.MAX_VALUE;
+               int medoid = -1;
+               for (int row = 0; row < matrix.nRows(); row++) {
+                       if (clusterid[row] == cluster) {
+                               double distance = metric.getMetric(matrix, 
cdata, matrix.getWeights(), row, cluster);
+                               if (distance < minDistance)
+                                       medoid = row;
+                       }
+               }
+               return medoid;
+       }
+
+       private boolean centersChanged(int[] oldCenters, int[] centers) {
+               if (oldCenters == null || centers == null) return true;
+
+               for (int i = 0; i < oldCenters.length; i++) {
+                       if (oldCenters[i] != centers[i]) return true;
+               }
+               return false;
+       }
+
+       private void outputCenters(int[] centers) {
+               System.out.println("Centroid points: ");
+               for (int i = 0; i < centers.length; i++) {
+                       System.out.println(" "+i+": "+centers[i]);
+               }
+       }
+
+       private void outputClusterId(int[] clusterId) {
+               System.out.println("Cluster IDs: ");
+               for (int i = 0; i < clusterId.length; i++) {
+                       System.out.println(" "+i+": "+clusterId[i]);
+               }
+       }
+
+       private double uniform() {
+               if (random == null) {
+                       Date date = new Date();
+                       random = new Random(date.getTime());
+               }
+               return random.nextDouble();
+       }
+}

Added: 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmedoid/KMedoidCluster.java
===================================================================
--- 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmedoid/KMedoidCluster.java
                           (rev 0)
+++ 
csplugins/trunk/ucsf/scooter/clusterMaker/src/clusterMaker/algorithms/kmedoid/KMedoidCluster.java
   2011-07-09 06:02:08 UTC (rev 26128)
@@ -0,0 +1,282 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2008 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package clusterMaker.algorithms.kmedoid;
+
+import java.awt.GridLayout;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import javax.swing.JPanel;
+
+// Cytoscape imports
+import cytoscape.Cytoscape;
+import cytoscape.data.CyAttributes;
+import cytoscape.layout.Tunable;
+import cytoscape.logger.CyLogger;
+import cytoscape.task.TaskMonitor;
+
+import clusterMaker.algorithms.ClusterAlgorithm;
+import clusterMaker.algorithms.AbstractClusterAlgorithm;
+import clusterMaker.algorithms.hierarchical.DistanceMetric;
+import clusterMaker.algorithms.hierarchical.EisenCluster;
+import clusterMaker.ui.ClusterViz;
+import clusterMaker.ui.KnnView;
+
+// clusterMaker imports
+
+public class KMedoidCluster extends AbstractClusterAlgorithm {
+       /**
+        * Linkage types
+        */
+       DistanceMetric[] distanceTypes = { DistanceMetric.EUCLIDEAN,
+                                          DistanceMetric.CITYBLOCK,
+                                          DistanceMetric.CORRELATION,
+                                          DistanceMetric.ABS_CORRELATION,
+                                          
DistanceMetric.UNCENTERED_CORRELATION,
+                                          
DistanceMetric.ABS_UNCENTERED_CORRELATION,
+                                          DistanceMetric.SPEARMANS_RANK,
+                                          DistanceMetric.KENDALLS_TAU,
+                                          DistanceMetric.VALUE_IS_CORRELATION 
};
+       String[] attributeArray = new String[1];
+
+       int kNumber = 0;
+       int rNumber = 0;
+       DistanceMetric distanceMetric = DistanceMetric.EUCLIDEAN;
+       boolean clusterAttributes = false;
+       boolean createGroups = true;
+       boolean ignoreMissing = false;
+       boolean selectedOnly = false;
+       String dataAttributes = null;
+       TaskMonitor monitor = null;
+       CyLogger logger = null;
+       KnnView knnView = null;
+
+       public KMedoidCluster() {
+               super();
+               logger = CyLogger.getLogger(KMedoidCluster.class);
+               initializeProperties();
+       }
+
+       public String getShortName() {return "kmedoid";};
+       public String getName() {return "K-Medoid cluster";};
+
+       public JPanel getSettingsPanel() {
+               // Everytime we ask for the panel, we want to update our 
attributes
+               Tunable attributeTunable = 
clusterProperties.get("attributeList");
+               attributeArray = EisenCluster.getAllAttributes();
+               attributeTunable.setLowerBound((Object)attributeArray);
+
+               // We also want to update the number our "guestimate" for k
+               double nodeCount = 
(double)Cytoscape.getCurrentNetwork().getNodeCount();
+               Tunable kTunable = clusterProperties.get("knumber");
+               if (selectedOnly) {
+                       int selNodes = 
Cytoscape.getCurrentNetwork().getSelectedNodes().size();
+                       if (selNodes > 0) nodeCount = (double)selNodes;
+               }
+
+               double kinit = Math.sqrt(nodeCount/2);
+               if (kinit > 1)
+                       kTunable.setValue((int)kinit);
+               else
+                       kTunable.setValue(1);
+
+               return clusterProperties.getTunablePanel();
+       }
+
+       public ClusterViz getVisualizer() {
+               // if (knnView == null)
+               //      knnView = new KnnView();
+
+               return new KnnView();
+       }
+
+       public void initializeProperties() {
+               super.initializeProperties();
+
+               /**
+                * Tuning values
+                */
+
+               // K
+               clusterProperties.add(new Tunable("knumber",
+                                                 "Number of clusters",
+                                                 Tunable.INTEGER, new 
Integer(10),
+                                                 (Object)kNumber, 
(Object)null, 0));
+
+               // Number of iterations
+               clusterProperties.add(new Tunable("iterations",
+                                                 "Number of iterations",
+                                                 Tunable.INTEGER, new 
Integer(10),
+                                                 (Object)rNumber, 
(Object)null, 0));
+
+               // The distance metric to use
+               clusterProperties.add(new Tunable("dMetric",
+                                                 "Distance Metric",
+                                                 Tunable.LIST, new Integer(0),
+                                                 (Object)distanceTypes, 
(Object)null, 0));
+
+               clusterProperties.add(new Tunable("attributeListGroup",
+                                                 "Source for array data",
+                                                 Tunable.GROUP, new 
Integer(1)));
+
+               // The attribute to use to get the weights
+               attributeArray = EisenCluster.getAllAttributes();
+               clusterProperties.add(new Tunable("attributeList",
+                                                 "Array sources",
+                                                 Tunable.LIST, "",
+                                                 (Object)attributeArray, 
(Object)null, Tunable.MULTISELECT));
+
+               // Whether or not to only cluster selected nodes/edges
+               clusterProperties.add(new Tunable("selectedOnly",
+                                                 "Only use selected 
nodes/edges for cluster",
+                                                 Tunable.BOOLEAN, new 
Boolean(false)));
+
+               // Whether or not to cluster attributes as well as nodes
+               clusterProperties.add(new Tunable("clusterAttributes",
+                                                 "Cluster attributes as well 
as nodes", 
+                                                 Tunable.BOOLEAN, new 
Boolean(false)));
+
+               // For expression data, we might want to exclude missing data
+               clusterProperties.add(new Tunable("ignoreMissing",
+                                                 "Ignore nodes with no data",
+                                                 Tunable.BOOLEAN, new 
Boolean(false)));
+
+               // Whether or not to create groups
+               clusterProperties.add(new Tunable("createGroups",
+                                                 "Create groups from 
clusters", 
+                                                 Tunable.BOOLEAN, new 
Boolean(true)));
+
+               clusterProperties.initializeProperties();
+               updateSettings(true);
+       }
+
+       public void updateSettings() {
+               updateSettings(false);
+       }
+
+       public void updateSettings(boolean force) {
+               clusterProperties.updateValues();
+               super.updateSettings(force);
+
+               Tunable t = clusterProperties.get("knumber");
+               if ((t != null) && (t.valueChanged() || force))
+                       kNumber = ((Integer) t.getValue()).intValue();
+
+               t = clusterProperties.get("iterations");
+               if ((t != null) && (t.valueChanged() || force))
+                       rNumber = ((Integer) t.getValue()).intValue();
+
+               t = clusterProperties.get("dMetric");
+               if ((t != null) && (t.valueChanged() || force))
+                       distanceMetric = distanceTypes[((Integer) 
t.getValue()).intValue()];
+
+               t = clusterProperties.get("clusterAttributes");
+               if ((t != null) && (t.valueChanged() || force))
+                       clusterAttributes = ((Boolean) 
t.getValue()).booleanValue();
+
+               t = clusterProperties.get("selectedOnly");
+               if ((t != null) && (t.valueChanged() || force))
+                       selectedOnly = ((Boolean) t.getValue()).booleanValue();
+
+               t = clusterProperties.get("ignoreMissing");
+               if ((t != null) && (t.valueChanged() || force))
+                       ignoreMissing = ((Boolean) t.getValue()).booleanValue();
+
+               t = clusterProperties.get("createGroups");
+               if ((t != null) && (t.valueChanged() || force))
+                       createGroups = ((Boolean) t.getValue()).booleanValue();
+
+               t = clusterProperties.get("attributeList");
+               if ((t != null) && (t.valueChanged() || force)) {
+                       dataAttributes = (String) t.getValue();
+               }
+       }
+
+       public void doCluster(TaskMonitor monitor) {
+               this.monitor = monitor;
+               // Sanity check all of our settings
+               if (debug)
+                       logger.debug("Performing k-medoid cluster with 
k="+kNumber+" using "+distanceMetric+" and attributes: "+dataAttributes);
+
+               if (dataAttributes == null || dataAttributes.length() == 0) {
+                       if (monitor != null) {
+                               monitor.setException(null, "Error: no attribute 
list selected");
+                               logger.warning("Must have an attribute list to 
use for cluster weighting");
+                       } else
+                               logger.error("Must have an attribute list to 
use for cluster weighting");
+                       return;
+               }
+
+               // Get our attributes we're going to use for the cluster
+               String attributeArray[] = getAttributeArray(dataAttributes);
+               // To make debugging easier, sort the attribute array
+               Arrays.sort(attributeArray);
+
+               KMCluster algorithm = new KMCluster(attributeArray, 
distanceMetric, logger, monitor);
+               algorithm.setCreateGroups(createGroups);
+               algorithm.setIgnoreMissing(ignoreMissing);
+               algorithm.setSelectedOnly(selectedOnly);
+               algorithm.setDebug(debug);
+
+               // Cluster the attributes, if requested
+               if (clusterAttributes && attributeArray.length > 1) {
+                       if (monitor != null)
+                               monitor.setStatus("Clustering attributes");
+                       algorithm.cluster(kNumber, rNumber, true);
+               }
+
+               // Cluster the nodes
+               if (monitor != null)
+                       monitor.setStatus("Clustering nodes");
+               algorithm.cluster(kNumber, rNumber, false);
+               if (monitor != null)
+                       monitor.setStatus("Clustering complete");
+
+               // Tell any listeners that we're done
+               pcs.firePropertyChange(ClusterAlgorithm.CLUSTER_COMPUTED, null, 
this);
+       }
+
+       public boolean isAvailable() {
+               return EisenCluster.isAvailable(getShortName());
+       }
+
+       private String[] getAttributeArray(String dataAttributes) {
+               String indices[] = dataAttributes.split(",");
+               String selectedAttributes[] = new String[indices.length];
+               for (int i = 0; i < indices.length; i++) {
+                       selectedAttributes[i] = 
attributeArray[Integer.parseInt(indices[i])];
+               }
+               return selectedAttributes;
+       }
+}

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

Reply via email to