X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fanalysis%2FAverageDistanceEngine.java;h=f4d69d5cb4b3e592df21768a2ada643d983ce886;hb=d27e73b6519abfe5922ae716efe9a8dcc58c7751;hp=a3301706a1cf1df72c1d0623035c1a031b9161b8;hpb=8fbc01654883e68f8843ad6632efaabfaf21692e;p=jalview.git diff --git a/src/jalview/analysis/AverageDistanceEngine.java b/src/jalview/analysis/AverageDistanceEngine.java index a330170..f4d69d5 100644 --- a/src/jalview/analysis/AverageDistanceEngine.java +++ b/src/jalview/analysis/AverageDistanceEngine.java @@ -20,7 +20,9 @@ */ package jalview.analysis; +import java.util.ArrayList; import java.util.BitSet; +import java.util.List; import java.util.Vector; import jalview.datamodel.AlignmentAnnotation; @@ -37,42 +39,110 @@ import jalview.viewmodel.AlignmentViewport; public class AverageDistanceEngine extends TreeEngine { ContactMatrixI cm; + AlignmentViewport av; + AlignmentAnnotation aa; + /** - * compute cosine distance matrix for a given contact matrix and create a UPGMA tree + * compute cosine distance matrix for a given contact matrix and create a + * UPGMA tree + * * @param cm */ - public AverageDistanceEngine(AlignmentViewport av, AlignmentAnnotation aa, ContactMatrixI cm) + public AverageDistanceEngine(AlignmentViewport av, AlignmentAnnotation aa, + ContactMatrixI cm) { - this.av =av; + this.av = av; this.aa = aa; - this.cm=cm; + this.cm = cm; + calculate(cm); + + } + + // 0 - normalised dot product + // 1 - L1 - ie (abs(v_1-v_2)/dim(v)) + // L1 is more rational - since can reason about value of difference, + // normalised dot product might give cleaner clusters, but more difficult to + // understand. + + int mode = 1; + + public void calculate(ContactMatrixI cm) + { + this.cm = cm; node = new Vector(); clusters = new Vector(); distances = new Matrix(new double[cm.getWidth()][cm.getWidth()]); - noseqs=cm.getWidth(); - done = new BitSet(); - for (int i=0;i groupNodes(float threshold) + { + List groups = new ArrayList(); + _groupNodes(groups, getTopNode(), threshold); + return groups; + } + + protected void _groupNodes(List groups, BinaryNode nd, + float threshold) + { + if (nd == null) + { + return; + } + + if ((nd.height / maxheight) > threshold) + { + groups.add(nd); + } + else + { + _groupNodes(groups, nd.left(), threshold); + _groupNodes(groups, nd.right(), threshold); + } + } + + /** + * DOCUMENT ME! + * + * @param nd + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public double findHeight(BinaryNode nd) + { + if (nd == null) + { + return maxheight; + } + + if ((nd.left() == null) && (nd.right() == null)) + { + nd.height = ((BinaryNode) nd.parent()).height + nd.dist; + + if (nd.height > maxheight) + { + return nd.height; + } + else + { + return maxheight; + } + } + else + { + if (nd.parent() != null) + { + nd.height = ((BinaryNode) nd.parent()).height + nd.dist; + } + else + { + maxheight = 0; + nd.height = (float) 0.0; + } + + maxheight = findHeight((BinaryNode) (nd.left())); + maxheight = findHeight((BinaryNode) (nd.right())); + } + + return maxheight; + } + + /** + * Search for leaf nodes below (or at) the given node + * + * @param top2 + * root node to search from + * + * @return + */ + public Vector findLeaves(BinaryNode top2) + { + Vector leaves = new Vector(); + findLeaves(top2, leaves); + return leaves; + } + + /** + * Search for leaf nodes. + * + * @param nd + * root node to search from + * @param leaves + * Vector of leaves to add leaf node objects too. + * + * @return Vector of leaf nodes on binary tree + */ + Vector findLeaves(BinaryNode nd, Vector leaves) + { + if (nd == null) + { + return leaves; + } + + if ((nd.left() == null) && (nd.right() == null)) // Interior node + // detection + { + leaves.addElement(nd); + + return leaves; + } + else + { + /* + * TODO: Identify internal nodes... if (node.isSequenceLabel()) { + * leaves.addElement(node); } + */ + findLeaves(nd.left(), leaves); + findLeaves(nd.right(), leaves); + } + + return leaves; + } + }