in progress
[jalview.git] / forester / java / src / org / forester / phylogeny / PhylogenyMethods.java
index 9ca9086..4a2115e 100644 (file)
@@ -30,6 +30,8 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -232,6 +234,164 @@ public class PhylogenyMethods {
         }
     }
 
+    final static public void sortNodeDescendents( final PhylogenyNode node, final DESCENDANT_SORT_PRIORITY pri ) {
+        class PhylogenyNodeSortTaxonomyPriority implements Comparator<PhylogenyNode> {
+
+            @Override
+            public int compare( final PhylogenyNode n1, final PhylogenyNode n2 ) {
+                if ( n1.getNodeData().isHasTaxonomy() && n2.getNodeData().isHasTaxonomy() ) {
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getScientificName() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getScientificName() ) ) ) {
+                        return n1.getNodeData().getTaxonomy().getScientificName().toLowerCase()
+                                .compareTo( n2.getNodeData().getTaxonomy().getScientificName().toLowerCase() );
+                    }
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getTaxonomyCode() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) {
+                        return n1.getNodeData().getTaxonomy().getTaxonomyCode()
+                                .compareTo( n2.getNodeData().getTaxonomy().getTaxonomyCode() );
+                    }
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getCommonName() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getCommonName() ) ) ) {
+                        return n1.getNodeData().getTaxonomy().getCommonName().toLowerCase()
+                                .compareTo( n2.getNodeData().getTaxonomy().getCommonName().toLowerCase() );
+                    }
+                }
+                if ( n1.getNodeData().isHasSequence() && n2.getNodeData().isHasSequence() ) {
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getName() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getName() ) ) ) {
+                        return n1.getNodeData().getSequence().getName().toLowerCase()
+                                .compareTo( n2.getNodeData().getSequence().getName().toLowerCase() );
+                    }
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getSymbol() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getSymbol() ) ) ) {
+                        return n1.getNodeData().getSequence().getSymbol()
+                                .compareTo( n2.getNodeData().getSequence().getSymbol() );
+                    }
+                    if ( ( n1.getNodeData().getSequence().getAccession() != null )
+                            && ( n2.getNodeData().getSequence().getAccession() != null )
+                            && !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getAccession().getValue() )
+                            && !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getAccession().getValue() ) ) {
+                        return n1.getNodeData().getSequence().getAccession().getValue()
+                                .compareTo( n2.getNodeData().getSequence().getAccession().getValue() );
+                    }
+                }
+                if ( ( !ForesterUtil.isEmpty( n1.getName() ) ) && ( !ForesterUtil.isEmpty( n2.getName() ) ) ) {
+                    return n1.getName().toLowerCase().compareTo( n2.getName().toLowerCase() );
+                }
+                return 0;
+            }
+        }
+        class PhylogenyNodeSortSequencePriority implements Comparator<PhylogenyNode> {
+
+            @Override
+            public int compare( final PhylogenyNode n1, final PhylogenyNode n2 ) {
+                if ( n1.getNodeData().isHasSequence() && n2.getNodeData().isHasSequence() ) {
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getName() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getName() ) ) ) {
+                        return n1.getNodeData().getSequence().getName().toLowerCase()
+                                .compareTo( n2.getNodeData().getSequence().getName().toLowerCase() );
+                    }
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getSymbol() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getSymbol() ) ) ) {
+                        return n1.getNodeData().getSequence().getSymbol()
+                                .compareTo( n2.getNodeData().getSequence().getSymbol() );
+                    }
+                    if ( ( n1.getNodeData().getSequence().getAccession() != null )
+                            && ( n2.getNodeData().getSequence().getAccession() != null )
+                            && !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getAccession().getValue() )
+                            && !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getAccession().getValue() ) ) {
+                        return n1.getNodeData().getSequence().getAccession().getValue()
+                                .compareTo( n2.getNodeData().getSequence().getAccession().getValue() );
+                    }
+                }
+                if ( n1.getNodeData().isHasTaxonomy() && n2.getNodeData().isHasTaxonomy() ) {
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getScientificName() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getScientificName() ) ) ) {
+                        return n1.getNodeData().getTaxonomy().getScientificName().toLowerCase()
+                                .compareTo( n2.getNodeData().getTaxonomy().getScientificName().toLowerCase() );
+                    }
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getTaxonomyCode() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) {
+                        return n1.getNodeData().getTaxonomy().getTaxonomyCode()
+                                .compareTo( n2.getNodeData().getTaxonomy().getTaxonomyCode() );
+                    }
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getCommonName() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getCommonName() ) ) ) {
+                        return n1.getNodeData().getTaxonomy().getCommonName().toLowerCase()
+                                .compareTo( n2.getNodeData().getTaxonomy().getCommonName().toLowerCase() );
+                    }
+                }
+                if ( ( !ForesterUtil.isEmpty( n1.getName() ) ) && ( !ForesterUtil.isEmpty( n2.getName() ) ) ) {
+                    return n1.getName().toLowerCase().compareTo( n2.getName().toLowerCase() );
+                }
+                return 0;
+            }
+        }
+        class PhylogenyNodeSortNodeNamePriority implements Comparator<PhylogenyNode> {
+
+            @Override
+            public int compare( final PhylogenyNode n1, final PhylogenyNode n2 ) {
+                if ( ( !ForesterUtil.isEmpty( n1.getName() ) ) && ( !ForesterUtil.isEmpty( n2.getName() ) ) ) {
+                    return n1.getName().toLowerCase().compareTo( n2.getName().toLowerCase() );
+                }
+                if ( n1.getNodeData().isHasTaxonomy() && n2.getNodeData().isHasTaxonomy() ) {
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getScientificName() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getScientificName() ) ) ) {
+                        return n1.getNodeData().getTaxonomy().getScientificName().toLowerCase()
+                                .compareTo( n2.getNodeData().getTaxonomy().getScientificName().toLowerCase() );
+                    }
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getTaxonomyCode() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) {
+                        return n1.getNodeData().getTaxonomy().getTaxonomyCode()
+                                .compareTo( n2.getNodeData().getTaxonomy().getTaxonomyCode() );
+                    }
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getCommonName() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getCommonName() ) ) ) {
+                        return n1.getNodeData().getTaxonomy().getCommonName().toLowerCase()
+                                .compareTo( n2.getNodeData().getTaxonomy().getCommonName().toLowerCase() );
+                    }
+                }
+                if ( n1.getNodeData().isHasSequence() && n2.getNodeData().isHasSequence() ) {
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getName() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getName() ) ) ) {
+                        return n1.getNodeData().getSequence().getName().toLowerCase()
+                                .compareTo( n2.getNodeData().getSequence().getName().toLowerCase() );
+                    }
+                    if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getSymbol() ) )
+                            && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getSymbol() ) ) ) {
+                        return n1.getNodeData().getSequence().getSymbol()
+                                .compareTo( n2.getNodeData().getSequence().getSymbol() );
+                    }
+                    if ( ( n1.getNodeData().getSequence().getAccession() != null )
+                            && ( n2.getNodeData().getSequence().getAccession() != null )
+                            && !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getAccession().getValue() )
+                            && !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getAccession().getValue() ) ) {
+                        return n1.getNodeData().getSequence().getAccession().getValue()
+                                .compareTo( n2.getNodeData().getSequence().getAccession().getValue() );
+                    }
+                }
+                return 0;
+            }
+        }
+        Comparator<PhylogenyNode> c;
+        switch ( pri ) {
+            case SEQUENCE:
+                c = new PhylogenyNodeSortSequencePriority();
+                break;
+            case NODE_NAME:
+                c = new PhylogenyNodeSortNodeNamePriority();
+                break;
+            default:
+                c = new PhylogenyNodeSortTaxonomyPriority();
+        }
+        final List<PhylogenyNode> descs = node.getDescendants();
+        Collections.sort( descs, c );
+        int i = 0;
+        for( final PhylogenyNode desc : descs ) {
+            node.setChildNode( i++, desc );
+        }
+    }
+
     final static public void transferNodeNameToField( final Phylogeny phy,
                                                       final PhylogenyMethods.PhylogenyNodeField field ) {
         final PhylogenyNodeIterator it = phy.iteratorPostorder();
@@ -1400,6 +1560,49 @@ public class PhylogenyMethods {
         return nodes_to_delete.size();
     }
 
+    /**
+     * 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
+     * @param pri 
+     */
+    public static void orderAppearance( final PhylogenyNode n,
+                                        final boolean order,
+                                        final boolean order_ext_alphabetically,
+                                        final DESCENDANT_SORT_PRIORITY pri ) {
+        if ( n.isExternal() ) {
+            return;
+        }
+        else {
+            PhylogenyNode temp = null;
+            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 );
+            }
+            else if ( order_ext_alphabetically ) {
+                boolean all_ext = true;
+                for( final PhylogenyNode i : n.getDescendants() ) {
+                    if ( !i.isExternal() ) {
+                        all_ext = false;
+                        break;
+                    }
+                }
+                if ( all_ext ) {
+                    PhylogenyMethods.sortNodeDescendents( n, pri );
+                }
+            }
+            for( int i = 0; i < n.getNumberOfDescendants(); ++i ) {
+                orderAppearance( n.getChildNode( i ), order, order_ext_alphabetically, pri );
+            }
+        }
+    }
+
     public static enum PhylogenyNodeField {
         CLADE_NAME,
         TAXONOMY_CODE,
@@ -1414,4 +1617,8 @@ public class PhylogenyMethods {
     public static enum TAXONOMY_EXTRACTION {
         NO, YES, PFAM_STYLE_ONLY;
     }
+
+    public static enum DESCENDANT_SORT_PRIORITY {
+        TAXONOMY, SEQUENCE, NODE_NAME;
+    }
 }