permissions = sandbox
[jalview.git] / forester / java / src / org / forester / phylogeny / Phylogeny.java
index db6804a..3d94dd7 100644 (file)
@@ -38,6 +38,7 @@ import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Vector;
 
+import org.forester.io.parsers.nhx.NHXParser;
 import org.forester.io.writers.PhylogenyWriter;
 import org.forester.phylogeny.PhylogenyNode.NH_CONVERSION_SUPPORT_VALUE_STYLE;
 import org.forester.phylogeny.data.BranchData;
@@ -47,6 +48,8 @@ import org.forester.phylogeny.data.PhylogenyDataUtil;
 import org.forester.phylogeny.data.Sequence;
 import org.forester.phylogeny.data.SequenceRelation;
 import org.forester.phylogeny.data.SequenceRelation.SEQUENCE_RELATION_TYPE;
+import org.forester.phylogeny.factories.ParserBasedPhylogenyFactory;
+import org.forester.phylogeny.factories.PhylogenyFactory;
 import org.forester.phylogeny.iterators.ExternalForwardIterator;
 import org.forester.phylogeny.iterators.LevelOrderTreeIterator;
 import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
@@ -83,7 +86,7 @@ public class Phylogeny {
     /**
      * Adds this Phylogeny to the list of child nodes of PhylogenyNode parent
      * and sets the parent of this to parent.
-     * 
+     *
      * @param n
      *            the PhylogenyNode to add
      */
@@ -123,7 +126,7 @@ public class Phylogeny {
     /**
      * This calculates the height of the subtree emanating at n for rooted,
      * tree-shaped phylogenies
-     * 
+     *
      * @param n
      *            the root-node of a subtree
      * @return the height of the subtree emanating at n
@@ -219,9 +222,9 @@ public class Phylogeny {
     /**
      * Need to call clearHashIdToNodeMap() afterwards (not done automatically
      * to allow client multiple deletions in linear time).
-     * Need to call 'recalculateNumberOfExternalDescendants(boolean)' after this 
+     * Need to call 'recalculateNumberOfExternalDescendants(boolean)' after this
      * if tree is to be displayed.
-     * 
+     *
      * @param remove_us the parent node of the subtree to be deleted
      */
     public void deleteSubtree( final PhylogenyNode remove_us, final boolean collapse_resulting_node_with_one_desc ) {
@@ -258,12 +261,12 @@ public class Phylogeny {
                     final int pi = p.getChildNodeIndex();
                     if ( removed_node.isFirstChildNode() ) {
                         p.getChildNode( 1 ).setDistanceToParent( PhylogenyMethods.addPhylogenyDistances( p
-                                .getDistanceToParent(), p.getChildNode( 1 ).getDistanceToParent() ) );
+                                                                                                         .getDistanceToParent(), p.getChildNode( 1 ).getDistanceToParent() ) );
                         pp.setChildNode( pi, p.getChildNode( 1 ) );
                     }
                     else {
                         p.getChildNode( 0 ).setDistanceToParent( PhylogenyMethods.addPhylogenyDistances( p
-                                .getDistanceToParent(), p.getChildNode( 0 ).getDistanceToParent() ) );
+                                                                                                         .getDistanceToParent(), p.getChildNode( 0 ).getDistanceToParent() ) );
                         pp.setChildNode( pi, p.getChildNode( 0 ) );
                     }
                 }
@@ -304,11 +307,16 @@ public class Phylogeny {
         return _distance_unit;
     }
 
