searhc of domains only when domains are shown!
[jalview.git] / forester / java / src / org / forester / phylogeny / PhylogenyMethods.java
index 94db898..6678e70 100644 (file)
@@ -47,6 +47,7 @@ import org.forester.phylogeny.data.BranchColor;
 import org.forester.phylogeny.data.BranchWidth;
 import org.forester.phylogeny.data.Confidence;
 import org.forester.phylogeny.data.DomainArchitecture;
+import org.forester.phylogeny.data.Event;
 import org.forester.phylogeny.data.Identifier;
 import org.forester.phylogeny.data.PhylogenyDataUtil;
 import org.forester.phylogeny.data.Sequence;
@@ -61,10 +62,9 @@ import org.forester.util.ForesterUtil;
 
 public class PhylogenyMethods {
 
-    private static PhylogenyMethods _instance      = null;
-    private final Set<Integer>      _temp_hash_set = new HashSet<Integer>();
-    private PhylogenyNode           _farthest_1    = null;
-    private PhylogenyNode           _farthest_2    = null;
+    private static PhylogenyMethods _instance   = null;
+    private PhylogenyNode           _farthest_1 = null;
+    private PhylogenyNode           _farthest_2 = null;
 
     private PhylogenyMethods() {
         // Hidden constructor.
@@ -114,6 +114,10 @@ public class PhylogenyMethods {
         return farthest_d;
     }
 
+    final public static Event getEventAtLCA( final PhylogenyNode n1, final PhylogenyNode n2 ) {
+        return obtainLCA( n1, n2 ).getNodeData().getEvent();
+    }
+
     @Override
     public Object clone() throws CloneNotSupportedException {
         throw new CloneNotSupportedException();
@@ -127,6 +131,24 @@ public class PhylogenyMethods {
         return _farthest_2;
     }
 
+    final public static void deleteNonOrthologousExternalNodes( final Phylogeny phy, final PhylogenyNode n ) {
+        if ( n.isInternal() ) {
+            throw new IllegalArgumentException( "node is not external" );
+        }
+        final ArrayList<PhylogenyNode> to_delete = new ArrayList<PhylogenyNode>();
+        for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
+            final PhylogenyNode i = it.next();
+            if ( !PhylogenyMethods.getEventAtLCA( n, i ).isSpeciation() ) {
+                to_delete.add( i );
+            }
+        }
+        for( final PhylogenyNode d : to_delete ) {
+            phy.deleteSubtree( d, true );
+        }
+        phy.clearHashIdToNodeMap();
+        phy.externalNodesHaveChanged();
+    }
+
     /**
      * Returns the LCA of PhylogenyNodes node1 and node2.
      * 
@@ -135,19 +157,19 @@ public class PhylogenyMethods {
      * @param node2
      * @return LCA of node1 and node2
      */
-    public PhylogenyNode obtainLCA( final PhylogenyNode node1, final PhylogenyNode node2 ) {
-        _temp_hash_set.clear();
+    public final static PhylogenyNode obtainLCA( final PhylogenyNode node1, final PhylogenyNode node2 ) {
+        final HashSet<Integer> ids_set = new HashSet<Integer>();
         PhylogenyNode n1 = node1;
         PhylogenyNode n2 = node2;
-        _temp_hash_set.add( n1.getId() );
+        ids_set.add( n1.getId() );
         while ( !n1.isRoot() ) {
             n1 = n1.getParent();
-            _temp_hash_set.add( n1.getId() );
+            ids_set.add( n1.getId() );
         }
-        while ( !_temp_hash_set.contains( n2.getId() ) && !n2.isRoot() ) {
+        while ( !ids_set.contains( n2.getId() ) && !n2.isRoot() ) {
             n2 = n2.getParent();
         }
-        if ( !_temp_hash_set.contains( n2.getId() ) ) {
+        if ( !ids_set.contains( n2.getId() ) ) {
             throw new IllegalArgumentException( "attempt to get LCA of two nodes which do not share a common root" );
         }
         return n2;
@@ -598,6 +620,17 @@ public class PhylogenyMethods {
         return max;
     }
 
+    public static int countNumberOfPolytomies( final Phylogeny phy ) {
+        int count = 0;
+        for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) {
+            final PhylogenyNode n = iter.next();
+            if ( !n.isExternal() && ( n.getNumberOfDescendants() > 2 ) ) {
+                count++;
+            }
+        }
+        return count;
+    }
+
     public static DescriptiveStatistics calculatNumberOfDescendantsPerNodeStatistics( final Phylogeny phy ) {
         final DescriptiveStatistics stats = new BasicDescriptiveStatistics();
         for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) {
@@ -740,11 +773,12 @@ public class PhylogenyMethods {
     }
 
     public static void deleteExternalNodesNegativeSelection( final Set<Integer> to_delete, final Phylogeny phy ) {
-        phy.hashIDs();
+        phy.clearHashIdToNodeMap();
         for( final Integer id : to_delete ) {
             phy.deleteSubtree( phy.getNode( id ), true );
         }
-        phy.hashIDs();
+        phy.clearHashIdToNodeMap();
+        phy.externalNodesHaveChanged();
     }
 
     public static void deleteExternalNodesNegativeSelection( final String[] node_names_to_delete, final Phylogeny p )
@@ -765,6 +799,8 @@ public class PhylogenyMethods {
                 p.deleteSubtree( n, true );
             }
         }
+        p.clearHashIdToNodeMap();
+        p.externalNodesHaveChanged();
     }
 
     public static void deleteExternalNodesPositiveSelection( final Set<Taxonomy> species_to_keep, final Phylogeny phy ) {
@@ -781,9 +817,8 @@ public class PhylogenyMethods {
                 throw new IllegalArgumentException( "node " + n.getId() + " has no taxonomic data" );
             }
         }
-        phy.hashIDs();
+        phy.clearHashIdToNodeMap();
         phy.externalNodesHaveChanged();
-        //  deleteExternalNodesNegativeSelection( to_delete, phy );
     }
 
     public static List<String> deleteExternalNodesPositiveSelection( final String[] node_names_to_keep,
@@ -977,12 +1012,12 @@ public class PhylogenyMethods {
         if ( !node.getNodeData().isHasTaxonomy() ) {
             return "";
         }
-        if ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
-            return node.getNodeData().getTaxonomy().getTaxonomyCode();
-        }
         else if ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) {
             return node.getNodeData().getTaxonomy().getScientificName();
         }
+        if ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
+            return node.getNodeData().getTaxonomy().getTaxonomyCode();
+        }
         else {
             return node.getNodeData().getTaxonomy().getCommonName();
         }
@@ -1275,6 +1310,8 @@ public class PhylogenyMethods {
         }
         if ( remove_me.isExternal() ) {
             phylogeny.deleteSubtree( remove_me, false );
+            phylogeny.clearHashIdToNodeMap();
+            phylogeny.externalNodesHaveChanged();
         }
         else {
             final PhylogenyNode parent = remove_me.getParent();
@@ -1286,7 +1323,7 @@ public class PhylogenyMethods {
                                                                  desc.getDistanceToParent() ) );
             }
             remove_me.setParent( null );
-            phylogeny.setIdHash( null );
+            phylogeny.clearHashIdToNodeMap();
             phylogeny.externalNodesHaveChanged();
         }
     }
