Clover icon

Coverage Report

  1. Project Clover database Mon Nov 11 2024 20:42:03 GMT
  2. Package jalview.datamodel

File BinaryNode.java

 

Coverage histogram

../../img/srcFileCovDistChart5.png
42% of files have more coverage

Code metrics

34
81
30
1
464
228
54
0.67
2.7
30
1.8

Classes

Class Line # Actions
BinaryNode 31 81 54
0.4689655346.9%
 

Contributing tests

This file is covered by 14 tests. .

Source view

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    * Represent a node in a binary tree
27    *
28    * @author $mclamp (probably!)$
29    * @version $Revision$
30    */
 
31    public class BinaryNode<T>
32    {
33    T element;
34   
35    String name;
36   
37    String label = null;
38   
39    BinaryNode<T> left;
40   
41    BinaryNode<T> right;
42   
43    BinaryNode<T> parent;
44   
45    /** Bootstrap value */
46    public int bootstrap;
47   
48    /** DOCUMENT ME!! */
49    public double dist;
50   
51    /** DOCUMENT ME!! */
52    public int count;
53   
54    /** DOCUMENT ME!! */
55    public double height;
56   
57    /** DOCUMENT ME!! */
58    public float ycount;
59   
60    /** DOCUMENT ME!! */
61    public Color color = Color.black;
62   
63    /**
64    * if true, node is created to simulate polytomy between parent and its 3 or
65    * more children
66    */
67    public boolean dummy = false;
68   
69    /**
70    * Creates a new BinaryNode object.
71    */
 
72  563 toggle public BinaryNode()
73    {
74  563 left = right = parent = null;
75  563 bootstrap = 0;
76  563 dist = 0;
77    }
78   
79    /**
80    * Creates a new BinaryNode object.
81    *
82    * @param element
83    * DOCUMENT ME!
84    * @param parent
85    * DOCUMENT ME!
86    * @param name
87    * DOCUMENT ME!
88    */
 
89  396 toggle public BinaryNode(T element, BinaryNode<T> parent, String name,
90    double dist)
91    {
92  396 this();
93  396 this.element = element;
94  396 this.parent = parent;
95  396 this.name = name;
96  396 this.dist = dist;
97    }
98   
 
99  396 toggle public BinaryNode(T element, BinaryNode<T> parent, String name,
100    double dist, int bootstrap)
101    {
102  396 this(element, parent, name, dist);
103  396 this.bootstrap = bootstrap;
104    }
105   
 
106  396 toggle public BinaryNode(T val, BinaryNode<T> parent, String name, double dist,
107    int bootstrap, boolean dummy)
108    {
109  396 this(val, parent, name, dist, bootstrap);
110  396 this.dummy = dummy;
111    }
112   
113    /**
114    * DOCUMENT ME!
115    *
116    * @return DOCUMENT ME!
117    */
 
118  114 toggle public T element()
119    {
120  114 return element;
121    }
122   
123    /**
124    * DOCUMENT ME!
125    *
126    * @param v
127    * DOCUMENT ME!
128    *
129    * @return DOCUMENT ME!
130    */
 
131  283 toggle public T setElement(T v)
132    {
133  283 return element = v;
134    }
135   
136    /**
137    * DOCUMENT ME!
138    *
139    * @return DOCUMENT ME!
140    */
 
141  5487 toggle public BinaryNode<T> left()
142    {
143  5487 return left;
144    }
145   
146    /**
147    * DOCUMENT ME!
148    *
149    * @param n
150    * DOCUMENT ME!
151    *
152    * @return DOCUMENT ME!
153    */
 
154  260 toggle public BinaryNode<T> setLeft(BinaryNode<T> n)
155    {
156  260 return left = n;
157    }
158   
159    /**
160    * DOCUMENT ME!
161    *
162    * @return DOCUMENT ME!
163    */
 
164  3785 toggle public BinaryNode<T> right()
165    {
166  3785 return right;
167    }
168   
169    /**
170    * DOCUMENT ME!
171    *
172    * @param n
173    * DOCUMENT ME!
174    *
175    * @return DOCUMENT ME!
176    */
 
177  280 toggle public BinaryNode<T> setRight(BinaryNode<T> n)
178    {
179  280 return right = n;
180    }
181   
182    /**
183    * DOCUMENT ME!
184    *
185    * @return DOCUMENT ME!
186    */
 
187  2120 toggle public BinaryNode<T> parent()
188    {
189  2120 return parent;
190    }
191   
192    /**
193    * DOCUMENT ME!
194    *
195    * @param n
196    * DOCUMENT ME!
197    *
198    * @return DOCUMENT ME!
199    */
 
200  144 toggle public BinaryNode<T> setParent(BinaryNode<T> n)
201    {
202  144 return parent = n;
203    }
204   
205    /**
206    * DOCUMENT ME!
207    *
208    * @return DOCUMENT ME!
209    */
 
210  278 toggle public boolean isLeaf()
211    {
212  278 return (left == null) && (right == null);
213    }
214   
215    /**
216    * attaches FIRST and SECOND node arguments as the LEFT and RIGHT children of
217    * this node (removing any old references) a null parameter DOES NOT mean that
218    * the pointer to the corresponding child node is set to NULL - you should use
219    * setChild(null), or detach() for this.
220    *
221    */
 
222  0 toggle public void SetChildren(BinaryNode<T> leftchild, BinaryNode<T> rightchild)
223    {
224  0 if (leftchild != null)
225    {
226  0 this.setLeft(leftchild);
227  0 leftchild.detach();
228  0 leftchild.setParent(this);
229    }
230   
231  0 if (rightchild != null)
232    {
233  0 this.setRight(rightchild);
234  0 rightchild.detach();
235  0 rightchild.setParent(this);
236    }
237    }
238   
239    /**
240    * Detaches the node from the binary tree, along with all its child nodes.
241    *
242    * @return BinaryNode The detached node.
243    */
 
244  20 toggle public BinaryNode<T> detach()
245    {
246  20 if (this.parent != null)
247    {
248  20 if (this.parent.left == this)
249    {
250  0 this.parent.left = null;
251    }
252    else
253    {
254  20 if (this.parent.right == this)
255    {
256  20 this.parent.right = null;
257    }
258    }
259    }
260   
261  20 this.parent = null;
262   
263  20 return this;
264    }
265   
266    /**
267    * Traverses up through the tree until a node with a free leftchild is
268    * discovered.
269    *
270    * @return BinaryNode
271    */
 
272  0 toggle public BinaryNode<T> ascendLeft()
273    {
274  0 BinaryNode<T> c = this;
275   
276  0 do
277    {
278  0 c = c.parent();
279  0 } while ((c != null) && (c.left() != null) && !c.left().isLeaf());
280   
281  0 return c;
282    }
283   
284    /**
285    * Traverses up through the tree until a node with a free rightchild is
286    * discovered. Jalview builds trees by descent on the left, so this may be
287    * unused.
288    *
289    * @return BinaryNode
290    */
 
291  0 toggle public BinaryNode<T> ascendRight()
292    {
293  0 BinaryNode<T> c = this;
294   
295  0 do
296    {
297  0 c = c.parent();
298  0 } while ((c != null) && (c.right() != null) && !c.right().isLeaf());
299   
300  0 return c;
301    }
302   
303    /**
304    *
305    * set the display name
306    *
307    * @param new
308    * name
309    */
 
310  263 toggle public void setName(String name)
311    {
312  263 this.name = name;
313    }
314   
315    /**
316    *
317    *
318    * @return the display name for this node
319    */
 
320  802 toggle public String getName()
321    {
322  802 return this.name;
323    }
324   
325    /**
326    * set integer bootstrap value
327    *
328    * @param boot
329    */
 
330  188 toggle public void setBootstrap(int boot)
331    {
332  188 this.bootstrap = boot;
333    }
334   
335    /**
336    * get bootstrap
337    *
338    * @return integer value
339    */
 
340  234 toggle public int getBootstrap()
341    {
342  234 return bootstrap;
343    }
344   
345    /**
346    * @param dummy
347    * true if node is created for the representation of polytomous trees
348    */
 
349  134 toggle public boolean isDummy()
350    {
351  134 return dummy;
352    }
353   
354    /**
355    * DOCUMENT ME!
356    *
357    * @param newstate
358    * DOCUMENT ME!
359    *
360    * @return DOCUMENT ME!
361    */
 
362  0 toggle public boolean setDummy(boolean newstate)
363    {
364  0 boolean oldstate = dummy;
365  0 dummy = newstate;
366   
367  0 return oldstate;
368    }
369   
370    /**
371    * check if there's a label to show
372    *
373    * @return true if non-empty/null string
374    */
 
375  192 toggle public boolean hasLabel()
376    {
377  192 return label != null && !label.isEmpty();
378    }
379   
 
380  0 toggle public String getLabel()
381    {
382  0 return label;
383    }
384   
 
385  0 toggle public void setLabel(String label)
386    {
387  0 this.label = label;
388    }
389   
390    /**
391    * ascends the tree but doesn't stop until a non-dummy node is discovered.
392    *
393    */
 
394  188 toggle public BinaryNode<T> AscendTree()
395    {
396  188 BinaryNode<T> c = this;
397   
398  188 do
399    {
400  188 c = c.parent();
401  188 } while ((c != null) && c.dummy);
402   
403  188 return c;
404    }
405   
 
406  192 toggle public String getDisplayName()
407    {
408  192 if (name != null && !name.isBlank())
409    {
410   
411  192 if (hasLabel())
412    {
413  0 return getName() + "|" + label;
414    }
415  192 return name;
416    }
417  0 return hasLabel() ? label : "";
418    }
419   
420    // cache this
421    private String branchIdentifier = null;
422   
423    /**
424    * get a concatenation of all node names under this node
425    */
 
426  0 toggle public String getBranchIdentifier()
427    {
428  0 if (branchIdentifier == null)
429    {
430  0 setBranchIdentifier(true);
431    }
432  0 return branchIdentifier;
433    }
434   
 
435  0 toggle protected void setBranchIdentifier(boolean force)
436    {
437    // only set if previously set, or asked for
438  0 if (branchIdentifier == null && !force)
439    {
440  0 return;
441    }
442  0 StringBuilder sb = new StringBuilder();
443  0 if (getName() != null)
444    {
445  0 sb.append(getName());
446    }
447  0 if (left() != null)
448    {
449  0 sb.append("::L:");
450  0 sb.append(left().getBranchIdentifier());
451    }
452  0 if (right() != null)
453    {
454  0 sb.append("::R:");
455  0 sb.append(right().getBranchIdentifier());
456    }
457  0 branchIdentifier = sb.toString();
458    // reset ancestors
459  0 if (parent() != null)
460    {
461  0 parent.setBranchIdentifier(false);
462    }
463    }
464    }