searhc of domains only when domains are shown!
[jalview.git] / forester / java / src / org / forester / phylogeny / Phylogeny.java
index 91f714d..a4102d2 100644 (file)
@@ -68,7 +68,7 @@ public class Phylogeny {
     private Confidence                                          _confidence;
     private Identifier                                          _identifier;
     private boolean                                             _rerootable;
-    private HashMap<Integer, PhylogenyNode>                     _idhash;
+    private HashMap<Integer, PhylogenyNode>                     _id_to_node_map;
     private List<PhylogenyNode>                                 _external_nodes_set;
     private Collection<Sequence>                                _sequenceRelationQueries;
     private Collection<SequenceRelation.SEQUENCE_RELATION_TYPE> _relevant_sequence_relation_types;
@@ -213,7 +213,7 @@ public class Phylogeny {
     }
 
     /**
-     * Need the delete and/or rehash _idhash (not done automatically
+     * Need to call clearHashIdToNodeMap() afterwards (not done automatically
      * to allow client multiple deletions in linear time).
      * Need to call 'recalculateNumberOfExternalDescendants(boolean)' after this 
      * if tree is to be displayed.
@@ -221,14 +221,13 @@ public class Phylogeny {
      * @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 ) {
-        if ( isEmpty() ) {
+        if ( isEmpty() || ( remove_us.isRoot() && ( getNumberOfExternalNodes() != 1 ) ) ) {
             return;
         }
-        if ( remove_us.isRoot() ) {
+        if ( remove_us.isRoot() && ( getNumberOfExternalNodes() == 1 ) ) {
             init();
-            return;
         }
-        if ( !collapse_resulting_node_with_one_desc ) {
+        else if ( !collapse_resulting_node_with_one_desc ) {
             remove_us.getParent().removeChildNode( remove_us );
         }
         else {
@@ -269,8 +268,7 @@ public class Phylogeny {
                 }
             }
         }
-        remove_us.setParent( null );
-        setIdHash( null );
+        remove_us.removeConnections();
         externalNodesHaveChanged();
     }
 
@@ -377,11 +375,8 @@ public class Phylogeny {
         return _identifier;
     }
 
-    // ---------------------------------------------------------
-    // Modification of Phylogeny topology and Phylogeny appearance
-    // ---------------------------------------------------------
-    private HashMap<Integer, PhylogenyNode> getIdHash() {
-        return _idhash;
+    private HashMap<Integer, PhylogenyNode> getIdToNodeMap() {
+        return _id_to_node_map;
     }
 
     /**
@@ -393,29 +388,16 @@ public class Phylogeny {
 
     /**
      * Finds the PhylogenyNode of this Phylogeny which has a matching ID number.
-     * Takes O(n) time. After method hashIDs() has been called it runs in
-     * constant time.
-     * 
-     * @param id
-     *            ID number (int) of the PhylogenyNode to find
      * @return PhylogenyNode with matching ID, null if not found
      */
     public PhylogenyNode getNode( final int id ) throws NoSuchElementException {
         if ( isEmpty() ) {
             throw new NoSuchElementException( "attempt to get node in an empty phylogeny" );
         }
-        if ( _idhash != null ) {
-            return _idhash.get( id );
+        if ( ( getIdToNodeMap() == null ) || getIdToNodeMap().isEmpty() ) {
+            reHashIdToNodeMap();
         }
-        else {
-            for( final PhylogenyNodeIterator iter = iteratorPreorder(); iter.hasNext(); ) {
-                final PhylogenyNode node = iter.next();
-                if ( node.getId() == id ) {
-                    return node;
-                }
-            }
-        }
-        return null;
+        return getIdToNodeMap().get( id );
     }
 
     /**
@@ -725,17 +707,21 @@ public class Phylogeny {
      * constant time. Important: The user is responsible for calling this method
      * (again) after this Phylogeny has been changed/created/renumbered.
      */
-    public void hashIDs() {
+    private void reHashIdToNodeMap() {
         if ( isEmpty() ) {
             return;
         }
-        setIdHash( new HashMap<Integer, PhylogenyNode>() );
+        setIdToNodeMap( new HashMap<Integer, PhylogenyNode>() );
         for( final PhylogenyNodeIterator iter = iteratorPreorder(); iter.hasNext(); ) {
             final PhylogenyNode node = iter.next();
-            getIdHash().put( node.getId(), node );
+            getIdToNodeMap().put( node.getId(), node );
         }
     }
 
+    public void clearHashIdToNodeMap() {
+        setIdToNodeMap( null );
+    }
+
     /**
      * Deletes this Phylogeny.
      */
@@ -746,7 +732,7 @@ public class Phylogeny {
         _description = "";
         _type = "";
         _distance_unit = "";
-        _idhash = null;
+        _id_to_node_map = null;
         _confidence = null;
         _identifier = null;
         _rerootable = true;
@@ -850,7 +836,7 @@ public class Phylogeny {
         if ( isEmpty() ) {
             return;
         }
-        _idhash = null;
+        _id_to_node_map = null;
         int max = 0;
         for( final PhylogenyNodeIterator it = iteratorPreorder(); it.hasNext(); ) {
             final PhylogenyNode node = it.next();
@@ -867,51 +853,11 @@ public class Phylogeny {
         PhylogenyNode.setNodeCount( max + 1 );
     }
 
-    /**
-     * Arranges the order of childern for each node of this Phylogeny in such a
-     * way that either the branch with more children is on top (right) or on
-     * bottom (left), dependent on the value of boolean order.
-     * 
-     * @param order
-     *            decides in which direction to order
-     */
-    public void orderAppearance( final boolean order ) throws RuntimeException {
-        if ( !isTree() ) {
-            throw new FailedConditionCheckException( "Attempt to order appearance on phylogeny which is not tree-like." );
-        }
-        if ( isEmpty() ) {
-            return;
-        }
-        orderAppearanceHelper( getRoot(), order );
-    }
-
-    // Helper method for "orderAppearance(boolean)".
-    // Traverses this Phylogeny recusively.
-    private void orderAppearanceHelper( final PhylogenyNode n, final boolean order ) {
-        if ( n.isExternal() ) {
-            return;
-        }
-        else {
-            PhylogenyNode temp = null;
-            // FIXME
-            if ( ( n.getNumberOfDescendants() == 2 )
-                    && ( n.getChildNode1().getNumberOfExternalNodes() != n.getChildNode2().getNumberOfExternalNodes() )
-                    && ( ( n.getChildNode1().getNumberOfExternalNodes() < n.getChildNode2().getNumberOfExternalNodes() ) == order ) ) {
-                temp = n.getChildNode1();
-                n.setChild1( n.getChildNode2() );
-                n.setChild2( temp );
-            }
-            for( int i = 0; i < n.getNumberOfDescendants(); ++i ) {
-                orderAppearanceHelper( n.getChildNode( i ), order );
-            }
-        }
-    }
-
     public void preOrderReId() {
         if ( isEmpty() ) {
             return;
         }
-        setIdHash( null );
+        setIdToNodeMap( null );
         int i = PhylogenyNode.getNodeCount();
         for( final PhylogenyNodeIterator it = iteratorPreorder(); it.hasNext(); ) {
             it.next().setId( i++ );
@@ -1206,8 +1152,8 @@ public class Phylogeny {
         _identifier = identifier;
     }
 
-    void setIdHash( final HashMap<Integer, PhylogenyNode> idhash ) {
-        _idhash = idhash;
+    private void setIdToNodeMap( final HashMap<Integer, PhylogenyNode> idhash ) {
+        _id_to_node_map = idhash;
     }
 
     /**
@@ -1256,28 +1202,6 @@ public class Phylogeny {
         _type = type;
     }
 
-    /**
-     * Swaps the the two childern of a PhylogenyNode node of this Phylogeny.
-     * <p>
-     * (Last modified: 06/13/01)
-     * 
-     * @param node
-     *            a PhylogenyNode of this Phylogeny
-     */
-    public void swapChildren( final PhylogenyNode node ) throws RuntimeException {
-        if ( !isTree() ) {
-            throw new FailedConditionCheckException( "Attempt to swap children on phylogeny which is not tree-like." );
-        }
-        if ( isEmpty() || node.isExternal() || ( node.getNumberOfDescendants() < 2 ) ) {
-            return;
-        }
-        final PhylogenyNode first = node.getFirstChildNode();
-        for( int i = 1; i < node.getNumberOfDescendants(); ++i ) {
-            node.setChildNode( i - 1, node.getChildNode( i ) );
-        }
-        node.setChildNode( node.getNumberOfDescendants() - 1, first );
-    } // swapChildren( PhylogenyNode )
-
     public String toNewHampshire() {
         return toNewHampshire( false, NH_CONVERSION_SUPPORT_VALUE_STYLE.NONE );
     }
@@ -1311,6 +1235,10 @@ public class Phylogeny {
         }
     }
 
+    public String toNexus() {
+        return toNexus( NH_CONVERSION_SUPPORT_VALUE_STYLE.NONE );
+    }
+
     public String toPhyloXML( final int phyloxml_level ) {
         try {
             return new PhylogenyWriter().toPhyloXML( this, phyloxml_level ).toString();