JAL-4134 - refactor tree calculation code to work with binaryNode base type.
[jalview.git] / src / jalview / datamodel / BinaryNode.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.datamodel;
22
23 import java.awt.Color;
24
25 /**
26  * DOCUMENT ME!
27  * 
28  * @author $author$
29  * @version $Revision$
30  */
31 public class BinaryNode
32 {
33   Object element;
34
35   String name;
36
37   BinaryNode left;
38
39   BinaryNode right;
40
41   BinaryNode parent;
42
43   /** DOCUMENT ME!! */
44   public int bootstrap;
45
46   /** DOCUMENT ME!! */
47   public double dist;
48
49   /** DOCUMENT ME!! */
50   public int count;
51
52   /** DOCUMENT ME!! */
53   public double height;
54
55   /** DOCUMENT ME!! */
56   public float ycount;
57
58   /** DOCUMENT ME!! */
59   public Color color = Color.black;
60
61   /** DOCUMENT ME!! */
62   public boolean dummy = false;
63
64   /**
65    * Creates a new BinaryNode object.
66    */
67   public BinaryNode()
68   {
69     left = right = parent = null;
70     bootstrap = 0;
71   }
72
73   /**
74    * Creates a new BinaryNode object.
75    * 
76    * @param element
77    *          DOCUMENT ME!
78    * @param parent
79    *          DOCUMENT ME!
80    * @param name
81    *          DOCUMENT ME!
82    */
83   public BinaryNode(Object element, BinaryNode parent, String name)
84   {
85     this.element = element;
86     this.parent = parent;
87     this.name = name;
88
89     left = right = null;
90   }
91
92   /**
93    * DOCUMENT ME!
94    * 
95    * @return DOCUMENT ME!
96    */
97   public Object element()
98   {
99     return element;
100   }
101
102   /**
103    * DOCUMENT ME!
104    * 
105    * @param v
106    *          DOCUMENT ME!
107    * 
108    * @return DOCUMENT ME!
109    */
110   public Object setElement(Object v)
111   {
112     return element = v;
113   }
114
115   /**
116    * DOCUMENT ME!
117    * 
118    * @return DOCUMENT ME!
119    */
120   public BinaryNode left()
121   {
122     return left;
123   }
124
125   /**
126    * DOCUMENT ME!
127    * 
128    * @param n
129    *          DOCUMENT ME!
130    * 
131    * @return DOCUMENT ME!
132    */
133   public BinaryNode setLeft(BinaryNode n)
134   {
135     return left = n;
136   }
137
138   /**
139    * DOCUMENT ME!
140    * 
141    * @return DOCUMENT ME!
142    */
143   public BinaryNode right()
144   {
145     return right;
146   }
147
148   /**
149    * DOCUMENT ME!
150    * 
151    * @param n
152    *          DOCUMENT ME!
153    * 
154    * @return DOCUMENT ME!
155    */
156   public BinaryNode setRight(BinaryNode n)
157   {
158     return right = n;
159   }
160
161   /**
162    * DOCUMENT ME!
163    * 
164    * @return DOCUMENT ME!
165    */
166   public BinaryNode parent()
167   {
168     return parent;
169   }
170
171   /**
172    * DOCUMENT ME!
173    * 
174    * @param n
175    *          DOCUMENT ME!
176    * 
177    * @return DOCUMENT ME!
178    */
179   public BinaryNode setParent(BinaryNode n)
180   {
181     return parent = n;
182   }
183
184   /**
185    * DOCUMENT ME!
186    * 
187    * @return DOCUMENT ME!
188    */
189   public boolean isLeaf()
190   {
191     return (left == null) && (right == null);
192   }
193
194   /**
195    * attaches FIRST and SECOND node arguments as the LEFT and RIGHT children of
196    * this node (removing any old references) a null parameter DOES NOT mean that
197    * the pointer to the corresponding child node is set to NULL - you should use
198    * setChild(null), or detach() for this.
199    * 
200    */
201   public void SetChildren(BinaryNode leftchild, BinaryNode rightchild)
202   {
203     if (leftchild != null)
204     {
205       this.setLeft(leftchild);
206       leftchild.detach();
207       leftchild.setParent(this);
208     }
209
210     if (rightchild != null)
211     {
212       this.setRight(rightchild);
213       rightchild.detach();
214       rightchild.setParent(this);
215     }
216   }
217
218   /**
219    * Detaches the node from the binary tree, along with all its child nodes.
220    * 
221    * @return BinaryNode The detached node.
222    */
223   public BinaryNode detach()
224   {
225     if (this.parent != null)
226     {
227       if (this.parent.left == this)
228       {
229         this.parent.left = null;
230       }
231       else
232       {
233         if (this.parent.right == this)
234         {
235           this.parent.right = null;
236         }
237       }
238     }
239
240     this.parent = null;
241
242     return this;
243   }
244
245   /**
246    * Traverses up through the tree until a node with a free leftchild is
247    * discovered.
248    * 
249    * @return BinaryNode
250    */
251   public BinaryNode ascendLeft()
252   {
253     BinaryNode c = this;
254
255     do
256     {
257       c = c.parent();
258     } while ((c != null) && (c.left() != null) && !c.left().isLeaf());
259
260     return c;
261   }
262
263   /**
264    * Traverses up through the tree until a node with a free rightchild is
265    * discovered. Jalview builds trees by descent on the left, so this may be
266    * unused.
267    * 
268    * @return BinaryNode
269    */
270   public BinaryNode ascendRight()
271   {
272     BinaryNode c = this;
273
274     do
275     {
276       c = c.parent();
277     } while ((c != null) && (c.right() != null) && !c.right().isLeaf());
278
279     return c;
280   }
281
282   /**
283    * 
284    * set the display name
285    * 
286    * @param new
287    *          name
288    */
289   public void setName(String name)
290   {
291     this.name = name;
292   }
293
294   /**
295    * 
296    * 
297    * @return the display name for this node
298    */
299   public String getName()
300   {
301     return this.name;
302   }
303
304   /**
305    * set integer bootstrap value
306    * 
307    * @param boot
308    */
309   public void setBootstrap(int boot)
310   {
311     this.bootstrap = boot;
312   }
313
314   /**
315    * get bootstrap
316    * 
317    * @return integer value
318    */
319   public int getBootstrap()
320   {
321     return bootstrap;
322   }
323
324   /**
325    * ascends the tree but doesn't stop until a non-dummy node is discovered.
326    * 
327    */
328   public BinaryNode AscendTree()
329   {
330     BinaryNode c = this;
331   
332     do
333     {
334       c = c.parent();
335     } while ((c != null) && c.dummy);
336   
337     return c;
338   }
339 }