From 2153d77fe476de9ceeb3b1e7fb3438c2ce373963 Mon Sep 17 00:00:00 2001 From: cmzmasek Date: Wed, 27 Jul 2016 15:53:47 -0700 Subject: [PATCH] minor improvements and bug-fixes --- .../org/forester/archaeopteryx/AptxConstants.java | 5 +- .../src/org/forester/archaeopteryx/AptxUtil.java | 25 +- .../org/forester/archaeopteryx/ArchaeopteryxE.java | 2 +- .../org/forester/archaeopteryx/Configuration.java | 10 + .../org/forester/archaeopteryx/ControlPanel.java | 2 +- .../src/org/forester/archaeopteryx/MainFrame.java | 21 +- .../forester/archaeopteryx/tools/ImageLoader.java | 6 +- .../io/parsers/phyloxml/data/ColorParser.java | 2 +- .../src/org/forester/phylogeny/PhylogenyNode.java | 9 +- .../org/forester/phylogeny/data/Confidence.java | 2 +- .../forester/phylogeny/data/PhylogenyDataUtil.java | 2 +- .../src/org/forester/phylogeny/data/Sequence.java | 4 +- forester/java/src/org/forester/test/Test.java | 45 ++++ forester/test_data/phyloxml_test_1.xml | 265 ++++++++++++++++++++ 14 files changed, 380 insertions(+), 20 deletions(-) create mode 100644 forester/test_data/phyloxml_test_1.xml diff --git a/forester/java/src/org/forester/archaeopteryx/AptxConstants.java b/forester/java/src/org/forester/archaeopteryx/AptxConstants.java index 4b1c713..19e0697 100644 --- a/forester/java/src/org/forester/archaeopteryx/AptxConstants.java +++ b/forester/java/src/org/forester/archaeopteryx/AptxConstants.java @@ -38,8 +38,8 @@ public final class AptxConstants { final static boolean __ALLOW_PHYLOGENETIC_INFERENCE = true; public final static String PRG_NAME = "Archaeopteryx"; - final static String VERSION = "0.9914 test"; - final static String PRG_DATE = "160714"; + final static String VERSION = "0.9915 test"; + final static String PRG_DATE = "160727"; final static String DEFAULT_CONFIGURATION_FILE_NAME = "_aptx_configuration_file"; final static String[] DEFAULT_FONT_CHOICES = { "Arial Unicode MS", "Dialog", "SansSerif", "Sans", "Arial", "Helvetica" }; @@ -68,6 +68,7 @@ public final class AptxConstants { static final int MAX_TREES_TO_LOAD = 100; final static float PDF_LINE_WIDTH_DEFAULT = 0.5f; final static String APTX_WEB_SITE = "https://sites.google.com/site/cmzmasek/home/software/archaeopteryx"; + final static String APTX_MAILING_LIST = "https://groups.google.com/forum/?fromgroups#!forum/archaeopteryx"; final static String APTX_DOC_SITE = "https://sites.google.com/site/cmzmasek/home/software/archaeopteryx/documentation"; final static String PHYLOXML_WEB_SITE = ForesterConstants.PHYLO_XML_LOCATION; final static String PHYLOXML_REFERENCE_URL = "http://www.biomedcentral.com/1471-2105/10/356/"; diff --git a/forester/java/src/org/forester/archaeopteryx/AptxUtil.java b/forester/java/src/org/forester/archaeopteryx/AptxUtil.java index 958a952..f0da94b 100644 --- a/forester/java/src/org/forester/archaeopteryx/AptxUtil.java +++ b/forester/java/src/org/forester/archaeopteryx/AptxUtil.java @@ -176,6 +176,17 @@ public final class AptxUtil { } return false; } + + final static public boolean isHasNoBranchLengthSmallerThanZero( final Phylogeny phy ) { + final PhylogenyNodeIterator it = phy.iteratorPostorder(); + while ( it.hasNext() ) { + final PhylogenyNode n = it.next(); + if ( n.getDistanceToParent() < 0.0 && !n.isRoot() ) { + return false; + } + } + return true; + } final static public boolean isHasAtLeastOneBranchWithSupportSD( final Phylogeny phy ) { final PhylogenyNodeIterator it = phy.iteratorPostorder(); @@ -771,12 +782,17 @@ public final class AptxUtil { final ControlPanel cp ) { if ( ( t != null ) && !t.isEmpty() ) { final boolean has_bl = AptxUtil.isHasAtLeastOneBranchLengthLargerThanZero( t ); + if ( !has_bl ) { cp.setDrawPhylogram( false ); cp.setDrawPhylogramEnabled( false ); } - else if ( cp.getDisplayAsPhylogramCb() != null ) { - cp.setDrawPhylogramEnabled( true ); + else { + final boolean has_all_bl = AptxUtil.isHasNoBranchLengthSmallerThanZero( t ); + cp.setDrawPhylogram( has_all_bl ); + if ( cp.getDisplayAsPhylogramCb() != null ) { + cp.setDrawPhylogramEnabled( true ); + } } } } @@ -789,7 +805,6 @@ public final class AptxUtil { atv_control.setDrawPhylogram( false ); atv_control.setDrawPhylogramEnabled( false ); } - if ( t.getFirstExternalNode().getBranchData().getBranchColor() != null && atv_control.getUseVisualStylesCb() != null ) { atv_control.getUseVisualStylesCb().setSelected( true ); @@ -805,7 +820,9 @@ public final class AptxUtil { if ( configuration.doGuessCheckOption( Configuration.display_as_phylogram ) ) { if ( atv_control.getDisplayAsPhylogramCb() != null ) { if ( has_bl ) { - atv_control.setDrawPhylogram( true ); + final boolean has_all_bl = AptxUtil.isHasNoBranchLengthSmallerThanZero( t ); + + atv_control.setDrawPhylogram( has_all_bl ); atv_control.setDrawPhylogramEnabled( true ); } else { diff --git a/forester/java/src/org/forester/archaeopteryx/ArchaeopteryxE.java b/forester/java/src/org/forester/archaeopteryx/ArchaeopteryxE.java index 1612aba..ff3ce2f 100644 --- a/forester/java/src/org/forester/archaeopteryx/ArchaeopteryxE.java +++ b/forester/java/src/org/forester/archaeopteryx/ArchaeopteryxE.java @@ -338,7 +338,7 @@ public class ArchaeopteryxE extends JApplet implements ActionListener { updateOptions( getOptions() ); } else if ( o == _about_item ) { - MainFrame.about(); + getMainPanel().getMainFrame().about(); } else if ( o == _help_item ) { try { diff --git a/forester/java/src/org/forester/archaeopteryx/Configuration.java b/forester/java/src/org/forester/archaeopteryx/Configuration.java index 79fec13..bf28511 100644 --- a/forester/java/src/org/forester/archaeopteryx/Configuration.java +++ b/forester/java/src/org/forester/archaeopteryx/Configuration.java @@ -253,6 +253,7 @@ public final class Configuration { private boolean _line_up_renderable_node_data = true; private boolean _right_align_domains = false; private boolean _allow_thick_strokes = false; + private boolean _could_read_config_file = false; static { for( final String font_name : AptxConstants.DEFAULT_FONT_CHOICES ) { if ( Arrays.binarySearch( AptxUtil.getAvailableFontFamiliesSorted(), font_name ) >= 0 ) { @@ -276,6 +277,7 @@ public final class Configuration { else { config_filename = cf; } + _could_read_config_file = false; setDisplayColors( new TreeMap() ); config_filename = config_filename.trim(); URL u = null; @@ -290,6 +292,7 @@ public final class Configuration { bf.close(); ForesterUtil.programMessage( AptxConstants.PRG_NAME, "successfully read from configuration url [" + config_filename + "]" ); + _could_read_config_file = true; } catch ( final Exception e ) { ForesterUtil.printWarningMessage( AptxConstants.PRG_NAME, "failed to read configuration from [" @@ -312,6 +315,7 @@ public final class Configuration { final BufferedReader bf = new BufferedReader( new FileReader( f ) ); readConfig( bf ); bf.close(); + _could_read_config_file = true; } catch ( final Exception e ) { if ( verbose ) { @@ -1793,4 +1797,10 @@ public final class Configuration { static String getDefaultFontFamilyName() { return DEFAULT_FONT_FAMILY; } + + public boolean isCouldReadConfigFile() { + return _could_read_config_file; + } + + } diff --git a/forester/java/src/org/forester/archaeopteryx/ControlPanel.java b/forester/java/src/org/forester/archaeopteryx/ControlPanel.java index 47a9f72..fb6f98c 100644 --- a/forester/java/src/org/forester/archaeopteryx/ControlPanel.java +++ b/forester/java/src/org/forester/archaeopteryx/ControlPanel.java @@ -455,7 +455,7 @@ final class ControlPanel extends JPanel implements ActionListener { } final ArrayList sequenceNamesToAdd = new ArrayList(); for( final Sequence seq : sequenceRelationQueries ) { - if ( seq.hasSequenceRelations() ) { + if ( seq.isHasSequenceRelations() ) { boolean fFoundForCurrentType = false; for( final SequenceRelation sq : seq.getSequenceRelations() ) { if ( sq.getType().equals( relationType ) ) { diff --git a/forester/java/src/org/forester/archaeopteryx/MainFrame.java b/forester/java/src/org/forester/archaeopteryx/MainFrame.java index e6309db..0336c92 100644 --- a/forester/java/src/org/forester/archaeopteryx/MainFrame.java +++ b/forester/java/src/org/forester/archaeopteryx/MainFrame.java @@ -272,6 +272,7 @@ public abstract class MainFrame extends JFrame implements ActionListener { JMenuItem _about_item; JMenuItem _help_item; JMenuItem _website_item; + JMenuItem _mailing_list_item; JMenuItem _phyloxml_website_item; JMenuItem _phyloxml_ref_item; JMenuItem _aptx_ref_item; @@ -606,6 +607,14 @@ public abstract class MainFrame extends JFrame implements ActionListener { ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() ); } } + else if ( o == _mailing_list_item ) { + try { + AptxUtil.openWebsite( AptxConstants.APTX_MAILING_LIST, is_applet, applet ); + } + catch ( final IOException e1 ) { + ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() ); + } + } else if ( o == _phyloxml_website_item ) { try { AptxUtil.openWebsite( AptxConstants.PHYLOXML_WEB_SITE, is_applet, applet ); @@ -1165,6 +1174,7 @@ public abstract class MainFrame extends JFrame implements ActionListener { _help_jmenu.add( _help_item = new JMenuItem( "Documentation" ) ); _help_jmenu.addSeparator(); _help_jmenu.add( _website_item = new JMenuItem( "Archaeopteryx Home" ) ); + _help_jmenu.add( _mailing_list_item = new JMenuItem( "Mailing List" ) ); _aptx_ref_item = new JMenuItem( "Archaeopteryx Reference" ); //TODO need to add this... _help_jmenu.add( _phyloxml_website_item = new JMenuItem( "phyloXML Home" ) ); _help_jmenu.add( _phyloxml_ref_item = new JMenuItem( "phyloXML Reference" ) ); @@ -1172,6 +1182,7 @@ public abstract class MainFrame extends JFrame implements ActionListener { _help_jmenu.add( _about_item = new JMenuItem( "About" ) ); customizeJMenuItem( _help_item ); customizeJMenuItem( _website_item ); + customizeJMenuItem( _mailing_list_item ); customizeJMenuItem( _phyloxml_website_item ); customizeJMenuItem( _aptx_ref_item ); customizeJMenuItem( _phyloxml_ref_item ); @@ -2000,13 +2011,21 @@ public abstract class MainFrame extends JFrame implements ActionListener { /** * Display the about box. */ - static void about() { + void about() { final StringBuffer about = new StringBuffer( "Archaeopteryx\nVersion " + AptxConstants.VERSION + "\n" ); about.append( "Copyright (C) 2016 Christian M Zmasek\n" ); about.append( "All Rights Reserved\n" ); about.append( "License: GNU Lesser General Public License (LGPL)\n" ); about.append( "Last modified: " + AptxConstants.PRG_DATE + "\n" ); about.append( "Based on: " + ForesterUtil.getForesterLibraryInformation() + "\n" ); + + if ( _configuration.isCouldReadConfigFile() ) { + about.append( "Using configuration file: " + _configuration.config_filename + "\n" ); + } + else { + about.append( "Not using a configuration file\n" ); + } + about.append( "phyloXML version : " + ForesterConstants.PHYLO_XML_VERSION + "\n" ); about.append( "phyloXML location: " + ForesterConstants.PHYLO_XML_LOCATION + "\n" ); if ( !ForesterUtil.isEmpty( ForesterUtil.JAVA_VERSION ) && !ForesterUtil.isEmpty( ForesterUtil.JAVA_VENDOR ) ) { diff --git a/forester/java/src/org/forester/archaeopteryx/tools/ImageLoader.java b/forester/java/src/org/forester/archaeopteryx/tools/ImageLoader.java index 9faee68..afe47f0 100644 --- a/forester/java/src/org/forester/archaeopteryx/tools/ImageLoader.java +++ b/forester/java/src/org/forester/archaeopteryx/tools/ImageLoader.java @@ -74,8 +74,10 @@ public class ImageLoader implements Runnable { && !node.getNodeData().getTaxonomy().getUris().isEmpty() ) { final List us = new ArrayList(); for( final Taxonomy t : node.getNodeData().getTaxonomies() ) { - for( final Uri uri : t.getUris() ) { - us.add( uri ); + if ( t.getUris() != null ) { + for( final Uri uri : t.getUris() ) { + us.add( uri ); + } } } for( final Uri uri : us ) { diff --git a/forester/java/src/org/forester/io/parsers/phyloxml/data/ColorParser.java b/forester/java/src/org/forester/io/parsers/phyloxml/data/ColorParser.java index 88f1d0c..ac5c521 100644 --- a/forester/java/src/org/forester/io/parsers/phyloxml/data/ColorParser.java +++ b/forester/java/src/org/forester/io/parsers/phyloxml/data/ColorParser.java @@ -74,7 +74,7 @@ public class ColorParser implements PhylogenyDataPhyloXmlParser { color.setValue( new Color( red, green, blue ) ); } else { - color.setValue( new Color( red, green, blue ) ); + color.setValue( new Color( red, green, blue, alpha ) ); } return color; } diff --git a/forester/java/src/org/forester/phylogeny/PhylogenyNode.java b/forester/java/src/org/forester/phylogeny/PhylogenyNode.java index 3928bc3..6aa0fff 100644 --- a/forester/java/src/org/forester/phylogeny/PhylogenyNode.java +++ b/forester/java/src/org/forester/phylogeny/PhylogenyNode.java @@ -468,12 +468,12 @@ public final class PhylogenyNode implements Comparable { public final PhylogenyNode getNextExternalNodeWhileTakingIntoAccountCollapsedNodes() { //TODO work on me ~~ - if ( isInternal() && !isCollapse() ) { - throw new UnsupportedOperationException( "attempt to get next external node of an uncollapsed internal node" ); - } if ( isRoot() ) { return null; } + if ( isInternal() && !isCollapse() ) { + throw new UnsupportedOperationException( "attempt to get next external node of an uncollapsed internal node" ); + } if ( getParent().isCollapse() ) { throw new UnsupportedOperationException( "attempt to get next external node of node with a collapsed parent" ); } @@ -617,9 +617,10 @@ public final class PhylogenyNode implements Comparable { /** * Returns whether this PhylogenyNode should be drawn as collapsed. + * Root can not be collapsed. */ final public boolean isCollapse() { - return _collapse; + return _collapse && _parent != null; } /** diff --git a/forester/java/src/org/forester/phylogeny/data/Confidence.java b/forester/java/src/org/forester/phylogeny/data/Confidence.java index 8b12491..1d490ff 100644 --- a/forester/java/src/org/forester/phylogeny/data/Confidence.java +++ b/forester/java/src/org/forester/phylogeny/data/Confidence.java @@ -38,7 +38,7 @@ import org.forester.util.ForesterUtil; public class Confidence implements PhylogenyData, Comparable { - public final static int CONFIDENCE_DEFAULT_VALUE = -9999; + public final static int CONFIDENCE_DEFAULT_VALUE = -Integer.MAX_VALUE; private double _value; private double _sd; private String _type; diff --git a/forester/java/src/org/forester/phylogeny/data/PhylogenyDataUtil.java b/forester/java/src/org/forester/phylogeny/data/PhylogenyDataUtil.java index 48da0e0..f40b507 100644 --- a/forester/java/src/org/forester/phylogeny/data/PhylogenyDataUtil.java +++ b/forester/java/src/org/forester/phylogeny/data/PhylogenyDataUtil.java @@ -35,7 +35,7 @@ import org.forester.util.ForesterUtil; public final class PhylogenyDataUtil { - /** Value of -99.0 is used as default value. */ + /** Value of -1024.0 is used as default value. */ public final static double BRANCH_LENGTH_DEFAULT = -1024.0; public static void appendClose( final Writer w, final String element_name ) throws IOException { diff --git a/forester/java/src/org/forester/phylogeny/data/Sequence.java b/forester/java/src/org/forester/phylogeny/data/Sequence.java index fd366c6..3561edc 100644 --- a/forester/java/src/org/forester/phylogeny/data/Sequence.java +++ b/forester/java/src/org/forester/phylogeny/data/Sequence.java @@ -315,8 +315,8 @@ public class Sequence implements PhylogenyData, MultipleUris, Comparable 0; + public boolean isHasSequenceRelations() { + return _seq_relations != null && _seq_relations.size() > 0; } public void init() { diff --git a/forester/java/src/org/forester/test/Test.java b/forester/java/src/org/forester/test/Test.java index 8e40249..5d8854d 100644 --- a/forester/java/src/org/forester/test/Test.java +++ b/forester/java/src/org/forester/test/Test.java @@ -479,6 +479,15 @@ public final class Test { System.out.println( "failed." ); failed++; } + System.out.print( "phyloXML parsing (validating against schema): " ); + if ( testPhyloXMLparsingValidating() ) { + System.out.println( "OK." ); + succeeded++; + } + else { + System.out.println( "failed." ); + failed++; + } System.out.print( "Roundtrip phyloXML parsing (validating against schema): " ); if ( Test.testBasicPhyloXMLparsingRoundtrip() ) { System.out.println( "OK." ); @@ -2740,6 +2749,42 @@ public final class Test { } return true; } + + private static boolean testPhyloXMLparsingValidating() { + try { + final PhylogenyFactory factory = ParserBasedPhylogenyFactory.getInstance(); + PhyloXmlParser xml_parser = null; + try { + xml_parser = PhyloXmlParser.createPhyloXmlParserXsdValidating(); + } + catch ( final Exception e ) { + // Do nothing -- means were not running from jar. + } + if ( xml_parser == null ) { + xml_parser = PhyloXmlParser.createPhyloXmlParser(); + if ( USE_LOCAL_PHYLOXML_SCHEMA ) { + xml_parser.setValidateAgainstSchema( PHYLOXML_LOCAL_XSD ); + } + else { + xml_parser.setValidateAgainstSchema( PHYLOXML_REMOTE_XSD ); + } + } + final Phylogeny[] phylogenies_0 = factory.create( new File( Test.PATH_TO_TEST_DATA + "phyloxml_test_1.xml" ), + xml_parser ); + if ( xml_parser.getErrorCount() > 0 ) { + System.out.println( xml_parser.getErrorMessages().toString() ); + return false; + } + if ( phylogenies_0.length != 3 ) { + return false; + } + } + catch ( final Exception e ) { + e.printStackTrace( System.out ); + return false; + } + return true; + } private static boolean testBasicProtein() { try { diff --git a/forester/test_data/phyloxml_test_1.xml b/forester/test_data/phyloxml_test_1.xml new file mode 100644 index 0000000..83c400d --- /dev/null +++ b/forester/test_data/phyloxml_test_1.xml @@ -0,0 +1,265 @@ + + + + tree 0 + 1-1 + test phylogeny + 2002-05-30T09:00:00 + 0.999 + 0.955 + + root node + 90 + 1e-3 + 2 + 10.5 + + 2 + 22 + 33 + 123 + + + 1 + ECDYS + ecdysozoa + authority, 1999 + molting animals + Ecdy + The Ecdysozoa + phylum + http://www.molting.org/m.jpg + http://www.ecdysozoa.org/ + + + 123 + Æ Ä ä, ö and ü>– — + 한글 + 日本語ひらがなカタカナ + русский алфавит + 繁體字 + ภาษาไทย + Tiếng Việt + + + BCL2L14 + Q9BZR8 + Apoptosis facilitator Bcl-2-like 14 protein + bcl2l14 + 12p13-p12 + MCSTSGCDLEEIPLDDDDLNTIEFKILAYY + http://www.pir.uniprot.org/cgi-bin/upEntry?id=B2L14_HUMAN + + intracellular organelle + + + + apoptosis + 1 + 0.2 + + lymphoma + http://www.google.com + http://www.bing.com + + + 383 + 1G5M + hsa:596 + 2G5M + + + + BCL2 + + + mixed + 1 + 99 + + + irgendwo + + 35.9296730123456789 + -78.9482370123456789 + 1303 + + + 129.549495485834893 + -78.00000000000000 + 1400 + + + + anderswo + + + Silurian + + + + Aguinaldo, A. M. A.; J. M. Turbeville, L. S. Linford, M. C. Rivera, J. R. Garey, R. A. Raff, & + J. A. Lake (1997). "Evidence for a clade of nematodes, arthropods and other moulting animals". + Nature 387 (6632): 489–493. + + + + + 2 + 33 + + node a + 0.2 + + 12 + 14 + 16 + + + 123 + CAEEL + C elegans + elegant nematode worm + species + http://www.wormbase.org/ + + + CAEEL_XYZ + + + CAEEL_ABC + + + other + 58 + 59403 + 58485 + 0.9901 + + + + node b + + 1 + 80 + + + + c + + + d + e + f + + + a + b + + + + node ba + + Africa + + + Silurian + 435 + 416 + 443.7 + + + + node bb + + 704294 + NEMVE + Nematostella vectensis + Stephenson, 1935 + starlet sea anemone + Nematostella vectensis Stephenson1935 + See + Anemone + + + species + http://www.eol.org/pages/704294 + + + + A + B + C + + + D + + + X + M + + + + Triassic + + + + node bc + + bc seq + + A + B + C + D + + + + 1 + + + 433 + + + + + + 1e-3 + + + 99.0000001 + + 2 + cell death + + + phylogeny2 + + + A + + + B + + + + + phylogeny3 + + + C + + + D + + + + 1e-3 + + + 1e-4 + + + \ No newline at end of file -- 1.7.10.2