In progress...
authorcmzmasek <chris.zma@outlook.com>
Fri, 21 Jul 2017 19:54:34 +0000 (12:54 -0700)
committercmzmasek <chris.zma@outlook.com>
Fri, 21 Jul 2017 19:54:34 +0000 (12:54 -0700)
forester/java/src/org/forester/application/cladinator.java [new file with mode: 0644]
forester/java/src/org/forester/archaeopteryx/TreePanel.java
forester/java/src/org/forester/test/Test.java
forester/java/src/org/forester/util/ForesterUtil.java

diff --git a/forester/java/src/org/forester/application/cladinator.java b/forester/java/src/org/forester/application/cladinator.java
new file mode 100644 (file)
index 0000000..9e9c945
--- /dev/null
@@ -0,0 +1,153 @@
+// $Id:
+// FORESTER -- software libraries and applications
+// for evolutionary biology research and applications.
+//
+// Copyright (C) 2008-2009 Christian M. Zmasek
+// Copyright (C) 2008-2009 Burnham Institute for Medical Research
+// 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
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// 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: https://sites.google.com/site/cmzmasek/home/software/forester
+
+package org.forester.application;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.forester.io.parsers.PhylogenyParser;
+import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException;
+import org.forester.io.parsers.util.ParserUtils;
+import org.forester.io.writers.PhylogenyWriter;
+import org.forester.phylogeny.Phylogeny;
+import org.forester.phylogeny.PhylogenyMethods;
+import org.forester.phylogeny.PhylogenyNode;
+import org.forester.phylogeny.data.Taxonomy;
+import org.forester.phylogeny.factories.ParserBasedPhylogenyFactory;
+import org.forester.phylogeny.factories.PhylogenyFactory;
+import org.forester.util.CommandLineArguments;
+import org.forester.util.ForesterUtil;
+
+public class cladinator {
+
+    final static private String PRG_NAME      = "cladinator";
+    final static private String PRG_VERSION   = "0.100";
+    final static private String PRG_DATE      = "170721";
+    final static private String PRG_DESC      = "clades within clades";
+    final static private String E_MAIL        = "phyloxml@gmail.com";
+    final static private String WWW           = "https://sites.google.com/site/cmzmasek/home/software/forester";
+    final static private String HELP_OPTION_1 = "help";
+    final static private String HELP_OPTION_2 = "h";
+
+    public static void main( final String args[] ) {
+        try {
+            ForesterUtil.printProgramInformation( PRG_NAME,
+                                                  PRG_DESC,
+                                                  PRG_VERSION,
+                                                  PRG_DATE,
+                                                  E_MAIL,
+                                                  WWW,
+                                                  ForesterUtil.getForesterLibraryInformation() );
+            CommandLineArguments cla = null;
+            try {
+                cla = new CommandLineArguments( args );
+            }
+            catch ( final Exception e ) {
+                ForesterUtil.fatalError( PRG_NAME, e.getMessage() );
+            }
+            if ( cla.isOptionSet( HELP_OPTION_1 ) || cla.isOptionSet( HELP_OPTION_2 ) ) {
+                System.out.println();
+                print_help();
+                System.exit( 0 );
+            }
+            else if ( ( args.length != 2 ) ) {
+                System.out.println();
+                System.out.println( "Wrong number of arguments." );
+                System.out.println();
+                print_help();
+                System.exit( -1 );
+            }
+            final List<String> allowed_options = new ArrayList<String>();
+            final File intreefile = cla.getFile( 0 );
+            final String query = cla.getName( 1 );
+            System.out.println( "Input tree: " + intreefile );
+            System.out.println( "Query:      " + query );
+            Phylogeny p = null;
+            try {
+                final PhylogenyFactory factory = ParserBasedPhylogenyFactory.getInstance();
+                final PhylogenyParser pp = ParserUtils.createParserDependingOnFileType( intreefile, true );
+                p = factory.create( intreefile, pp )[ 0 ];
+            }
+            catch ( final Exception e ) {
+                System.out.println( "\nCould not read \"" + intreefile + "\" [" + e.getMessage() + "]\n" );
+                System.exit( -1 );
+            }
+            execute( p, query );
+        }
+        catch ( final Exception e ) {
+            ForesterUtil.fatalError( PRG_NAME, e.getMessage() );
+        }
+    }
+
+    private static void execute( final Phylogeny p, final String query ) {
+        final PhylogenyNode qnode = p.getNode( query );
+        if ( qnode.isRoot() ) {
+            throw new IllegalStateException( "Unexpected error: Query " + query
+                    + " is root. This should have never happened" );
+        }
+        if ( qnode.getParent().isRoot() ) {
+            throw new IllegalStateException( "Unexpected error: Parent of query " + query
+                    + " is root. This should have never happened" );
+        }
+        final PhylogenyNode qnode_pp = qnode.getParent().getParent();
+        final List<PhylogenyNode> qnode_ext_nodes = qnode_pp.getAllExternalDescendants();
+        final int lec_ext_nodes = qnode_ext_nodes.size() - 1;
+        final int p_ext_nodes = p.getNumberOfExternalNodes() - 1;
+        final double lec_ratio = ( 100.0 * lec_ext_nodes ) / p_ext_nodes;
+        final List<String> qnode_ext_nodes_names = new ArrayList<String>();
+        for( final PhylogenyNode qnode_ext_node : qnode_ext_nodes ) {
+            String name = qnode_ext_node.getName();
+            if ( ForesterUtil.isEmptyTrimmed( name ) ) {
+                throw new IllegalArgumentException( "external node(s) with empty names found" );
+            }
+            name = name.trim();
+            if ( !name.equals( query ) ) {
+                qnode_ext_nodes_names.add( name );
+            }
+        }
+        final String greatest_common_prefix = ForesterUtil.greatestCommonPrefix( qnode_ext_nodes_names );
+        System.out.println( );
+        System.out.println( "Results:");
+        if ( greatest_common_prefix.length() < 1 ) {
+            System.out.println( "WARNING: No greatest common prefix" );
+        }
+        else {
+            System.out.println( "Greatest common prefix: " + greatest_common_prefix );
+        }
+        if ( qnode_pp.isRoot() ) {
+            System.out.println( "WARNING: Least Encompassing Clade is entire tree" );
+        }
+        System.out.println( "Least Encompassing Clade has " + lec_ext_nodes + " external nodes (" +lec_ratio + "% of a total of "+ p_ext_nodes +")" );
+    }
+
+    private final static void print_help() {
+        System.out.println( "Usage: " + PRG_NAME
+                + " <gene tree file> <query>" );
+        System.out.println();
+    }
+}
index 3a8ba12..048c9a3 100644 (file)
@@ -4121,6 +4121,23 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                             ann.append( n.getName() );
                             ann.append( separator );
                         }
