lca work
[jalview.git] / forester / java / src / org / forester / phylogeny / PhylogenyBranch.java
1 // $Id:
2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
4 //
5 // Copyright (C) 2008-2009 Christian M. Zmasek
6 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
7 // Copyright (C) 2000-2001 Washington University School of Medicine
8 // and Howard Hughes Medical Institute
9 // All rights reserved
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 //
25 // Contact: phylosoft @ gmail . com
26 // WWW: www.phylosoft.org/forester
27
28 package org.forester.phylogeny;
29
30 import org.forester.phylogeny.data.PhylogenyData;
31
32 /*
33  * @author Christian M. Zmasek
34  */
35 public class PhylogenyBranch implements Edge {
36
37     private final PhylogenyNode _node_1;
38     private final PhylogenyNode _node_2;
39     private PhylogenyData       _data;
40     private final boolean       _is_directed;
41     private boolean             _towards_1;
42
43     public PhylogenyBranch( final PhylogenyNode first_node, final PhylogenyNode second_node ) {
44         if ( ( first_node == null ) || ( second_node == null ) ) {
45             throw new IllegalArgumentException( "Attempt to create a branch with a null node" );
46         }
47         _node_1 = first_node;
48         _node_2 = second_node;
49         _is_directed = false;
50     }
51
52     public PhylogenyBranch( final PhylogenyNode first_node,
53                             final PhylogenyNode second_node,
54                             final boolean direction_towards_first ) {
55         if ( ( first_node == null ) || ( second_node == null ) ) {
56             throw new IllegalArgumentException( "Attempt to create a branch with a null node" );
57         }
58         _node_1 = first_node;
59         _node_2 = second_node;
60         _is_directed = true;
61         _towards_1 = direction_towards_first;
62     }
63
64     @Override
65     public boolean equals( final Object obj ) {
66         if ( this == obj ) {
67             return true;
68         }
69         if ( obj == null ) {
70             return false;
71         }
72         if ( getClass() != obj.getClass() ) {
73             return false;
74         }
75         final PhylogenyBranch other = ( PhylogenyBranch ) obj;
76         return hashCode() == other.hashCode();
77     }
78
79     public PhylogenyNode getConnectedNode( final PhylogenyNode node ) throws IllegalArgumentException {
80         if ( node == _node_1 ) {
81             return _node_2;
82         }
83         else if ( node == _node_2 ) {
84             return _node_1;
85         }
86         else {
87             throw new IllegalArgumentException( "Attempt to get " + "connected node on branch with node which is "
88                     + "not connected by the branch" );
89         }
90     }
91
92     @Override
93     public PhylogenyData getData() {
94         return _data;
95     }
96
97     @Override
98     public PhylogenyNode getFirstNode() {
99         return _node_1;
100     }
101
102     @Override
103     public PhylogenyNode getSecondNode() {
104         return _node_2;
105     }
106
107     @Override
108     public int hashCode() {
109         final int PRIME = 31;
110         int result = 1;
111         final int node_1_hc = _node_1.hashCode();
112         final int node_2_hc = _node_2.hashCode();
113         int hc_1 = 0;
114         int hc_2 = 0;
115         if ( !_is_directed ) {
116             if ( node_1_hc > node_2_hc ) {
117                 hc_1 = node_2_hc;
118                 hc_2 = node_1_hc;
119             }
120             else {
121                 hc_1 = node_1_hc;
122                 hc_2 = node_2_hc;
123             }
124         }
125         else {
126             if ( _towards_1 ) {
127                 hc_1 = node_2_hc;
128                 hc_2 = node_1_hc;
129             }
130             else {
131                 hc_1 = node_1_hc;
132                 hc_2 = node_2_hc;
133             }
134         }
135         result = PRIME * result + ( ( _data == null ) ? 0 : _data.hashCode() );
136         result = PRIME * result + ( _is_directed ? 1231 : 1237 );
137         result = PRIME * result + hc_1;
138         result = PRIME * result + hc_2;
139         return result;
140     }
141
142     public boolean isDirected() {
143         return _is_directed;
144     }
145
146     public boolean isDirectionTowards( final PhylogenyNode node ) throws RuntimeException {
147         if ( !isDirected() ) {
148             throw new RuntimeException( "Attempt to get direction of undirected branch" );
149         }
150         return ( ( node == _node_1 ) && _towards_1 );
151     }
152
153     public void setDirectionTowards( final PhylogenyNode node ) {
154         _towards_1 = node == _node_1;
155     }
156
157     @Override
158     public String toString() {
159         if ( isDirected() ) {
160             if ( isDirectionTowards( getFirstNode() ) ) {
161                 return ( getSecondNode().getName() + " -> " + getFirstNode().getName() );
162             }
163             else {
164                 return ( getFirstNode().getName() + " -> " + getSecondNode().getName() );
165             }
166         }
167         else {
168             return ( getFirstNode().getName() + " -- " + getSecondNode().getName() );
169         }
170     }
171 }