import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.BinaryNode;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
*
* @return DOCUMENT ME!
*/
- private static List<SequenceI> _sortByTree(SequenceNode node,
+ private static List<SequenceI> _sortByTree(BinaryNode node,
List<SequenceI> tmp, List<SequenceI> seqset)
{
if (node == null)
return tmp;
}
- SequenceNode left = (SequenceNode) node.left();
- SequenceNode right = (SequenceNode) node.right();
+ BinaryNode left = (BinaryNode) node.left();
+ BinaryNode right = (BinaryNode) node.right();
if ((left == null) && (right == null))
{
- if (!node.isPlaceholder() && (node.element() != null))
+ if (!(node instanceof SequenceNode && ((SequenceNode)node).isPlaceholder()) && (node.element() != null))
{
if (node.element() instanceof SequenceI)
{
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.analysis;
+
+import java.util.BitSet;
+import java.util.Vector;
+
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.BinaryNode;
+import jalview.datamodel.ContactListI;
+import jalview.datamodel.ContactMatrixI;
+import jalview.math.Matrix;
+import jalview.viewmodel.AlignmentViewport;
+
+/**
+ * This class implements distance calculations used in constructing a Average
+ * Distance tree (also known as UPGMA)
+ */
+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
+ * @param cm
+ */
+ public AverageDistanceEngine(AlignmentViewport av, AlignmentAnnotation aa, ContactMatrixI cm)
+ {
+ this.av =av;
+ this.aa = aa;
+ this.cm=cm;
+ node = new Vector<BinaryNode>();
+ clusters = new Vector<BitSet>();
+ distances = new Matrix(new double[cm.getWidth()][cm.getWidth()]);
+ noseqs=cm.getWidth();
+ done = new BitSet();
+ for (int i=0;i<cm.getWidth();i++)
+ {
+ // init the tree engine node for this column
+ BinaryNode cnode = new BinaryNode();
+ cnode.setElement(Integer.valueOf(i));
+ cnode.setName("c"+i);
+ node.addElement(cnode);
+ BitSet bs = new BitSet();
+ bs.set(i);
+ clusters.addElement(bs);
+
+ // compute distance matrix element
+ ContactListI ith=cm.getContactList(i);
+ for (int j=0;j<i;j++)
+ {
+ ContactListI jth = cm.getContactList(j);
+ double prd=0;
+ for (int indx=0;indx<cm.getHeight();indx++)
+ {
+ prd+=ith.getContactAt(indx)*jth.getContactAt(indx);
+ }
+ distances.setValue(i, j, prd);
+ distances.setValue(j, i, prd);
+ }
+ }
+
+ noClus = clusters.size();
+ cluster();
+
+ }
+ /**
+ * Calculates and saves the distance between the combination of cluster(i) and
+ * cluster(j) and all other clusters. An average of the distances from
+ * cluster(i) and cluster(j) is calculated, weighted by the sizes of each
+ * cluster.
+ *
+ * @param i
+ * @param j
+ */
+ @Override
+ protected void findClusterDistance(int i, int j)
+ {
+ int noi = clusters.elementAt(i).cardinality();
+ int noj = clusters.elementAt(j).cardinality();
+
+ // New distances from cluster i to others
+ double[] newdist = new double[noseqs];
+
+ for (int l = 0; l < noseqs; l++)
+ {
+ if ((l != i) && (l != j))
+ {
+ newdist[l] = ((distances.getValue(i, l) * noi)
+ + (distances.getValue(j, l) * noj)) / (noi + noj);
+ }
+ else
+ {
+ newdist[l] = 0;
+ }
+ }
+
+ for (int ii = 0; ii < noseqs; ii++)
+ {
+ distances.setValue(i, ii, newdist[ii]);
+ distances.setValue(ii, i, newdist[ii]);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected double findMinDistance()
+ {
+ double min = Double.MAX_VALUE;
+
+ for (int i = 0; i < (noseqs - 1); i++)
+ {
+ for (int j = i + 1; j < noseqs; j++)
+ {
+ if (!done.get(i) && !done.get(j))
+ {
+ if (distances.getValue(i, j) < min)
+ {
+ mini = i;
+ minj = j;
+
+ min = distances.getValue(i, j);
+ }
+ }
+ }
+ }
+ return min;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void findNewDistances(BinaryNode nodei, BinaryNode nodej,
+ double dist)
+ {
+ double ih = 0;
+ double jh = 0;
+
+ BinaryNode sni = nodei;
+ BinaryNode snj = nodej;
+
+ while (sni != null)
+ {
+ ih = ih + sni.dist;
+ sni = (BinaryNode) sni.left();
+ }
+
+ while (snj != null)
+ {
+ jh = jh + snj.dist;
+ snj = (BinaryNode) snj.left();
+ }
+
+ nodei.dist = ((dist / 2) - ih);
+ nodej.dist = ((dist / 2) - jh);
+ }
+
+}
import jalview.datamodel.SeqCigar;
import jalview.datamodel.SequenceI;
import jalview.datamodel.SequenceNode;
-import jalview.math.MatrixI;
import jalview.viewmodel.AlignmentViewport;
import java.util.BitSet;
import java.util.Vector;
-public abstract class TreeBuilder
+public abstract class TreeBuilder extends TreeEngine
{
public static final String AVERAGE_DISTANCE = "AV";
public static final String NEIGHBOUR_JOINING = "NJ";
- protected Vector<BitSet> clusters;
-
protected SequenceI[] sequences;
public AlignmentView seqData;
- protected BitSet done;
-
- protected int noseqs;
-
- int noClus;
-
- protected MatrixI distances;
-
- protected int mini;
-
- protected int minj;
-
- protected double ri;
-
- protected double rj;
-
- BinaryNode maxdist;
-
- BinaryNode top;
-
- double maxDistValue;
-
- double maxheight;
-
- int ycount;
-
- Vector<SequenceNode> node;
-
private AlignmentView seqStrings;
/**
}
/**
- * DOCUMENT ME!
- *
- * @param nd
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- 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;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param nd
- * DOCUMENT ME!
- */
- void reCount(BinaryNode nd)
- {
- ycount = 0;
- // _lycount = 0;
- // _lylimit = this.node.size();
- _reCount(nd);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param nd
- * DOCUMENT ME!
- */
- void _reCount(BinaryNode nd)
- {
- // if (_lycount<_lylimit)
- // {
- // System.err.println("Warning: depth of _recount greater than number of
- // nodes.");
- // }
- if (nd == null)
- {
- return;
- }
- // _lycount++;
-
- if ((nd.left() != null) && (nd.right() != null))
- {
-
- _reCount(nd.left());
- _reCount((BinaryNode) nd.right());
-
- BinaryNode l = nd.left();
- BinaryNode r = nd.right();
-
- nd.count = l.count + r.count;
- nd.ycount = (l.ycount + r.ycount) / 2;
- }
- else
- {
- nd.count = 1;
- nd.ycount = ycount++;
- }
- // _lycount--;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public BinaryNode getTopNode()
- {
- return top;
- }
-
- /**
*
* @return true if tree has real distances
*/
}
/**
- * Form clusters by grouping sub-clusters, starting from one sequence per
- * cluster, and finishing when only two clusters remain
- */
- void cluster()
- {
- while (noClus > 2)
- {
- findMinDistance();
-
- joinClusters(mini, minj);
-
- noClus--;
- }
-
- int rightChild = done.nextClearBit(0);
- int leftChild = done.nextClearBit(rightChild + 1);
-
- joinClusters(leftChild, rightChild);
- top = (node.elementAt(leftChild));
-
- reCount(top);
- findHeight(top);
- findMaxDist(top);
- }
-
- /**
- * Returns the minimum distance between two clusters, and also sets the
- * indices of the clusters in fields mini and minj
- *
- * @return
- */
- protected abstract double findMinDistance();
-
- /**
* Calculates the tree using the given score model and parameters, and the
* configured tree type
* <p>
cluster();
}
- /**
- * Finds the node, at or below the given node, with the maximum distance, and
- * saves the node and the distance value
- *
- * @param nd
- */
- void findMaxDist(BinaryNode nd)
- {
- if (nd == null)
- {
- return;
- }
-
- if ((nd.left() == null) && (nd.right() == null))
- {
- double dist = nd.dist;
-
- if (dist > maxDistValue)
- {
- maxdist = nd;
- maxDistValue = dist;
- }
- }
- else
- {
- findMaxDist((BinaryNode) nd.left());
- findMaxDist((BinaryNode) nd.right());
- }
- }
-
- /**
- * Calculates and returns r, whatever that is
- *
- * @param i
- * @param j
- *
- * @return
- */
- protected double findr(int i, int j)
- {
- double tmp = 1;
-
- for (int k = 0; k < noseqs; k++)
- {
- if ((k != i) && (k != j) && (!done.get(k)))
- {
- tmp = tmp + distances.getValue(i, k);
- }
- }
-
- if (noClus > 2)
- {
- tmp = tmp / (noClus - 2);
- }
-
- return tmp;
- }
-
protected void init(AlignmentView seqView, int start, int end)
{
- this.node = new Vector<SequenceNode>();
+ this.node = new Vector<BinaryNode>();
if (seqView != null)
{
this.seqData = seqView;
}
/**
- * Merges cluster(j) to cluster(i) and recalculates cluster and node distances
- *
- * @param i
- * @param j
- */
- void joinClusters(final int i, final int j)
- {
- double dist = distances.getValue(i, j);
-
- ri = findr(i, j);
- rj = findr(j, i);
-
- findClusterDistance(i, j);
-
- SequenceNode sn = new SequenceNode();
-
- sn.setLeft((node.elementAt(i)));
- sn.setRight((node.elementAt(j)));
-
- BinaryNode tmpi = (node.elementAt(i));
- BinaryNode tmpj = (node.elementAt(j));
-
- findNewDistances(tmpi, tmpj, dist);
-
- tmpi.setParent(sn);
- tmpj.setParent(sn);
-
- node.setElementAt(sn, i);
-
- /*
- * move the members of cluster(j) to cluster(i)
- * and mark cluster j as out of the game
- */
- clusters.get(i).or(clusters.get(j));
- clusters.get(j).clear();
- done.set(j);
- }
-
- /*
- * Computes and stores new distances for nodei and nodej, given the previous
- * distance between them
- */
- protected abstract void findNewDistances(BinaryNode nodei,
- BinaryNode nodej, double previousDistance);
-
- /**
- * Calculates and saves the distance between the combination of cluster(i) and
- * cluster(j) and all other clusters. The form of the calculation depends on
- * the tree clustering method being used.
- *
- * @param i
- * @param j
- */
- protected abstract void findClusterDistance(int i, int j);
-
- /**
* Start by making a cluster for each individual sequence
*/
void makeLeaves()
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.analysis;
+
+import java.util.BitSet;
+import java.util.Vector;
+
+import jalview.datamodel.BinaryNode;
+import jalview.datamodel.SequenceNode;
+import jalview.math.MatrixI;
+
+public abstract class TreeEngine
+{
+
+ protected Vector<BitSet> clusters;
+
+ protected BitSet done;
+
+ protected int noseqs;
+
+ protected int noClus;
+
+ protected MatrixI distances;
+
+ protected double ri;
+
+ protected double rj;
+
+ protected Vector<BinaryNode> node;
+
+ BinaryNode maxdist;
+
+ double maxDistValue;
+
+ protected int mini;
+
+ protected int minj;
+
+ protected BinaryNode top;
+
+ protected int ycount;
+
+ double maxheight;
+
+ /**
+ * Calculates and returns r, whatever that is
+ *
+ * @param i
+ * @param j
+ *
+ * @return
+ */
+ protected double findr(int i, int j)
+ {
+ double tmp = 1;
+
+ for (int k = 0; k < noseqs; k++)
+ {
+ if ((k != i) && (k != j) && (!done.get(k)))
+ {
+ tmp = tmp + distances.getValue(i, k);
+ }
+ }
+
+ if (noClus > 2)
+ {
+ tmp = tmp / (noClus - 2);
+ }
+
+ return tmp;
+ }
+
+ /**
+ * Merges cluster(j) to cluster(i) and recalculates cluster and node distances
+ *
+ * @param i
+ * @param j
+ */
+ protected void joinClusters(final int i, final int j)
+ {
+ double dist = distances.getValue(i, j);
+
+ ri = findr(i, j);
+ rj = findr(j, i);
+
+ findClusterDistance(i, j);
+
+ BinaryNode sn = new BinaryNode();
+
+ sn.setLeft((node.elementAt(i)));
+ sn.setRight((node.elementAt(j)));
+
+ BinaryNode tmpi = (node.elementAt(i));
+ BinaryNode tmpj = (node.elementAt(j));
+
+ findNewDistances(tmpi, tmpj, dist);
+
+ tmpi.setParent(sn);
+ tmpj.setParent(sn);
+
+ node.setElementAt(sn, i);
+
+ /*
+ * move the members of cluster(j) to cluster(i)
+ * and mark cluster j as out of the game
+ */
+ clusters.get(i).or(clusters.get(j));
+ clusters.get(j).clear();
+ done.set(j);
+ }
+
+ protected abstract void findNewDistances(BinaryNode nodei,
+ BinaryNode nodej, double previousDistance);
+
+ /**
+ * Calculates and saves the distance between the combination of cluster(i) and
+ * cluster(j) and all other clusters. The form of the calculation depends on
+ * the tree clustering method being used.
+ *
+ * @param i
+ * @param j
+ */
+ protected abstract void findClusterDistance(int i, int j);
+
+ /**
+ * Finds the node, at or below the given node, with the maximum distance, and
+ * saves the node and the distance value
+ *
+ * @param nd
+ */
+ protected void findMaxDist(BinaryNode nd)
+ {
+ if (nd == null)
+ {
+ return;
+ }
+
+ if ((nd.left() == null) && (nd.right() == null))
+ {
+ double dist = nd.dist;
+
+ if (dist > maxDistValue)
+ {
+ maxdist = nd;
+ maxDistValue = dist;
+ }
+ }
+ else
+ {
+ findMaxDist((BinaryNode) nd.left());
+ findMaxDist((BinaryNode) nd.right());
+ }
+ }
+
+ /**
+ * Form clusters by grouping sub-clusters, starting from one sequence per
+ * cluster, and finishing when only two clusters remain
+ */
+ protected void cluster()
+ {
+ while (noClus > 2)
+ {
+ findMinDistance();
+
+ joinClusters(mini, minj);
+
+ noClus--;
+ }
+
+ int rightChild = done.nextClearBit(0);
+ int leftChild = done.nextClearBit(rightChild + 1);
+
+ joinClusters(leftChild, rightChild);
+ top = (node.elementAt(leftChild));
+
+ reCount(top);
+ findHeight(top);
+ findMaxDist(top);
+ }
+
+ /**
+ * Returns the minimum distance between two clusters, and also sets the
+ * indices of the clusters in fields mini and minj
+ *
+ * @return
+ */
+ protected abstract double findMinDistance();
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param nd
+ * DOCUMENT ME!
+ */
+ protected void _reCount(BinaryNode nd)
+ {
+ // if (_lycount<_lylimit)
+ // {
+ // System.err.println("Warning: depth of _recount greater than number of
+ // nodes.");
+ // }
+ if (nd == null)
+ {
+ return;
+ }
+ // _lycount++;
+
+ if ((nd.left() != null) && (nd.right() != null))
+ {
+
+ _reCount(nd.left());
+ _reCount((BinaryNode) nd.right());
+
+ BinaryNode l = nd.left();
+ BinaryNode r = nd.right();
+
+ nd.count = l.count + r.count;
+ nd.ycount = (l.ycount + r.ycount) / 2;
+ }
+ else
+ {
+ nd.count = 1;
+ nd.ycount = ycount++;
+ }
+ // _lycount--;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param nd
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ 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;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param nd
+ * DOCUMENT ME!
+ */
+ void reCount(BinaryNode nd)
+ {
+ ycount = 0;
+ // _lycount = 0;
+ // _lylimit = this.node.size();
+ _reCount(nd);
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public BinaryNode getTopNode()
+ {
+ return top;
+ }
+
+}
int noseqs;
- SequenceNode top;
+ BinaryNode top;
double maxDistValue;
int ycount;
- Vector<SequenceNode> node;
+ Vector<BinaryNode> node;
boolean hasDistances = true; // normal case for jalview trees
public TreeModel(SequenceI[] seqs, AlignmentView odata,
NewickFile treefile)
{
- this(seqs, treefile.getTree(), treefile.HasDistances(),
+ this(seqs, (SequenceNode) treefile.getTree(), treefile.HasDistances(),
treefile.HasBootstrap(), treefile.HasRootDistance());
seqData = odata;
{
SequenceIdMatcher algnIds = new SequenceIdMatcher(seqs);
- Vector<SequenceNode> leaves = findLeaves(top);
+ Vector<BinaryNode> leaves = findLeaves(top);
int i = 0;
int namesleft = seqs.length;
// int countOne2Many = 0;
while (i < leaves.size())
{
- j = leaves.elementAt(i++);
+ // TODO - decide if we get rid of the polymorphism here ?
+ j = (SequenceNode)leaves.elementAt(i++);
realnam = j.getName();
nam = null;
*/
public void updatePlaceHolders(List<SequenceI> list)
{
- Vector<SequenceNode> leaves = findLeaves(top);
+ Vector<BinaryNode> leaves = findLeaves(top);
int sz = leaves.size();
SequenceIdMatcher seqmatcher = null;
while (i < sz)
{
- SequenceNode leaf = leaves.elementAt(i++);
+ SequenceNode leaf = (SequenceNode) leaves.elementAt(i++);
if (list.contains(leaf.element()))
{
/**
* Search for leaf nodes below (or at) the given node
*
- * @param nd
+ * @param top2
* root node to search from
*
* @return
*/
- public Vector<SequenceNode> findLeaves(SequenceNode nd)
+ public Vector<BinaryNode> findLeaves(BinaryNode top2)
{
- Vector<SequenceNode> leaves = new Vector<SequenceNode>();
- findLeaves(nd, leaves);
+ Vector<BinaryNode> leaves = new Vector<BinaryNode>();
+ findLeaves(top2, leaves);
return leaves;
}
*
* @return Vector of leaf nodes on binary tree
*/
- Vector<SequenceNode> findLeaves(SequenceNode nd,
- Vector<SequenceNode> leaves)
+ Vector<BinaryNode> findLeaves(BinaryNode nd,
+ Vector<BinaryNode> leaves)
{
if (nd == null)
{
* @param threshold
* @see #getGroups()
*/
- public List<SequenceNode> groupNodes(float threshold)
+ public List<BinaryNode> groupNodes(float threshold)
{
- List<SequenceNode> groups = new ArrayList<SequenceNode>();
+ List<BinaryNode> groups = new ArrayList<BinaryNode>();
_groupNodes(groups, getTopNode(), threshold);
return groups;
}
- protected void _groupNodes(List<SequenceNode> groups, SequenceNode nd,
+ protected void _groupNodes(List<BinaryNode> groups, BinaryNode nd,
float threshold)
{
if (nd == null)
*
* @return DOCUMENT ME!
*/
- public SequenceNode getTopNode()
+ public BinaryNode getTopNode()
{
return top;
}
*/
public void applyToNodes(NodeTransformI nodeTransformI)
{
- for (Enumeration<SequenceNode> nodes = node.elements(); nodes
+ for (Enumeration<BinaryNode> nodes = node.elements(); nodes
.hasMoreElements(); nodeTransformI
.transform(nodes.nextElement()))
{
Hashtable nodeHash = new Hashtable();
- SequenceNode highlightNode;
+ BinaryNode highlightNode;
AlignmentPanel ap;
tree2.findHeight(tree2.getTopNode());
// Now have to calculate longest name based on the leaves
- Vector<SequenceNode> leaves = tree2.findLeaves(tree2.getTopNode());
+ Vector<BinaryNode> leaves = tree2.findLeaves(tree2.getTopNode());
boolean has_placeholders = false;
longestName = "";
for (int i = 0; i < leaves.size(); i++)
{
- SequenceNode lf = leaves.elementAt(i);
+ BinaryNode lf = leaves.elementAt(i);
- if (lf.isPlaceholder())
+ if (lf instanceof SequenceNode && ((SequenceNode)lf).isPlaceholder())
{
has_placeholders = true;
}
setMarkPlaceholders(has_placeholders);
}
- public void drawNode(Graphics g, SequenceNode node, float chunk,
+ public void drawNode(Graphics g, BinaryNode node, float chunk,
double scale, int width, int offx, int offy)
{
if (node == null)
g.drawString(nodeLabel, xstart + 2, ypos - 2);
}
- String name = (markPlaceholders && node.isPlaceholder())
+ String name = (markPlaceholders && node instanceof SequenceNode && ((SequenceNode) node).isPlaceholder())
? (PLACEHOLDER + node.getName())
: node.getName();
FontMetrics fm = g.getFontMetrics(font);
}
else
{
- drawNode(g, (SequenceNode) node.left(), chunk, scale, width, offx,
+ drawNode(g, (BinaryNode) node.left(), chunk, scale, width, offx,
offy);
- drawNode(g, (SequenceNode) node.right(), chunk, scale, width, offx,
+ drawNode(g, (BinaryNode) node.right(), chunk, scale, width, offx,
offy);
double height = node.height;
}
else
{
- Vector<SequenceNode> leaves = tree.findLeaves(highlightNode);
+ Vector<BinaryNode> leaves = tree.findLeaves(highlightNode);
for (int i = 0; i < leaves.size(); i++)
{
Object ob = findElement(evt.getX(), evt.getY());
- if (ob instanceof SequenceNode)
+ if (ob instanceof BinaryNode)
{
- highlightNode = (SequenceNode) ob;
+ highlightNode = (BinaryNode) ob;
repaint();
}
else
threshold = (float) (x - offx)
/ (float) (getSize().width - labelLength - 2 * offx);
- List<SequenceNode> groups = tree.groupNodes(threshold);
+ List<BinaryNode> groups = tree.groupNodes(threshold);
setColor(tree.getTopNode(), Color.black);
av.setSelectionGroup(null);
}
- void colourGroups(List<SequenceNode> groups)
+ void colourGroups(List<BinaryNode> groups)
{
for (int i = 0; i < groups.size(); i++)
{
(int) (Math.random() * 255), (int) (Math.random() * 255));
setColor(groups.get(i), col.brighter());
- Vector<SequenceNode> l = tree.findLeaves(groups.get(i));
+ Vector<BinaryNode> l = tree.findLeaves(groups.get(i));
Vector<SequenceI> sequences = new Vector<>();
for (int j = 0; j < l.size(); j++)
Map<Object, Rectangle> nameHash = new Hashtable<>();
- Map<SequenceNode, Rectangle> nodeHash = new Hashtable<>();
+ Map<BinaryNode, Rectangle> nodeHash = new Hashtable<>();
- SequenceNode highlightNode;
+ BinaryNode highlightNode;
boolean applyToAllViews = false;
tree.findHeight(tree.getTopNode());
// Now have to calculate longest name based on the leaves
- Vector<SequenceNode> leaves = tree.findLeaves(tree.getTopNode());
+ Vector<BinaryNode> leaves = tree.findLeaves(tree.getTopNode());
boolean has_placeholders = false;
longestName = "";
for (int i = 0; i < leaves.size(); i++)
{
- SequenceNode lf = leaves.elementAt(i);
+ BinaryNode lf = leaves.elementAt(i);
- if (lf.isPlaceholder())
+ if (lf instanceof SequenceNode && ((SequenceNode)lf).isPlaceholder())
{
has_placeholders = true;
}
* @param offy
* DOCUMENT ME!
*/
- public void drawNode(Graphics g, SequenceNode node, float chunk,
+ public void drawNode(Graphics g, BinaryNode node, float chunk,
double wscale, int width, int offx, int offy)
{
if (node == null)
g.drawString(nodeLabel, xstart + 2, ypos - 2);
}
- String name = (markPlaceholders && node.isPlaceholder())
+ String name = (markPlaceholders && ((node instanceof SequenceNode && ((SequenceNode)node).isPlaceholder())))
? (PLACEHOLDER + node.getName())
: node.getName();
}
else
{
- drawNode(g, (SequenceNode) node.left(), chunk, wscale, width, offx,
+ drawNode(g, (BinaryNode) node.left(), chunk, wscale, width, offx,
offy);
- drawNode(g, (SequenceNode) node.right(), chunk, wscale, width, offx,
+ drawNode(g, (BinaryNode) node.right(), chunk, wscale, width, offx,
offy);
double height = node.height;
}
}
- for (Entry<SequenceNode, Rectangle> entry : nodeHash.entrySet())
+ for (Entry<BinaryNode, Rectangle> entry : nodeHash.entrySet())
{
Rectangle rect = entry.getValue();
}
else
{
- Vector<SequenceNode> leaves = tree.findLeaves(highlightNode);
+ Vector<BinaryNode> leaves = tree.findLeaves(highlightNode);
for (int i = 0; i < leaves.size(); i++)
{
Object ob = findElement(evt.getX(), evt.getY());
- if (ob instanceof SequenceNode)
+ if (ob instanceof BinaryNode)
{
- highlightNode = (SequenceNode) ob;
+ highlightNode = (BinaryNode) ob;
this.setToolTipText(
"<html>" + MessageManager.getString("label.highlightnode"));
repaint();
av.sendSelection();
return;
}
- else if (!(ob instanceof SequenceNode))
+ else if (!(ob instanceof BinaryNode))
{
// Find threshold
if (tree.getMaxHeight() != 0)
threshold = (float) (x - offx)
/ (float) (getWidth() - labelLength - (2 * offx));
- List<SequenceNode> groups = tree.groupNodes(threshold);
+ List<BinaryNode> groups = tree.groupNodes(threshold);
setColor(tree.getTopNode(), Color.black);
AlignmentPanel[] aps = getAssociatedPanels();
}
- void colourGroups(List<SequenceNode> groups)
+ void colourGroups(List<BinaryNode> groups)
{
AlignmentPanel[] aps = getAssociatedPanels();
for (int i = 0; i < groups.size(); i++)
(int) (Math.random() * 255), (int) (Math.random() * 255));
setColor(groups.get(i), col.brighter());
- Vector<SequenceNode> l = tree.findLeaves(groups.get(i));
+ Vector<BinaryNode> l = tree.findLeaves(groups.get(i));
Vector<SequenceI> sequences = new Vector<>();
*/
public class NewickFile extends FileParse
{
- SequenceNode root;
+ BinaryNode root;
private boolean HasBootstrap = false;
* @param newtree
* DOCUMENT ME!
*/
- public NewickFile(SequenceNode newtree)
+ public NewickFile(BinaryNode newtree)
{
root = newtree;
}
* @param distances
* DOCUMENT ME!
*/
- public NewickFile(SequenceNode newtree, boolean bootstrap,
+ public NewickFile(BinaryNode newtree, boolean bootstrap,
boolean distances)
{
root = newtree;
* @param rootdistance
* DOCUMENT ME!
*/
- public NewickFile(SequenceNode newtree, boolean bootstrap,
+ public NewickFile(BinaryNode newtree, boolean bootstrap,
boolean distances, boolean rootdistance)
{
root = newtree;
*
* @return DOCUMENT ME!
*/
- public SequenceNode getTree()
+ public BinaryNode getTree()
{
return root;
}
}
// Non recursive call deals with root node properties
- public void print(StringBuffer tf, SequenceNode root)
+ public void print(StringBuffer tf, BinaryNode root)
{
if (root != null)
{
{
if (root.isDummy())
{
- _print(tf, (SequenceNode) root.right());
- _print(tf, (SequenceNode) root.left());
+ _print(tf, root.right());
+ _print(tf, root.left());
}
else
{
tf.append("(");
- _print(tf, (SequenceNode) root.right());
+ _print(tf, root.right());
if (root.left() != null)
{
tf.append(",");
}
- _print(tf, (SequenceNode) root.left());
+ _print(tf, root.left());
tf.append(")" + printRootField(root));
}
}
}
// Recursive call for non-root nodes
- public void _print(StringBuffer tf, SequenceNode c)
+ public void _print(StringBuffer tf, BinaryNode c)
{
if (c != null)
{
{
if (c.isDummy())
{
- _print(tf, (SequenceNode) c.left());
+ _print(tf, c.left());
if (c.left() != null)
{
tf.append(",");
}
- _print(tf, (SequenceNode) c.right());
+ _print(tf, c.right());
}
else
{
tf.append("(");
- _print(tf, (SequenceNode) c.right());
+ _print(tf, c.right());
if (c.left() != null)
{
tf.append(",");
}
- _print(tf, (SequenceNode) c.left());
+ _print(tf, c.left());
tf.append(")" + printNodeField(c));
}
}
Console.warn("Not updating SequenceTreeMap for " + tree.getVorbaId());
return;
}
- Vector<SequenceNode> leaves = tp.getTree()
+ Vector<BinaryNode> leaves = tp.getTree()
.findLeaves(tp.getTree().getTopNode());
Treenode[] tn = tree.getTreenode(); // todo: select nodes for this
// particular tree
*/
public Treenode[] makeTreeNodes(TreeModel treeModel, Newick newick)
{
- Vector<SequenceNode> leaves = treeModel
+ Vector<BinaryNode> leaves = treeModel
.findLeaves(treeModel.getTopNode());
Vector tnv = new Vector();
Enumeration l = leaves.elements();
--- /dev/null
+package jalview.analysis;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import jalview.bin.Cache;
+import jalview.bin.Console;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ContactMatrixI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FastaFile;
+import jalview.io.FileLoader;
+import jalview.io.FormatAdapter;
+import jalview.util.Platform;
+import jalview.ws.datamodel.alphafold.PAEContactMatrix;
+
+public class AverageDistanceEngineTest
+{
+
+ @BeforeClass(alwaysRun = true)
+ public void setUpJvOptionPane()
+ {
+ JvOptionPane.setInteractiveMode(false);
+ JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void loadProperties()
+ {
+ Cache.loadProperties("test/jalview/bin/TestProps.jvprops");
+ }
+ @Test
+ public void testUPGMAEngine() throws Exception
+ {
+ AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded("examples/test_fab41.result/sample.a3m",DataSourceType.FILE);
+ AlignmentI seqs = af.getViewport().getAlignment();
+ SequenceI target = seqs.getSequenceAt(0);
+ File testPAE = new File("examples/test_fab41.result/test_fab41_predicted_aligned_error_v1.json");
+ List<Object> pae_obj = (List<Object>) Platform.parseJSON(new FileInputStream(testPAE));
+ if (pae_obj == null)
+ {
+ Assert.fail("JSON PAE file did not parse properly.");
+ }
+ ContactMatrixI matrix = new PAEContactMatrix(target,
+ (Map<String, Object>) pae_obj.get(0));
+ AlignmentAnnotation aa = target.addContactList(matrix);
+ long start = System.currentTimeMillis();
+ AverageDistanceEngine clusterer = new AverageDistanceEngine(af.getViewport(), null, matrix);
+ System.out.println("built a tree in "+(System.currentTimeMillis()-start)*0.001+" seconds.");
+ StringBuffer sb = new StringBuffer();
+ System.out.println("Newick string\n"+ new jalview.io.NewickFile(clusterer.getTopNode(),true,true).print());
+
+ }
+
+}
AssertJUnit.assertTrue(
stage + "Invalid Tree '" + nf.getWarningMessage() + "'",
nf.isValid());
- SequenceNode tree = nf.getTree();
+ BinaryNode tree = nf.getTree();
AssertJUnit.assertTrue(stage + "Null Tree", tree != null);
stage = "Creating newick file from testTree " + treename;
String gentree = new NewickFile(tree).print(nf.HasBootstrap(),
AssertJUnit.assertTrue(stage + "Null Tree", tree_regen != null);
stage = "Compare original and generated tree" + treename;
- Vector<SequenceNode> oseqs, nseqs;
+ Vector<BinaryNode> oseqs, nseqs;
oseqs = new TreeModel(new SequenceI[0], null, nf)
.findLeaves(nf.getTree());
AssertJUnit.assertTrue(stage + "No nodes in original tree.",