+    public final static Phylogeny createInstanceFromNhxString( final String nhx ) throws IOException {
+        final PhylogenyFactory factory = ParserBasedPhylogenyFactory.getInstance();
+        return factory.create( nhx, new NHXParser() )[ 0 ];
+    }
+
     /**
-     * 
+     *
      * Warning. The order of the returned nodes is random
      * -- and hence cannot be relied on.
-     * 
+     *
      * @return Unordered set of PhylogenyNode
      */
     public List<PhylogenyNode> getExternalNodes() {
@@ -334,7 +342,7 @@ public class Phylogeny {
     /**
      * Sets the number of duplications of this Phylogeny (int). A value of -1
      * indicates that the number of duplications is unknown.
-     * 
+     *
      * @param clean_nh
      *            set to true for clean NH format
      */
@@ -365,7 +373,7 @@ public class Phylogeny {
      * height is the longest distance from the root to an external node. Please
      * note. Child nodes of collapsed nodes are ignored -- which is useful for
      * display purposes but might be misleading for other applications.
-     * 
+     *
      * @return the height for rooted, tree-shaped phylogenies
      */
     public double getHeight() {
@@ -403,7 +411,7 @@ public class Phylogeny {
     /**
      * Returns a PhylogenyNode of this Phylogeny which has a matching name.
      * Throws an Exception if seqname is not present in this or not unique.
-     * 
+     *
      * @param name
      *            name (String) of PhylogenyNode to find
      * @return PhylogenyNode with matchin name
@@ -424,7 +432,7 @@ public class Phylogeny {
 
     /**
      * This is time-inefficient since it runs a iterator each time it is called.
-     * 
+     *
      */
     public int getNodeCount() {
         if ( isEmpty() ) {
@@ -440,7 +448,7 @@ public class Phylogeny {
     /**
      * Returns a List with references to all Nodes of this Phylogeny which have
      * a matching name.
-     * 
+     *
      * @param name
      *            name (String) of Nodes to find
      * @return Vector of references to Nodes of this Phylogeny with matching
@@ -489,6 +497,20 @@ public class Phylogeny {
         return nodes;
     }
 
+    public List<PhylogenyNode> getNodesViaGeneName( final String seq_name ) {
+        if ( isEmpty() ) {
+            return null;
+        }
+        final List<PhylogenyNode> nodes = new ArrayList<PhylogenyNode>();
+        for( final PhylogenyNodeIterator iter = iteratorPreorder(); iter.hasNext(); ) {
+            final PhylogenyNode n = iter.next();
+            if ( n.getNodeData().isHasSequence() && n.getNodeData().getSequence().getGeneName().equals( seq_name ) ) {
+                nodes.add( n );
+            }
+        }
+        return nodes;
+    }
+
     public List<PhylogenyNode> getNodesViaTaxonomyCode( final String taxonomy_code ) {
         if ( isEmpty() ) {
             return null;
@@ -507,7 +529,7 @@ public class Phylogeny {
     /**
      * Returns a Vector with references to all Nodes of this Phylogeny which
      * have a matching species name.
-     * 
+     *
      * @param specname
      *            species name (String) of Nodes to find
      * @return Vector of references to Nodes of this Phylogeny with matching
@@ -607,7 +629,7 @@ public class Phylogeny {
      * <p>
      * (Last modified: 11/22/00) Olivier CHABROL :
      * olivier.chabrol@univ-provence.fr
-     * 
+     *
      * @param n
      *            external PhylogenyNode whose orthologs are to be returned
      * @return Vector of references to all orthologous Nodes of PhylogenyNode n
@@ -636,11 +658,11 @@ public class Phylogeny {
             if ( node.isDuplication() && isContains( taxIdList, taxonomyCodeRangeList ) ) {
                 if ( node.getChildNode1() == prev ) {
                     v.addAll( getNodeByTaxonomyID( searchNodeSpeciesId, node.getChildNode2()
-                            .getAllExternalDescendants() ) );
+                                                   .getAllExternalDescendants() ) );
                 }
                 else {
                     v.addAll( getNodeByTaxonomyID( searchNodeSpeciesId, node.getChildNode1()
-                            .getAllExternalDescendants() ) );
+                                                   .getAllExternalDescendants() ) );
                 }
             }
         }
@@ -689,7 +711,7 @@ public class Phylogeny {
     /**
      * Returns whether this is a completely binary tree (i.e. all internal nodes
      * are bifurcations).
-     * 
+     *
      */
     public boolean isCompletelyBinary() {
         if ( isEmpty() ) {
@@ -706,7 +728,7 @@ public class Phylogeny {
 
     /**
      * Checks whether a Phylogeny object is deleted (or empty).
-     * 
+     *
      * @return true if the tree is deleted (or empty), false otherwise
      */
     public boolean isEmpty() {
@@ -748,7 +770,7 @@ public class Phylogeny {
      * Resets the ID numbers of the nodes of this Phylogeny in level order,
      * starting with start_label (for the root). <br>
      * WARNING. After this method has been called, node IDs are no longer
-     * unique. 
+     * unique.
      */
     public void levelOrderReID() {
         if ( isEmpty() ) {
@@ -788,7 +810,7 @@ public class Phylogeny {
      * (Re)counts the number of children for each PhylogenyNode of this
      * Phylogeny. As an example, this method needs to be called after a
      * Phylogeny has been reRooted and it is to be displayed.
-     * 
+     *
      * @param consider_collapsed_nodes
      *            set to true to take into account collapsed nodes (collapsed
      *            nodes have 1 child).
@@ -821,7 +843,7 @@ public class Phylogeny {
      * <p>
      * <li>recalculateNumberOfExternalDescendants(boolean)
      * <li>recalculateAndReset()
-     * 
+     *
      * @param id
      *            ID (int) of PhylogenyNode of this Phylogeny
      */
@@ -830,35 +852,6 @@ public class Phylogeny {
     }
 
     /**
-     * Places the root of this Phylogeny on Branch b. The new root is always
-     * placed on the middle of the branch b.
-     * 
-     */
-    public void reRoot( final PhylogenyBranch b ) {
-        final PhylogenyNode n1 = b.getFirstNode();
-        final PhylogenyNode n2 = b.getSecondNode();
-        if ( n1.isExternal() ) {
-            reRoot( n1 );
-        }
-        else if ( n2.isExternal() ) {
-            reRoot( n2 );
-        }
-        else if ( ( n2 == n1.getChildNode1() ) || ( n2 == n1.getChildNode2() ) ) {
-            reRoot( n2 );
-        }
-        else if ( ( n1 == n2.getChildNode1() ) || ( n1 == n2.getChildNode2() ) ) {
-            reRoot( n1 );
-        }
-        else if ( ( n1.getParent() != null ) && n1.getParent().isRoot()
-                && ( ( n1.getParent().getChildNode1() == n2 ) || ( n1.getParent().getChildNode2() == n2 ) ) ) {
-            reRoot( n1 );
-        }
-        else {
-            throw new IllegalArgumentException( "reRoot( Branch b ): b is not a branch." );
-        }
-    }
-
-    /**
      * Places the root of this Phylogeny on the parent branch PhylogenyNode n.
      * The new root is always placed on the middle of the branch.
      * <p>
@@ -870,7 +863,7 @@ public class Phylogeny {
      * </ul>
      * <p>
      * (Last modified: 10/01/01)
-     * 
+     *
      * @param n
      *            PhylogenyNode of this Phylogeny\
      */
@@ -1002,7 +995,7 @@ public class Phylogeny {
                 }
                 else {
                     node.setDistanceToParent( ( c.getDistanceToParent() >= 0.0 ? c.getDistanceToParent() : 0.0 )
-                            + ( node.getDistanceToParent() >= 0.0 ? node.getDistanceToParent() : 0.0 ) );
+                                              + ( node.getDistanceToParent() >= 0.0 ? node.getDistanceToParent() : 0.0 ) );
                 }
                 if ( c.getBranchDataDirectly() != null ) {
                     node.setBranchData( ( BranchData ) c.getBranchDataDirectly().copy() );
@@ -1105,14 +1098,12 @@ public class Phylogeny {
     }
 
     public String toNewHampshire() {
-        return toNewHampshire( false, NH_CONVERSION_SUPPORT_VALUE_STYLE.NONE );
+        return toNewHampshire( NH_CONVERSION_SUPPORT_VALUE_STYLE.NONE );
     }
 
-    public String toNewHampshire( final boolean simple_nh,
-                                  final NH_CONVERSION_SUPPORT_VALUE_STYLE nh_conversion_support_style ) {
+    public String toNewHampshire( final NH_CONVERSION_SUPPORT_VALUE_STYLE nh_conversion_support_style ) {
         try {
-            return new PhylogenyWriter().toNewHampshire( this, simple_nh, true, nh_conversion_support_style )
-                    .toString();
+            return new PhylogenyWriter().toNewHampshire( this, true, nh_conversion_support_style ).toString();
         }
         catch ( final IOException e ) {
             throw new Error( "this should not have happend: " + e.getMessage() );
@@ -1155,7 +1146,7 @@ public class Phylogeny {
     // ---------------------------------------------------------
     /**
      * Converts this Phylogeny to a New Hampshire X (String) representation.
-     * 
+     *
      * @return New Hampshire X (String) representation of this
      * @see #toNewHampshireX()
      */
@@ -1189,7 +1180,7 @@ public class Phylogeny {
     /**
      * Return Node by TaxonomyId Olivier CHABROL :
      * olivier.chabrol@univ-provence.fr
-     * 
+     *
      * @param taxonomyID
      *            search taxonomy identifier
      * @param nodes
@@ -1209,7 +1200,7 @@ public class Phylogeny {
     /**
      * List all species contains in all leaf under a node Olivier CHABROL :
      * olivier.chabrol@univ-provence.fr
-     * 
+     *
      * @param node
      *            PhylogenyNode whose sub node species are returned
      * @return species contains in all leaf under the param node
@@ -1232,7 +1223,7 @@ public class Phylogeny {
      * Create a map [<PhylogenyNode, List<String>], the list contains the
      * species contains in all leaf under phylogeny node Olivier CHABROL :
      * olivier.chabrol@univ-provence.fr
-     * 
+     *
      * @param node
      *            the tree root node
      * @param map
@@ -1255,7 +1246,7 @@ public class Phylogeny {
     /**
      * Util method to check if all element of a list is contains in the
      * rangeList. Olivier CHABROL : olivier.chabrol@univ-provence.fr
-     * 
+     *
      * @param list
      *            list to be check
      * @param rangeList