@@ -1294,7 +1331,8 @@ public class PhylogenyMethods {
     public static List<PhylogenyNode> searchData( final String query,
                                                   final Phylogeny phy,
                                                   final boolean case_sensitive,
-                                                  final boolean partial ) {
+                                                  final boolean partial,
+                                                  final boolean search_domains ) {
         final List<PhylogenyNode> nodes = new ArrayList<PhylogenyNode>();
         if ( phy.isEmpty() || ( query == null ) ) {
             return nodes;
@@ -1354,7 +1392,7 @@ public class PhylogenyMethods {
                               partial ) ) {
                 match = true;
             }
-            if ( !match && node.getNodeData().isHasSequence()
+            if ( search_domains && !match && node.getNodeData().isHasSequence()
                     && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
                 final DomainArchitecture da = node.getNodeData().getSequence().getDomainArchitecture();
                 I: for( int i = 0; i < da.getNumberOfDomains(); ++i ) {
@@ -1390,7 +1428,8 @@ public class PhylogenyMethods {
     public static List<PhylogenyNode> searchDataLogicalAnd( final String[] queries,
                                                             final Phylogeny phy,
                                                             final boolean case_sensitive,
-                                                            final boolean partial ) {
+                                                            final boolean partial,
+                                                            final boolean search_domains ) {
         final List<PhylogenyNode> nodes = new ArrayList<PhylogenyNode>();
         if ( phy.isEmpty() || ( queries == null ) || ( queries.length < 1 ) ) {
             return nodes;
@@ -1453,7 +1492,7 @@ public class PhylogenyMethods {
                                   partial ) ) {
                     match = true;
                 }
-                if ( !match && node.getNodeData().isHasSequence()
+                if ( search_domains && !match && node.getNodeData().isHasSequence()
                         && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
                     final DomainArchitecture da = node.getNodeData().getSequence().getDomainArchitecture();
                     I: for( int i = 0; i < da.getNumberOfDomains(); ++i ) {
@@ -1478,22 +1517,6 @@ public class PhylogenyMethods {
                             break I;
                         }
                     }
-                    //                    final String[] bcp_ary = node.getNodeData().getBinaryCharacters()
-                    //                            .getPresentCharactersAsStringArray();
-                    //                    I: for( final String bc : bcp_ary ) {
-                    //                        if ( match( bc, query, case_sensitive, partial ) ) {
-                    //                            match = true;
-                    //                            break I;
-                    //                        }
-                    //                    }
-                    //                    final String[] bcg_ary = node.getNodeData().getBinaryCharacters()
-                    //                            .getGainedCharactersAsStringArray();
-                    //                    I: for( final String bc : bcg_ary ) {
-                    //                        if ( match( bc, query, case_sensitive, partial ) ) {
-                    //                            match = true;
-                    //                            break I;
-                    //                        }
-                    //                    }
                 }
                 if ( !match ) {
                     all_matched = false;
@@ -1602,6 +1625,8 @@ public class PhylogenyMethods {
         for( final PhylogenyNode phylogenyNode : nodes_to_delete ) {
             to_be_stripped.deleteSubtree( phylogenyNode, true );
         }
+        to_be_stripped.clearHashIdToNodeMap();
+        to_be_stripped.externalNodesHaveChanged();
         return nodes_to_delete.size();
     }