+                        if ( n.getNodeData().isHasTaxonomy() ) {
+                            if ( getControlPanel().isShowTaxonomyCode()
+                                    && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
+                                ann.append( n.getNodeData().getTaxonomy().getTaxonomyCode() );
+                                ann.append( separator );
+                            }
+                            if ( getControlPanel().isShowTaxonomyScientificNames()
+                                    && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
+                                ann.append( n.getNodeData().getTaxonomy().getScientificName() );
+                                ann.append( separator );
+                            }
+                            if ( getControlPanel().isShowTaxonomyCommonNames()
+                                    && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) ) {
+                                ann.append( n.getNodeData().getTaxonomy().getCommonName() );
+                                ann.append( separator );
+                            }
+                        }
                         if ( getControlPanel().isShowSeqSymbols()
                                 && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) {
                             ann.append( n.getNodeData().getSequence().getSymbol() );
@@ -4141,24 +4158,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                             ann.append( n.getNodeData().getSequence().getAccession().asText() );
                             ann.append( separator );
                         }
-                        if ( n.getNodeData().isHasTaxonomy() ) {
-                            if ( getControlPanel().isShowTaxonomyCode()
-                                    && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
-                                ann.append( n.getNodeData().getTaxonomy().getTaxonomyCode() );
-                                ann.append( separator );
-                            }
-                            if ( getControlPanel().isShowTaxonomyScientificNames()
-                                    && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
-                                ann.append( n.getNodeData().getTaxonomy().getScientificName() );
-                                ann.append( separator );
-                            }
-                            if ( getControlPanel().isShowTaxonomyCommonNames()
-                                    && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) ) {
-                                ann.append( n.getNodeData().getTaxonomy().getCommonName() );
-                                ann.append( separator );
-                            }
-                        }
-                        String ann_str;
+                       
+                        final String ann_str;
                         if ( ann.length() > 0 && ann.charAt( ann.length() - 1 ) == separator ) {
                             ann_str = ann.substring( 0, ann.length() - 1 );
                         }
index 949d9dd..0a070c0 100644 (file)
@@ -218,6 +218,17 @@ public final class Test {
             succeeded++;
         }
         System.out.println( "OK." );
+        
+        System.out.print( "Common prefix: " );
+        if ( !testCommonPrefix() ) {
+            System.out.println( "failed." );
+            failed++;
+        }
+        else {
+            succeeded++;
+        }
+        System.out.println( "OK." );
+        
         System.out.print( "Sequence writer: " );
         if ( testSequenceWriter() ) {
             System.out.println( "OK." );
@@ -1090,6 +1101,7 @@ public final class Test {
         }
     }
 
