// Implementation of some algorithms for building phylogenetic trees from // Durbin et al: Biological Sequence Analysis, CUP 1998, chapter 7. // Peter Sestoft, sestoft@itu.dk 1999-12-07 version 0.3 // Reference: http://www.itu.dk/people/sestoft/bsa.html // License: Anybody can use this code for any purpose, including // teaching, research, and commercial purposes, provided proper // reference is made to its origin. Neither the author nor the Royal // Veterinary and Agricultural University, Copenhagen, Denmark, can // take any responsibility for the consequences of using this code. // Compile with: // javac Match7.java // Run with: // java Match7 import java.awt.*; import java.awt.event.*; // The abstract class of clusters or rooted trees abstract class Cluster { public abstract void draw(Graphics g, int w, int h); } // UPGMA clusters or trees, built by the UPGMA algorithm class UPCluster extends Cluster { int lab; // Cluster identifier int card; // The number of sequences in the cluster double height; // The height of the node UPCluster left, right; // Left and right children, or null double[] dmat; // Distances to lower-numbered nodes, or null public UPCluster(int lab, double[] dmat) { // Leaves = single sequences this.lab = lab + 1; card = 1; this.dmat = dmat; } public UPCluster(int lab, UPCluster left, UPCluster right, double height, double[] dmat) { this.lab = lab + 1; this.left = left; this.right = right; card = left.card + right.card; this.height = height; this.dmat = dmat; } public boolean live() { return dmat != null; } public void kill() { dmat = null; } public void print() { print(0); } void print(int n) { if (right != null) right.print(n + 6); indent(n); System.out.println("[" + lab + "] (" + (int)(100*height)/100.0 + ")"); if (left != null) left.print(n + 6); } void indent(int n) { for (int i=0; i= dimdjk || dijdkm == dimdjk && dijdkm >= dikdjm || dikdjm == dimdjk && dikdjm >= dijdkm)) { System.out.println("(i, j, k, m) = ("+i+","+j+","+k+","+m+")"); return false; } } return true; } } // Displaying and printing clusters or rooted trees class TreeFrame extends ClosableFrame { String title; Button printButton = new Button("Print tree"); TreeCanvas tc; public TreeFrame(String title, Cluster c) { super(title); this.title = title; tc = new TreeCanvas(c); add(tc, "Center"); Panel p = new Panel(); p.add(printButton); printButton.addActionListener(new buttonListener()); add(p, "South"); pack(); show(); } public void setCluster(Cluster c) { tc.setCluster(c); } public class buttonListener implements ActionListener { public void actionPerformed(ActionEvent e) { Toolkit t = getToolkit(); PrintJob pj = t.getPrintJob(TreeFrame.this, "Printing " + title, null); if (pj != null) { Graphics pg = pj.getGraphics(); printAll(pg); pg.dispose(); pj.end(); } } } } class TreeCanvas extends Canvas { Cluster c; public TreeCanvas(Cluster c) { this.c = c; } public void setCluster(Cluster c) { this.c = c; repaint(); } public void paint(Graphics g) { Dimension d = getSize(); if (c != null) c.draw(g, d.width, d.height); } public Dimension getPreferredSize() { return new Dimension(300, 300); } public Dimension getMinimumSize() { return getPreferredSize(); } } public class Match7 { public static void main(String[] args) { double[][] ds1 = { { }, { 3.5 }, { 17.0, 14.0 }, { 13.0, 13.0, 13.0 }, { 17.5, 16.5, 13.0, 5.0 } }; double[][] ds2 = { { }, { 0.3 }, { 0.5, 0.6 }, { 0.6, 0.5, 0.9 } }; UPGMA upclu = new UPGMA(ds1); new TreeFrame("UPGMA tree", upclu.getRoot()); NJ njclu = new NJ(ds2); new TreeFrame("Neighbour tree", njclu.getRoot()); } } class CloseListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } class ClosableFrame extends Frame { public ClosableFrame(String name) { super(name); addWindowListener(new CloseListener()); } }