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.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+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);
+ }
+ /***
+ * not the right place - OH WELL!
+ */
+
+ /**
+ * Makes a list of groups, where each group is represented by a node whose
+ * height (distance from the root node), as a fraction of the height of the
+ * whole tree, is greater than the given threshold. This corresponds to
+ * selecting the nodes immediately to the right of a vertical line
+ * partitioning the tree (if the tree is drawn with root to the left). Each
+ * such node represents a group that contains all of the sequences linked to
+ * the child leaf nodes.
+ *
+ * @param threshold
+ * @see #getGroups()
+ */
+ public List<BinaryNode> groupNodes(float threshold)
+ {
+ List<BinaryNode> groups = new ArrayList<BinaryNode>();
+ _groupNodes(groups, getTopNode(), threshold);
+ return groups;
+ }
+
+ protected void _groupNodes(List<BinaryNode> 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<BinaryNode> findLeaves(BinaryNode top2)
+ {
+ Vector<BinaryNode> leaves = new Vector<BinaryNode>();
+ 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<BinaryNode> findLeaves(BinaryNode nd,
+ Vector<BinaryNode> 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;
+ }
+
+
+}
import jalview.api.analysis.ScoreModelI;
import jalview.api.analysis.SimilarityParamsI;
-import jalview.datamodel.SequenceNode;
+import jalview.datamodel.BinaryNode;
import jalview.viewmodel.AlignmentViewport;
/**
* {@inheritDoc}
*/
@Override
- protected void findNewDistances(SequenceNode nodei, SequenceNode nodej,
+ protected void findNewDistances(BinaryNode nodei, BinaryNode nodej,
double dist)
{
double ih = 0;
double jh = 0;
- SequenceNode sni = nodei;
- SequenceNode snj = nodej;
+ BinaryNode sni = nodei;
+ BinaryNode snj = nodej;
while (sni != null)
{
ih = ih + sni.dist;
- sni = (SequenceNode) sni.left();
+ sni = (BinaryNode) sni.left();
}
while (snj != null)
{
jh = jh + snj.dist;
- snj = (SequenceNode) snj.left();
+ snj = (BinaryNode) snj.left();
}
nodei.dist = ((dist / 2) - ih);
import jalview.api.analysis.ScoreModelI;
import jalview.api.analysis.SimilarityParamsI;
-import jalview.datamodel.SequenceNode;
+import jalview.datamodel.BinaryNode;
import jalview.viewmodel.AlignmentViewport;
/**
* {@inheritDoc}
*/
@Override
- protected void findNewDistances(SequenceNode nodei, SequenceNode nodej,
+ protected void findNewDistances(BinaryNode nodei, BinaryNode nodej,
double dist)
{
nodei.dist = ((dist + ri) - rj) / 2;
import jalview.api.analysis.ScoreModelI;
import jalview.api.analysis.SimilarityParamsI;
import jalview.datamodel.AlignmentView;
+import jalview.datamodel.BinaryNode;
import jalview.datamodel.CigarArray;
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;
-
- SequenceNode maxdist;
-
- SequenceNode top;
-
- double maxDistValue;
-
- double maxheight;
-
- int ycount;
-
- Vector<SequenceNode> node;
-
private AlignmentView seqStrings;
/**
}
/**
- * DOCUMENT ME!
- *
- * @param nd
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- double findHeight(SequenceNode nd)
- {
- if (nd == null)
- {
- return maxheight;
- }
-
- if ((nd.left() == null) && (nd.right() == null))
- {
- nd.height = ((SequenceNode) nd.parent()).height + nd.dist;
-
- if (nd.height > maxheight)
- {
- return nd.height;
- }
- else
- {
- return maxheight;
- }
- }
- else
- {
- if (nd.parent() != null)
- {
- nd.height = ((SequenceNode) nd.parent()).height + nd.dist;
- }
- else
- {
- maxheight = 0;
- nd.height = (float) 0.0;
- }
-
- maxheight = findHeight((SequenceNode) (nd.left()));
- maxheight = findHeight((SequenceNode) (nd.right()));
- }
-
- return maxheight;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param nd
- * DOCUMENT ME!
- */
- void reCount(SequenceNode nd)
- {
- ycount = 0;
- // _lycount = 0;
- // _lylimit = this.node.size();
- _reCount(nd);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param nd
- * DOCUMENT ME!
- */
- void _reCount(SequenceNode 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((SequenceNode) nd.left());
- _reCount((SequenceNode) nd.right());
-
- SequenceNode l = (SequenceNode) nd.left();
- SequenceNode r = (SequenceNode) 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 SequenceNode 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(SequenceNode 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((SequenceNode) nd.left());
- findMaxDist((SequenceNode) 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)));
-
- SequenceNode tmpi = (node.elementAt(i));
- SequenceNode 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(SequenceNode nodei,
- SequenceNode 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;
*/
public TreeModel(TreeBuilder tree)
{
- this(tree.getSequences(), tree.getTopNode(), tree.hasDistances(),
+ this(tree.getSequences(), (SequenceNode) tree.getTopNode(), tree.hasDistances(),
tree.hasBootstrap(), tree.hasRootDistance());
seqData = tree.getOriginalData();
}
{
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 nd
* SequenceNode
*/
- void printNode(SequenceNode nd)
+ void printNode(BinaryNode nd)
{
if (nd == null)
{
else
{
System.out.println("Dist " + nd.dist);
- printNode((SequenceNode) nd.left());
- printNode((SequenceNode) nd.right());
+ printNode((BinaryNode) nd.left());
+ printNode((BinaryNode) nd.right());
}
}
* @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 double findHeight(SequenceNode nd)
+ public double findHeight(BinaryNode nd)
{
if (nd == null)
{
if ((nd.left() == null) && (nd.right() == null))
{
- nd.height = ((SequenceNode) nd.parent()).height + nd.dist;
+ nd.height = ((BinaryNode) nd.parent()).height + nd.dist;
if (nd.height > maxheight)
{
{
if (nd.parent() != null)
{
- nd.height = ((SequenceNode) nd.parent()).height + nd.dist;
+ nd.height = ((BinaryNode) nd.parent()).height + nd.dist;
}
else
{
nd.height = (float) 0.0;
}
- maxheight = findHeight((SequenceNode) (nd.left()));
- maxheight = findHeight((SequenceNode) (nd.right()));
+ maxheight = findHeight((BinaryNode) (nd.left()));
+ maxheight = findHeight((BinaryNode) (nd.right()));
}
return maxheight;
* @param nd
* DOCUMENT ME!
*/
- void printN(SequenceNode nd)
+ void printN(BinaryNode nd)
{
if (nd == null)
{
if ((nd.left() != null) && (nd.right() != null))
{
- printN((SequenceNode) nd.left());
- printN((SequenceNode) nd.right());
+ printN((BinaryNode) nd.left());
+ printN((BinaryNode) nd.right());
}
else
{
* @param nd
* DOCUMENT ME!
*/
- public void reCount(SequenceNode nd)
+ public void reCount(BinaryNode nd)
{
ycount = 0;
// _lycount = 0;
* @param nd
* DOCUMENT ME!
*/
- void _reCount(SequenceNode nd)
+ void _reCount(BinaryNode nd)
{
// if (_lycount<_lylimit)
// {
if ((nd.left() != null) && (nd.right() != null))
{
- _reCount((SequenceNode) nd.left());
- _reCount((SequenceNode) nd.right());
+ _reCount((BinaryNode) nd.left());
+ _reCount((BinaryNode) nd.right());
- SequenceNode l = (SequenceNode) nd.left();
- SequenceNode r = (SequenceNode) nd.right();
+ BinaryNode l = (BinaryNode) nd.left();
+ BinaryNode r = (BinaryNode) nd.right();
nd.count = l.count + r.count;
nd.ycount = (l.ycount + r.ycount) / 2;
* @param nd
* DOCUMENT ME!
*/
- public void swapNodes(SequenceNode nd)
+ public void swapNodes(BinaryNode nd)
{
if (nd == null)
{
return;
}
- SequenceNode tmp = (SequenceNode) nd.left();
+ BinaryNode tmp = (BinaryNode) nd.left();
nd.setLeft(nd.right());
nd.setRight(tmp);
* @param dir
* DOCUMENT ME!
*/
- void changeDirection(SequenceNode nd, SequenceNode dir)
+ void changeDirection(BinaryNode nd, BinaryNode dir)
{
if (nd == null)
{
if (nd.parent() != top)
{
- changeDirection((SequenceNode) nd.parent(), nd);
+ changeDirection((BinaryNode) nd.parent(), nd);
- SequenceNode tmp = (SequenceNode) nd.parent();
+ BinaryNode tmp = (BinaryNode) nd.parent();
if (dir == nd.left())
{
*
* @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()))
{
import jalview.analysis.Conservation;
import jalview.analysis.TreeModel;
import jalview.api.AlignViewportI;
+import jalview.datamodel.BinaryNode;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
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;
}
int ystart = (int) (node.left() == null ? 0
- : (((SequenceNode) node.left()).ycount * chunk)) + offy;
+ : (((BinaryNode) node.left()).ycount * chunk)) + offy;
int yend = (int) (node.right() == null ? 0
- : (((SequenceNode) node.right()).ycount * chunk)) + offy;
+ : (((BinaryNode) node.right()).ycount * chunk)) + offy;
Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);
nodeHash.put(node, pos);
int width = getSize().width;
int height = getSize().height;
- SequenceNode top = tree.getTopNode();
+ BinaryNode top = tree.getTopNode();
double wscale = (float) (width * .8 - offx * 2) / tree.getMaxHeight();
if (top.count == 0)
{
- top.count = ((SequenceNode) top.left()).count
- + ((SequenceNode) top.right()).count;
+ top.count = ((BinaryNode) top.left()).count
+ + ((BinaryNode) top.right()).count;
}
float chunk = (float) (height - offy) / top.count;
pickNode(pickBox, top, chunk, wscale, width, offx, offy);
}
- public void pickNode(Rectangle pickBox, SequenceNode node, float chunk,
+ public void pickNode(Rectangle pickBox, BinaryNode node, float chunk,
double scale, int width, int offx, int offy)
{
if (node == null)
}
else
{
- pickNode(pickBox, (SequenceNode) node.left(), chunk, scale, width,
+ pickNode(pickBox, (BinaryNode) node.left(), chunk, scale, width,
offx, offy);
- pickNode(pickBox, (SequenceNode) node.right(), chunk, scale, width,
+ pickNode(pickBox, (BinaryNode) node.right(), chunk, scale, width,
offx, offy);
}
}
- public void setColor(SequenceNode node, Color c)
+ public void setColor(BinaryNode node, Color c)
{
if (node == null)
{
else
{
node.color = c;
- setColor((SequenceNode) node.left(), c);
- setColor((SequenceNode) node.right(), c);
+ setColor((BinaryNode) node.left(), c);
+ setColor((BinaryNode) node.right(), c);
}
}
double wscale = (width - labelLength - offx * 2) / tree.getMaxHeight();
- SequenceNode top = tree.getTopNode();
+ BinaryNode top = tree.getTopNode();
if (top.count == 0)
{
- top.count = ((SequenceNode) top.left()).count
- + ((SequenceNode) top.right()).count;
+ top.count = ((BinaryNode) top.left()).count
+ + ((BinaryNode) top.right()).count;
}
float chunk = (float) (height - offy) / top.count;
}
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++)
*/
package jalview.datamodel;
+import java.awt.Color;
+
/**
* DOCUMENT ME!
*
BinaryNode parent;
- /** DOCUMENT ME!! */
+ /** Bootstrap value */
public int bootstrap;
+ /** DOCUMENT ME!! */
+ public double dist;
+
+ /** DOCUMENT ME!! */
+ public int count;
+
+ /** DOCUMENT ME!! */
+ public double height;
+
+ /** DOCUMENT ME!! */
+ public float ycount;
+
+ /** DOCUMENT ME!! */
+ public Color color = Color.black;
+
+ /** DOCUMENT ME!! */
+ public boolean dummy = false;
+
/**
* Creates a new BinaryNode object.
*/
{
left = right = parent = null;
bootstrap = 0;
+ dist = 0;
}
/**
* @param name
* DOCUMENT ME!
*/
- public BinaryNode(Object element, BinaryNode parent, String name)
+ public BinaryNode(Object element, BinaryNode parent, String name,
+ double dist)
{
+ this();
this.element = element;
this.parent = parent;
this.name = name;
+ this.dist = dist;
+ }
+
+ public BinaryNode(Object element, BinaryNode parent, String name,
+ double dist, int bootstrap)
+ {
+ this(element, parent, name, dist);
+ this.bootstrap = bootstrap;
+ }
- left = right = null;
+ public BinaryNode(Object val, BinaryNode parent, String name, double dist,
+ int bootstrap, boolean dummy)
+ {
+ this(val, parent, name, dist, bootstrap);
+ this.dummy = dummy;
}
/**
{
return bootstrap;
}
+
+ /**
+ * @param dummy
+ * true if node is created for the representation of polytomous trees
+ */
+ public boolean isDummy()
+ {
+ return dummy;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param newstate
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public boolean setDummy(boolean newstate)
+ {
+ boolean oldstate = dummy;
+ dummy = newstate;
+
+ return oldstate;
+ }
+
+ /**
+ * ascends the tree but doesn't stop until a non-dummy node is discovered.
+ *
+ */
+ public BinaryNode AscendTree()
+ {
+ BinaryNode c = this;
+
+ do
+ {
+ c = c.parent();
+ } while ((c != null) && c.dummy);
+
+ return c;
+ }
}
*/
package jalview.datamodel;
-import java.awt.Color;
-
/**
* DOCUMENT ME!
*
*/
public class SequenceNode extends BinaryNode
{
- /** DOCUMENT ME!! */
- public double dist;
-
- /** DOCUMENT ME!! */
- public int count;
-
- /** DOCUMENT ME!! */
- public double height;
-
- /** DOCUMENT ME!! */
- public float ycount;
-
- /** DOCUMENT ME!! */
- public Color color = Color.black;
-
- /** DOCUMENT ME!! */
- public boolean dummy = false;
-
private boolean placeholder = false;
/**
super();
}
- /**
- * Creates a new SequenceNode object.
- *
- * @param val
- * DOCUMENT ME!
- * @param parent
- * DOCUMENT ME!
- * @param dist
- * DOCUMENT ME!
- * @param name
- * DOCUMENT ME!
- */
- public SequenceNode(Object val, SequenceNode parent, double dist,
- String name)
+ public SequenceNode(SequenceI val, BinaryNode parent, String name,
+ double dist, int bootstrap, boolean dummy)
{
- super(val, parent, name);
- this.dist = dist;
+ super(val, parent, name, dist, bootstrap, dummy);
}
- /**
- * Creates a new SequenceNode object.
- *
- * @param val
- * DOCUMENT ME!
- * @param parent
- * DOCUMENT ME!
- * @param name
- * DOCUMENT ME!
- * @param dist
- * DOCUMENT ME!
- * @param bootstrap
- * DOCUMENT ME!
- * @param dummy
- * DOCUMENT ME!
- */
- public SequenceNode(Object val, SequenceNode parent, String name,
- double dist, int bootstrap, boolean dummy)
+ public SequenceNode(SequenceI element, BinaryNode parent, String name,
+ double dist, int bootstrap)
{
- super(val, parent, name);
- this.dist = dist;
- this.bootstrap = bootstrap;
- this.dummy = dummy;
+ super(element, parent, name, dist, bootstrap);
}
- /**
- * @param dummy
- * true if node is created for the representation of polytomous trees
- */
- public boolean isDummy()
+ public SequenceNode(SequenceI element, BinaryNode parent, String name,
+ double dist)
{
- return dummy;
+ super(element, parent, name, dist);
}
/*
/**
* DOCUMENT ME!
*
- * @param newstate
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public boolean setDummy(boolean newstate)
- {
- boolean oldstate = dummy;
- dummy = newstate;
-
- return oldstate;
- }
-
- /**
- * DOCUMENT ME!
- *
* @param Placeholder
* DOCUMENT ME!
*/
}
/**
- * ascends the tree but doesn't stop until a non-dummy node is discovered.
- * This will probably break if the tree is a mixture of BinaryNodes and
- * SequenceNodes.
- */
- public SequenceNode AscendTree()
- {
- SequenceNode c = this;
-
- do
- {
- c = (SequenceNode) c.parent();
- } while ((c != null) && c.dummy);
-
- return c;
- }
-
- /**
* test if this node has a name that might be a label rather than a bootstrap
* value
*
import jalview.analysis.Conservation;
import jalview.analysis.TreeModel;
import jalview.api.AlignViewportI;
+import jalview.datamodel.BinaryNode;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
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;
}
int ystart = (node.left() == null ? 0
- : (int) (((SequenceNode) node.left()).ycount * chunk)) + offy;
+ : (int) (((BinaryNode) node.left()).ycount * chunk)) + offy;
int yend = (node.right() == null ? 0
- : (int) (((SequenceNode) node.right()).ycount * chunk))
+ : (int) (((BinaryNode) node.right()).ycount * chunk))
+ offy;
Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);
}
}
- for (Entry<SequenceNode, Rectangle> entry : nodeHash.entrySet())
+ for (Entry<BinaryNode, Rectangle> entry : nodeHash.entrySet())
{
Rectangle rect = entry.getValue();
int width = getWidth();
int height = getHeight();
- SequenceNode top = tree.getTopNode();
+ BinaryNode top = tree.getTopNode();
double wscale = ((width * .8) - (offx * 2)) / tree.getMaxHeight();
if (top.count == 0)
{
- top.count = ((SequenceNode) top.left()).count
- + ((SequenceNode) top.right()).count;
+ top.count = ((BinaryNode) top.left()).count
+ + ((BinaryNode) top.right()).count;
}
float chunk = (float) (height - (offy)) / top.count;
* @param offy
* DOCUMENT ME!
*/
- public void pickNode(Rectangle pickBox, SequenceNode node, float chunk,
+ public void pickNode(Rectangle pickBox, BinaryNode node, float chunk,
double wscale, int width, int offx, int offy)
{
if (node == null)
}
else
{
- pickNode(pickBox, (SequenceNode) node.left(), chunk, wscale, width,
+ pickNode(pickBox, (BinaryNode) node.left(), chunk, wscale, width,
offx, offy);
- pickNode(pickBox, (SequenceNode) node.right(), chunk, wscale, width,
+ pickNode(pickBox, (BinaryNode) node.right(), chunk, wscale, width,
offx, offy);
}
}
* @param c
* DOCUMENT ME!
*/
- public void setColor(SequenceNode node, Color c)
+ public void setColor(BinaryNode node, Color c)
{
if (node == null)
{
}
}
}
- setColor((SequenceNode) node.left(), c);
- setColor((SequenceNode) node.right(), c);
+ setColor((BinaryNode) node.left(), c);
+ setColor((BinaryNode) node.right(), c);
}
/**
double wscale = (width - labelLength - (offx * 2))
/ tree.getMaxHeight();
- SequenceNode top = tree.getTopNode();
+ BinaryNode top = tree.getTopNode();
if (top.count == 0)
{
- top.count = ((SequenceNode) top.left()).count
- + ((SequenceNode) top.right()).count;
+ top.count = ((BinaryNode) top.left()).count
+ + ((BinaryNode) top.right()).count;
}
float chunk = (float) (height - (offy)) / top.count;
}
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<>();
&& !((SequenceNode) node).isDummy())
{
String newname = null;
- SequenceI sq = (SequenceI) ((SequenceNode) node).element();
+ SequenceI sq = (SequenceI) ((BinaryNode) node).element();
if (sq != null)
{
// search dbrefs, features and annotation
{
// String oldname = ((SequenceNode) node).getName();
// TODO : save oldname in the undo object for this modification.
- ((SequenceNode) node).setName(newname);
+ ((BinaryNode) node).setName(newname);
}
}
}
import java.util.Locale;
+import jalview.datamodel.BinaryNode;
import jalview.datamodel.SequenceNode;
import jalview.util.MessageManager;
*/
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;
root = new SequenceNode();
- SequenceNode realroot = null;
- SequenceNode c = root;
+ BinaryNode realroot = null;
+ BinaryNode c = root;
int d = -1;
int cp = 0;
{
c.setRight(new SequenceNode(null, c, null, DefDistance,
DefBootstrap, false));
- c = (SequenceNode) c.right();
+ c = (BinaryNode) c.right();
}
else
{
if (c.left() != null)
{
// Dummy node for polytomy - keeps c.left free for new node
- SequenceNode tmpn = new SequenceNode(null, c, null, 0, 0, true);
+ BinaryNode tmpn = new SequenceNode(null, c, null, 0, 0, true);
tmpn.SetChildren(c.left(), c.right());
c.setRight(tmpn);
}
c.setLeft(new SequenceNode(null, c, null, DefDistance,
DefBootstrap, false));
- c = (SequenceNode) c.left();
+ c = (BinaryNode) c.left();
}
if (realroot == null)
else
{
// Find a place to put the leaf
- SequenceNode newnode = new SequenceNode(null, c, nodename,
+ BinaryNode newnode = new SequenceNode(null, c, nodename,
(HasDistances) ? distance : DefDistance,
(HasBootstrap) ? bootstrap : DefBootstrap, false);
parseNHXNodeProps(c, commentString2);
{
// Insert a dummy node for polytomy
// dummy nodes have distances
- SequenceNode newdummy = new SequenceNode(null, c, null,
+ BinaryNode newdummy = new SequenceNode(null, c, null,
(HasDistances ? 0 : DefDistance), 0, true);
newdummy.SetChildren(c.left(), newnode);
c.setLeft(newdummy);
// Just advance focus, if we need to
if ((c.left() != null) && (!c.left().isLeaf()))
{
- c = (SequenceNode) c.left();
+ c = (BinaryNode) c.left();
}
}
}
* @param commentString
* @param commentString2
*/
- private void parseNHXNodeProps(SequenceNode c, String commentString)
+ private void parseNHXNodeProps(BinaryNode c, String commentString)
{
// TODO: store raw comment on the sequenceNode so it can be recovered when
// tree is output
*
* @return DOCUMENT ME!
*/
- public SequenceNode getTree()
+ public BinaryNode getTree()
{
return root;
}
*
* @return DOCUMENT ME!
*/
- private String printNodeField(SequenceNode c)
+ private String printNodeField(BinaryNode c)
{
return ((c.getName() == null) ? "" : nodeName(c.getName()))
+ ((HasBootstrap) ? ((c.getBootstrap() > -1)
*
* @return DOCUMENT ME!
*/
- private String printRootField(SequenceNode root)
+ private String printRootField(BinaryNode root)
{
return (printRootInfo)
? (((root.getName() == null) ? "" : nodeName(root.getName()))
}
// 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();
{
if (!((jalview.datamodel.SequenceNode) tnode).isPlaceholder())
{
- Object assocseq = ((jalview.datamodel.SequenceNode) tnode)
+ Object assocseq = ((BinaryNode) tnode)
.element();
if (assocseq instanceof SequenceI)
{
--- /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.BinaryNode;
+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());
+
+ clusterer.findHeight(clusterer.getTopNode());
+ List<BinaryNode> groups = clusterer.groupNodes(0.8f);
+ int n=1;
+ for (BinaryNode root:groups)
+ {
+ System.out.println("Cluster "+n++);
+ for (BinaryNode leaf:clusterer.findLeaves(root))
+ {
+ System.out.print(" "+leaf.getName());
+ }
+ System.out.println("\\");
+ }
+
+ }
+
+}
import jalview.analysis.SequenceIdMatcher;
import jalview.analysis.TreeModel;
+import jalview.datamodel.BinaryNode;
import jalview.datamodel.SequenceI;
import jalview.datamodel.SequenceNode;
import jalview.gui.JvOptionPane;
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(),
stage + "Newick file is invalid ('"
+ nf_regen.getWarningMessage() + "')",
nf_regen.isValid());
- SequenceNode tree_regen = nf.getTree();
+ BinaryNode tree_regen = nf.getTree();
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.",