org.forester.phylogeny.PhylogenyBranch Maven / Gradle / Ivy
// $Id:
// FORESTER -- software libraries and applications
// for evolutionary biology research and applications.
//
// Copyright (C) 2008-2009 Christian M. Zmasek
// Copyright (C) 2008-2009 Burnham Institute for Medical Research
// Copyright (C) 2000-2001 Washington University School of Medicine
// and Howard Hughes Medical Institute
// All rights reserved
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
//
// Contact: phylosoft @ gmail . com
// WWW: https://sites.google.com/site/cmzmasek/home/software/forester
package org.forester.phylogeny;
import org.forester.phylogeny.data.PhylogenyData;
/*
* @author Christian M. Zmasek
*/
public class PhylogenyBranch {
private final PhylogenyNode _node_1;
private final PhylogenyNode _node_2;
private PhylogenyData _data;
private final boolean _is_directed;
private boolean _towards_1;
public PhylogenyBranch( final PhylogenyNode first_node, final PhylogenyNode second_node ) {
if ( ( first_node == null ) || ( second_node == null ) ) {
throw new IllegalArgumentException( "Attempt to create a branch with a null node" );
}
_node_1 = first_node;
_node_2 = second_node;
_is_directed = false;
}
public PhylogenyBranch( final PhylogenyNode first_node,
final PhylogenyNode second_node,
final boolean direction_towards_first ) {
if ( ( first_node == null ) || ( second_node == null ) ) {
throw new IllegalArgumentException( "Attempt to create a branch with a null node" );
}
_node_1 = first_node;
_node_2 = second_node;
_is_directed = true;
_towards_1 = direction_towards_first;
}
@Override
public boolean equals( final Object obj ) {
if ( this == obj ) {
return true;
}
if ( obj == null ) {
return false;
}
if ( getClass() != obj.getClass() ) {
return false;
}
final PhylogenyBranch other = ( PhylogenyBranch ) obj;
return hashCode() == other.hashCode();
}
public PhylogenyNode getConnectedNode( final PhylogenyNode node ) throws IllegalArgumentException {
if ( node == _node_1 ) {
return _node_2;
}
else if ( node == _node_2 ) {
return _node_1;
}
else {
throw new IllegalArgumentException( "Attempt to get " + "connected node on branch with node which is "
+ "not connected by the branch" );
}
}
public PhylogenyData getData() {
return _data;
}
public PhylogenyNode getFirstNode() {
return _node_1;
}
public PhylogenyNode getSecondNode() {
return _node_2;
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
final int node_1_hc = _node_1.hashCode();
final int node_2_hc = _node_2.hashCode();
int hc_1 = 0;
int hc_2 = 0;
if ( !_is_directed ) {
if ( node_1_hc > node_2_hc ) {
hc_1 = node_2_hc;
hc_2 = node_1_hc;
}
else {
hc_1 = node_1_hc;
hc_2 = node_2_hc;
}
}
else {
if ( _towards_1 ) {
hc_1 = node_2_hc;
hc_2 = node_1_hc;
}
else {
hc_1 = node_1_hc;
hc_2 = node_2_hc;
}
}
result = ( PRIME * result ) + ( ( _data == null ) ? 0 : _data.hashCode() );
result = ( PRIME * result ) + ( _is_directed ? 1231 : 1237 );
result = ( PRIME * result ) + hc_1;
result = ( PRIME * result ) + hc_2;
return result;
}
public boolean isDirected() {
return _is_directed;
}
public boolean isDirectionTowards( final PhylogenyNode node ) throws RuntimeException {
if ( !isDirected() ) {
throw new RuntimeException( "Attempt to get direction of undirected branch" );
}
return ( ( node == _node_1 ) && _towards_1 );
}
public void setDirectionTowards( final PhylogenyNode node ) {
_towards_1 = node == _node_1;
}
@Override
public String toString() {
if ( isDirected() ) {
if ( isDirectionTowards( getFirstNode() ) ) {
return ( getSecondNode().getName() + " -> " + getFirstNode().getName() );
}
else {
return ( getFirstNode().getName() + " -> " + getSecondNode().getName() );
}
}
else {
return ( getFirstNode().getName() + " -- " + getSecondNode().getName() );
}
}
}