+   
     private static boolean testEngulfingOverlapRemoval() {
         try {
             final Domain d0 = new BasicDomain( "d0", 0, 8, ( short ) 1, ( short ) 1, 0.1, 1 );
@@ -1852,6 +1864,69 @@ public final class Test {
         return true;
     }
 
+    
+    private static boolean testCommonPrefix() {
+        final List<String> l0 = new ArrayList<String>();
+        l0.add( "abc" );
+        if ( !ForesterUtil.greatestCommonPrefix( l0 ).equals( "abc" ) ) {
+            return false;
+        }
+        
+        final List<String> l1 = new ArrayList<String>();
+        l1.add( "abc" );
+        l1.add( "abX" );
+        if ( !ForesterUtil.greatestCommonPrefix( l1 ).equals( "ab" ) ) {
+            return false;
+        }
+        
+        final List<String> l2 = new ArrayList<String>();
+        l2.add( "abc" );
+        l2.add( "abX" );
+        l2.add( "axy" );
+        if ( !ForesterUtil.greatestCommonPrefix( l2 ).equals( "a" ) ) {
+            return false;
+        }
+        
+        final List<String> l3 = new ArrayList<String>();
+        l3.add( "abXsdfsdfsdfsdfsdfsd" );
+        l3.add( "abXsdfsdfsdfsdfsdfsd" );
+        l3.add( "abc" );
+        l3.add( "abXsdfsdfsdfsdfsdfsd" );
+        l3.add( "ab" );
+        l3.add( "abc" );
+        l3.add( "ab" );
+        if ( !ForesterUtil.greatestCommonPrefix( l3 ).equals( "ab" ) ) {
+            return false;
+        }
+        
+        final List<String> l4 = new ArrayList<String>();
+        l4.add( "abXsdfsdfsdfsdfsdfsd" );
+        l4.add( "abXsdfsdfsdfsdfsdfsd" );
+        l4.add( "abc" );
+        l4.add( "Xsdfsdfsdfsdfsdfsd" );
+        l4.add( "ab" );
+        l4.add( "abc" );
+        if ( !ForesterUtil.greatestCommonPrefix( l4 ).equals( "" ) ) {
+            return false;
+        }
+        
+        final List<String> l5 = new ArrayList<String>();
+        l5.add( "" );
+        if ( !ForesterUtil.greatestCommonPrefix( l5 ).equals( "" ) ) {
+            return false;
+        }
+        
+        final List<String> l6 = new ArrayList<String>();
+        l6.add( "abc" );
+        l6.add( "abX" );
+        l6.add( "" );
+        if ( !ForesterUtil.greatestCommonPrefix( l6 ).equals( "" ) ) {
+            return false;
+        }
+        return true;
+    }
+
+    
     private static boolean testUTF8ParsingFromFile() {
         try {
             final PhyloXmlParser xml_parser = PhyloXmlParser.createPhyloXmlParser();
index 2374654..3ba3887 100644 (file)
@@ -593,6 +593,13 @@ public final class ForesterUtil {
     final public static boolean isEmpty( final String s ) {
         return ( ( s == null ) || ( s.length() < 1 ) );
     }
+    
+    final public static boolean isEmptyTrimmed( final String s ) {
+       if ( s == null ) {
+           return true;
+       }
+       return ( ( s.trim().length() < 1 ) );
+    }
 
     /**
      * Returns true is Domain domain falls in an uninterrupted stretch of
@@ -1572,6 +1579,30 @@ public final class ForesterUtil {
         return the_one;
     }
 
+    public final static String greatestCommonPrefix( final String a, final String b ) {
+        final int min_length = Math.min( a.length(), b.length() );
+        for( int i = 0; i < min_length; ++i ) {
+            if ( a.charAt( i ) != b.charAt( i ) ) {
+                return a.substring( 0, i );
+            }
+        }
+        return a.substring( 0, min_length );
+    }
+
+    public final static String greatestCommonPrefix( final List<String> strings ) {
+        if ( strings == null ) {
+            throw new IllegalArgumentException( "list is null" );
+        }
+        if ( strings.isEmpty() ) {
+            throw new IllegalArgumentException( "list is empty" );
+        }
+        String common = strings.get( 0 );
+        for( int i = 1; i < strings.size(); ++i ) {
+            common = greatestCommonPrefix( common, strings.get( i ) );
+        }
+        return common;
+    }
+
     private ForesterUtil() {
     }
 }