in progress...
[jalview.git] / forester / java / src / org / forester / sdi / SDIR.java
index f75f6f8..bc395c3 100644 (file)
@@ -7,7 +7,7 @@
 // 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
 // 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: www.phylosoft.org/forester
+// WWW: https://sites.google.com/site/cmzmasek/home/software/forester
 
 package org.forester.sdi;
 
@@ -45,11 +45,11 @@ import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
  * <li>Mapping cost L <li>Phylogeny height - which is the largest distance from
  * root to external node (minimizing of which is the same as "midpoint rooting")
  * </ul>
- * 
+ *
  * @see SDIse
- * 
+ *
  * @see SDI
- * 
+ *
  * @author Christian M. Zmasek
  */
 public class SDIR {
@@ -76,7 +76,7 @@ public class SDIR {
     /**
      * Returns the number of differently rooted trees which minimize the
      * (rooting) "criterion" - as determined by method "infer".
-     * 
+     *
      * @see #infer(Phylogeny,Phylogeny,boolean,boolean,boolean,boolean,int,boolean)
      * @return number of differently rooted trees which minimized the criterion
      */
@@ -97,7 +97,7 @@ public class SDIR {
      * not necessarily zero.
      * <p>
      * (Last modified: 01/22/00)
-     * 
+     *
      * @see #infer(Phylogeny,Phylogeny,boolean,boolean,boolean,boolean,int,boolean)
      * @return the minimal difference in tree heights -- IF calculated by
      *         "infer"
@@ -113,7 +113,7 @@ public class SDIR {
      * <B>IMPORTANT </B>: If the tree is not rooted by minimizing the sum of
      * duplications or the mapping cost L, then this number is NOT NECESSARILY
      * the MINIMAL number of duplications.
-     * 
+     *
      * @see #infer(Phylogeny,Phylogeny,boolean,boolean,boolean,boolean,int,boolean)
      * @return (minimal) number of duplications
      */
@@ -126,7 +126,7 @@ public class SDIR {
      * minimize_mapping_cost is set to true.
      * <p>
      * (Last modified: 11/07/00)
-     * 
+     *
      * @see #infer(Phylogeny,Phylogeny,boolean,boolean,boolean,boolean,int,boolean)
      * @return the minimal mapping cost "L" -- IF calculated by "infer"
      */
@@ -142,7 +142,7 @@ public class SDIR {
      * first criterion.
      * <p>
      * (Last modified: 01/12/00)
-     * 
+     *
      * @see #infer(Phylogeny,Phylogeny,boolean,boolean,boolean,boolean,int,boolean)
      * @return the minimal tree height -- IF calculated by "infer"
      */
@@ -153,7 +153,7 @@ public class SDIR {
     /**
      * Returns the sum of times (in ms) needed to run method infer of class SDI.
      * Final variable TIME needs to be set to true.
-     * 
+     *
      * @return sum of times (in ms) needed to run method infer of class SDI
      */
     public long getTimeSumSDI() {
@@ -188,7 +188,7 @@ public class SDIR {
      * </ul>
      * <p>
      * (Last modified: 10/01/01)
-     * 
+     *
      * @param gene_tree
      *            a binary (except deepest node) gene Phylogeny
      * @param species_tree
@@ -212,6 +212,7 @@ public class SDIR {
      *            Array) must be no lower than 1
      * @return array of rooted Trees with duplication vs. speciation assigned if
      *         return_trees is set to true, null otherwise
+     * @throws SDIException
      */
     public Phylogeny[] infer( final Phylogeny gene_tree,
                               final Phylogeny species_tree,
@@ -219,9 +220,9 @@ public class SDIR {
                               boolean minimize_sum_of_dup,
                               final boolean minimize_height,
                               final boolean return_trees,
-                              int max_trees_to_return ) {
+                              int max_trees_to_return ) throws SDIException {
         init();
-        SDIse sdise = null;
+        SDI sdise = null;
         final ArrayList<Phylogeny> trees = new ArrayList<Phylogeny>();
         Phylogeny[] tree_array = null;
         List<PhylogenyBranch> branches = null;
@@ -265,26 +266,23 @@ public class SDIR {
             final PhylogenyNode n = iter.next();
             if ( n.isRoot() ) {
                 if ( ( n.getNumberOfDescendants() != 2 ) && ( n.getNumberOfDescendants() != 3 ) ) {
-                    throw new IllegalArgumentException( "attempt to run SDI on gene tree with "
-                            + n.getNumberOfDescendants() + " child nodes at its root" );
+                    throw new SDIException( "gene tree has " + n.getNumberOfDescendants() + " descendents at its root" );
                 }
             }
             else if ( !n.isExternal() && ( n.getNumberOfDescendants() != 2 ) ) {
-                throw new IllegalArgumentException( "attempt to run SDI on gene tree which is not completely binary [found node with "
-                        + n.getNumberOfDescendants() + " child nodes]" );
+                throw new SDIException( "gene tree is not completely binary" );
             }
         }
         for( final PhylogenyNodeIterator iter = species_tree.iteratorPostorder(); iter.hasNext(); ) {
             final PhylogenyNode n = iter.next();
             if ( !n.isExternal() && ( n.getNumberOfDescendants() != 2 ) ) {
-                throw new IllegalArgumentException( "attempt to run SDI with a species tree which is not completely binary (after stripping) [found node with "
-                        + n.getNumberOfDescendants() + " child nodes]" );
+                throw new SDIException( "species tree (after stripping) is not completely binary" );
             }
         }
         g.reRoot( g.getFirstExternalNode() );
         branches = SDIR.getBranchesInPreorder( g );
         if ( minimize_mapping_cost || minimize_sum_of_dup ) {
-            sdise = new SDIse( g, species_tree );
+            sdise = new SDI( g, species_tree );
             duplications = sdise.getDuplicationsSum();
         }
         final Set<PhylogenyBranch> used_root_placements = new HashSet<PhylogenyBranch>();
@@ -294,7 +292,7 @@ public class SDIR {
             prev_root_c2 = prev_root.getChildNode2();
             prev_root_was_dup = prev_root.isDuplication();
             final PhylogenyBranch current_branch = branches.get( j );
-            g.reRoot( current_branch );
+            GSDIR.reRoot( current_branch, g );
             if ( minimize_mapping_cost || minimize_sum_of_dup ) {
                 duplications = sdise.updateM( prev_root_was_dup, prev_root_c1, prev_root_c2 );
             }
@@ -420,7 +418,7 @@ public class SDIR {
                     height = height__diff[ 0 ];
                     diff = height__diff[ 1 ];
                     if ( Math.abs( diff ) < SDIR.ZERO_DIFF ) {
-                        sdise = new SDIse( g, species_tree );
+                        sdise = new SDI( g, species_tree );
                         min_duplications = sdise.getDuplicationsSum();
                         min_height = height;
                         min_diff = Math.abs( diff );
@@ -496,8 +494,8 @@ public class SDIR {
             branches.add( new PhylogenyBranch( t.getRoot().getChildNode1(), t.getRoot().getChildNode2() ) );
             return branches;
         }
-        final Set<Integer> one = new HashSet<Integer>();
-        final Set<Integer> two = new HashSet<Integer>();
+        final Set<Long> one = new HashSet<Long>();
+        final Set<Long> two = new HashSet<Long>();
         PhylogenyNode node = t.getRoot();
         while ( !node.isRoot() || !two.contains( node.getId() ) ) {
             if ( !node.isExternal() && !two.contains( node.getId() ) ) {
@@ -545,10 +543,10 @@ public class SDIR {
         double diff = 0.0;
         double height = 0.0;
         final double[] height_diff = new double[ 2 ];
-        final double l0 = t.calculateSubtreeHeight( t.getRoot().getChildNode( 0 ) );
-        final double l1 = t.calculateSubtreeHeight( t.getRoot().getChildNode( 1 ) );
+        final double l0 = t.calculateSubtreeHeight( t.getRoot().getChildNode( 0 ), false );
+        final double l1 = t.calculateSubtreeHeight( t.getRoot().getChildNode( 1 ), false );
         diff = l0 - l1;
-        height = t.getHeight();
+        height = t.calculateHeight(false);
         if ( d > 0.0 ) {
             if ( ( 2 * d ) > Math.abs( diff ) ) {
                 child0.setDistanceToParent( d - ( diff / 2.0 ) );