From 12fb7d9470cefe81e135eb79a17288ca055ec0ed Mon Sep 17 00:00:00 2001 From: cmzmasek Date: Fri, 5 Aug 2016 18:23:47 -0700 Subject: [PATCH] some additions being added --- .../src/org/forester/archaeopteryx/AptxUtil.java | 39 ++ .../org/forester/archaeopteryx/Configuration.java | 25 +- .../org/forester/archaeopteryx/ControlPanel.java | 61 ++- .../src/org/forester/archaeopteryx/MainFrame.java | 10 +- .../archaeopteryx/MainFrameApplication.java | 394 +++++++++++--------- .../src/org/forester/archaeopteryx/TreePanel.java | 171 ++++++++- .../org/forester/archaeopteryx/TreePanelUtil.java | 142 +++++-- .../io/parsers/phyloxml/PhyloXmlMapping.java | 1 + .../io/parsers/phyloxml/data/TaxonomyParser.java | 8 + .../org/forester/phylogeny/PhylogenyMethods.java | 27 +- .../src/org/forester/phylogeny/data/Taxonomy.java | 28 +- 11 files changed, 694 insertions(+), 212 deletions(-) diff --git a/forester/java/src/org/forester/archaeopteryx/AptxUtil.java b/forester/java/src/org/forester/archaeopteryx/AptxUtil.java index f0da94b..f946f23 100644 --- a/forester/java/src/org/forester/archaeopteryx/AptxUtil.java +++ b/forester/java/src/org/forester/archaeopteryx/AptxUtil.java @@ -44,10 +44,12 @@ import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.text.ParseException; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -751,6 +753,22 @@ public final class AptxUtil { } return str_array; } + + final static String[] getAllPossibleRanks(final Map present_ranks) { + final String[] str_array = new String[ PhyloXmlUtil.TAXONOMY_RANKS_LIST.size() - 2 ]; + int i = 0; + for( final String e : PhyloXmlUtil.TAXONOMY_RANKS_LIST ) { + if ( !e.equals( PhyloXmlUtil.UNKNOWN ) && !e.equals( PhyloXmlUtil.OTHER ) ) { + if ( present_ranks != null && present_ranks.containsKey( e ) ) { + str_array[ i++ ] = e + " (" + present_ranks.get(e) + ")"; + } + else { + str_array[ i++ ] = e; + } + } + } + return str_array; + } final static String[] getAllRanks( final Phylogeny tree ) { final SortedSet ranks = new TreeSet(); @@ -1079,4 +1097,25 @@ public final class AptxUtil { final IIOImage iio_image = new IIOImage( image, null, null ); writer.write( null, iio_image, image_write_param ); } + + final static Map getRankCounts(final Phylogeny tree) { + final Map present_ranks = new HashMap(); + + if ( ( tree != null ) && !tree.isEmpty() ) { + for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) { + final PhylogenyNode n = it.next(); + if ( !n.isExternal() && n.getNodeData().isHasTaxonomy() + && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getRank() ) && !n.isRoot() ) { + final String rank = n.getNodeData().getTaxonomy().getRank().toLowerCase(); + if (present_ranks.containsKey( rank ) ) { + present_ranks.put( rank, present_ranks.get( rank ) + 1 ); + } + else { + present_ranks.put( rank, 1 ); + } + } + } + } + return present_ranks; + } } diff --git a/forester/java/src/org/forester/archaeopteryx/Configuration.java b/forester/java/src/org/forester/archaeopteryx/Configuration.java index bf28511..b4a4398 100644 --- a/forester/java/src/org/forester/archaeopteryx/Configuration.java +++ b/forester/java/src/org/forester/archaeopteryx/Configuration.java @@ -68,13 +68,13 @@ public final class Configuration { } final static String clickto_options[][] = { { "Display Node Data", "display" }, { "Collapse/Uncollapse", "display" }, { "Root/Reroot", "display" }, - { "Go to Sub-/Super-Tree", "display" }, { "Swap Descendants", "display" }, + { "Go to Sub/Supertree", "display" }, { "Swap Descendants", "display" }, { "Colorize Node(s)", "display" }, { "Change Node Font(s)", "display" }, { "Colorize Subtree(s)", "display" }, { "Open Sequence DB", "display" }, { "Open PDB", "display" }, { "Open Taxonomy DB", "display" }, { "Launch BLAST", "display" }, { "Cut Subtree", "display" }, { "Copy Subtree", "display" }, { "Paste Subtree", "display" }, { "Delete Subtree/Node", "display" }, { "Add New Node", "display" }, { "Edit Node Data", "display" }, { "Sort Descendants", "display" }, - { "List Node Data", "display" }, { "Select Node(s)", "display" } }; + { "List Node Data", "display" }, { "Select Node(s)", "display" } , { "Uncollapse All", "display" }, { "Order Subtree", "display" }, }; private final static String DEFAULT_SPECIES_COLORS[][] = { { "BRAFL", "0x00FFFF" }, { "SPHGR", "0x9620F0" }, { "STRPU", "0x9620F0" }, { "CIOIN", "0xFF1CAE" }, { "CIOSA", "0xFF2CAE" }, { "BOVIN", "0x5C3317" }, { "CANFA", "0x8B2323" }, { "HUMAN", "0xFF2400" }, @@ -114,6 +114,9 @@ public final class Configuration { final static int sort_descendents = 18; final static int get_ext_desc_data = 19; final static int select_nodes = 20; + final static int uncollapse_all = 21; + final static int order_subtree = 22; + // ------------------ // Click-to options // ------------------ @@ -131,7 +134,8 @@ public final class Configuration { { "Rollover", "display", "yes" }, { "Relation Confidence", "nodisplay", "no" }, { "Vector Data", "nodisplay", "no" }, { "Taxonomy Images", "display", "no" }, { "Properties", "display", "no" }, { "Gene Name", "display", "yes" }, - { "Multiple Seq Alignment", "display", "no" }, { "Branch Length Values", "display", "no" } }; + { "Multiple Seq Alignment", "display", "no" }, { "Branch Length Values", "display", "no" } + , { "Taxonomy Rank", "display", "no" }}; final static int display_as_phylogram = 0; final static int show_node_names = 1; final static int show_tax_code = 2; @@ -161,6 +165,8 @@ public final class Configuration { final static int show_gene_names = 26; final static int show_mol_seqs = 27; final static int write_branch_length_values = 28; + final static int show_tax_rank = 29; + static final String VALIDATE_AGAINST_PHYLOXML_XSD_SCHEMA = "validate_against_phyloxml_xsd_schema"; private static Hashtable _sequence_colors; private static Hashtable _annotation_colors; @@ -548,6 +554,10 @@ public final class Configuration { public void setDisplayTaxonomyCode( final boolean b ) { display_options[ show_tax_code ][ 2 ] = b ? "yes" : "no"; } + + public void setDisplayTaxonomyRank( final boolean b ) { + display_options[ show_tax_rank ][ 2 ] = b ? "yes" : "no"; + } public void setDisplayTaxonomyCommonNames( final boolean b ) { display_options[ show_taxonomy_common_names ][ 2 ] = b ? "yes" : "no"; @@ -655,6 +665,9 @@ public final class Configuration { else if ( name.equals( "collapse_uncollapse" ) ) { index = Configuration.collapse_uncollapse; } + else if ( name.equals( "uncollapse_all" ) ) { + index = Configuration.uncollapse_all; + } else if ( name.equals( "reroot" ) ) { index = Configuration.reroot; } @@ -664,6 +677,9 @@ public final class Configuration { else if ( name.equals( "swap" ) ) { index = Configuration.swap; } + else if ( name.equals( "order_subtree" ) ) { + index = Configuration.order_subtree; + } else if ( name.equals( "sort_descendants" ) ) { index = Configuration.sort_descendents; } @@ -1386,6 +1402,9 @@ public final class Configuration { else if ( key.equals( "show_taxonomy_code" ) ) { key_index = Configuration.show_tax_code; } + else if ( key.equals( "show_taxonomy_rank" ) ) { + key_index = Configuration.show_tax_rank; + } else if ( key.equals( "write_confidence_values" ) ) { key_index = Configuration.write_confidence_values; } diff --git a/forester/java/src/org/forester/archaeopteryx/ControlPanel.java b/forester/java/src/org/forester/archaeopteryx/ControlPanel.java index fb6f98c..f9b53b6 100644 --- a/forester/java/src/org/forester/archaeopteryx/ControlPanel.java +++ b/forester/java/src/org/forester/archaeopteryx/ControlPanel.java @@ -93,7 +93,9 @@ final class ControlPanel extends JPanel implements ActionListener { SUBTREE, SWAP, CHANGE_NODE_FONT, - COLOR_NODE_FONT; + COLOR_NODE_FONT, + UNCOLLAPSE_ALL, + ORDER_SUBTREE; } final static Font jcb_bold_font = new Font( Configuration.getDefaultFontFamilyName(), Font.BOLD, @@ -116,6 +118,10 @@ final class ControlPanel extends JPanel implements ActionListener { private JLabel _click_to_label; private List _click_to_names; private int _collapse_cb_item; + private int _uncollapse_all_cb_item; + private int _order_subtree_cb_item; + + private JCheckBox _color_acc_species; private JCheckBox _color_acc_sequence; private JCheckBox _color_according_to_annotation; @@ -146,7 +152,6 @@ final class ControlPanel extends JPanel implements ActionListener { private int _open_tax_web_item; private int _color_node_font_item; private JButton _order; - private boolean _order_of_appearance; private int _paste_subtree_item; private int _reroot_cb_item; private JButton _return_to_super_tree; @@ -178,6 +183,7 @@ final class ControlPanel extends JPanel implements ActionListener { private JCheckBox _show_sequence_acc; private JComboBox _show_sequence_relations; private JCheckBox _show_taxo_code; + private JCheckBox _show_taxo_rank; private JCheckBox _show_taxo_common_names; private JCheckBox _show_taxo_images_cb; private JCheckBox _show_taxo_scientific_names; @@ -208,7 +214,6 @@ final class ControlPanel extends JPanel implements ActionListener { setBorder( BorderFactory.createRaisedBevelBorder() ); } setLayout( new GridLayout( 0, 1, 2, 2 ) ); - _order_of_appearance = true; setupControls(); } @@ -291,8 +296,8 @@ final class ControlPanel extends JPanel implements ActionListener { else if ( isShowSeqNames() || isShowSeqSymbols() || isShowGeneNames() ) { pri = DESCENDANT_SORT_PRIORITY.SEQUENCE; } - PhylogenyMethods.orderAppearance( tp.getPhylogeny().getRoot(), _order_of_appearance, true, pri ); - _order_of_appearance = !_order_of_appearance; + PhylogenyMethods.orderAppearanceX( tp.getPhylogeny().getRoot(), true, pri ); + tp.setNodeInPreorderToNull(); tp.getPhylogeny().externalNodesHaveChanged(); tp.getPhylogeny().clearHashIdToNodeMap(); @@ -740,6 +745,15 @@ final class ControlPanel extends JPanel implements ActionListener { } cb_index++; } +if ( _configuration.doDisplayClickToOption( Configuration.uncollapse_all ) ) { + _uncollapse_all_cb_item = cb_index; + addClickToOption( Configuration.uncollapse_all, + _configuration.getClickToTitle( Configuration.uncollapse_all ) ); + if ( default_option == Configuration.uncollapse_all ) { + selected_index = cb_index; + } + cb_index++; +} if ( _configuration.doDisplayClickToOption( Configuration.reroot ) ) { _reroot_cb_item = cb_index; addClickToOption( Configuration.reroot, _configuration.getClickToTitle( Configuration.reroot ) ); @@ -764,6 +778,16 @@ final class ControlPanel extends JPanel implements ActionListener { } cb_index++; } +if ( _configuration.doDisplayClickToOption( Configuration.order_subtree ) ) { + _order_subtree_cb_item = cb_index; + addClickToOption( Configuration.order_subtree, + _configuration.getClickToTitle( Configuration.order_subtree ) ); + if ( default_option == Configuration.order_subtree ) { + selected_index = cb_index; + } + cb_index++; +} + if ( _configuration.doDisplayClickToOption( Configuration.sort_descendents ) ) { _sort_descendents_item = cb_index; addClickToOption( Configuration.sort_descendents, @@ -989,6 +1013,10 @@ final class ControlPanel extends JPanel implements ActionListener { setCheckbox( Configuration.show_taxonomy_common_names, _configuration.doCheckOption( Configuration.show_taxonomy_common_names ) ); } + if ( _configuration.doDisplayOption( Configuration.show_tax_rank ) ) { + addCheckbox( Configuration.show_tax_rank, _configuration.getDisplayTitle( Configuration.show_tax_rank ) ); + setCheckbox( Configuration.show_tax_rank, _configuration.doCheckOption( Configuration.show_tax_rank ) ); + } if ( _configuration.doDisplayOption( Configuration.show_seq_names ) ) { addCheckbox( Configuration.show_seq_names, _configuration.getDisplayTitle( Configuration.show_seq_names ) ); setCheckbox( Configuration.show_seq_names, _configuration.doCheckOption( Configuration.show_seq_names ) ); @@ -1164,8 +1192,9 @@ final class ControlPanel extends JPanel implements ActionListener { _show_whole.setPreferredSize( new Dimension( 10, 10 ) ); _return_to_super_tree = new JButton( RETURN_TO_SUPER_TREE_TEXT ); _return_to_super_tree.setEnabled( false ); - _order = new JButton( "Order Subtrees" ); + _order = new JButton( "Order Tree" ); _uncollapse_all = new JButton( "Uncollapse All" ); + addJButton( _zoom_in_y, x_panel ); addJButton( _zoom_out_x, y_panel ); addJButton( _show_whole, y_panel ); @@ -1238,6 +1267,11 @@ final class ControlPanel extends JPanel implements ActionListener { addJCheckBox( _show_taxo_code, ch_panel ); add( ch_panel ); break; + case Configuration.show_tax_rank: + _show_taxo_rank = new JCheckBox( title ); + addJCheckBox( _show_taxo_rank, ch_panel ); + add( ch_panel ); + break; case Configuration.show_taxonomy_images: _show_taxo_images_cb = new JCheckBox( title ); addJCheckBox( _show_taxo_images_cb, ch_panel ); @@ -1569,6 +1603,10 @@ final class ControlPanel extends JPanel implements ActionListener { boolean isShowTaxonomyCode() { return ( ( _show_taxo_code != null ) && _show_taxo_code.isSelected() ); } + + boolean isShowTaxonomyRank() { + return ( ( _show_taxo_rank != null ) && _show_taxo_rank.isSelected() ); + } boolean isShowTaxonomyCommonNames() { return ( ( _show_taxo_common_names != null ) && _show_taxo_common_names.isSelected() ); @@ -1707,6 +1745,11 @@ final class ControlPanel extends JPanel implements ActionListener { _show_taxo_code.setSelected( state ); } break; + case Configuration.show_tax_rank: + if ( _show_taxo_rank != null ) { + _show_taxo_rank.setSelected( state ); + } + break; case Configuration.show_taxonomy_images: if ( _show_taxo_images_cb != null ) { _show_taxo_images_cb.setSelected( state ); @@ -1889,6 +1932,12 @@ final class ControlPanel extends JPanel implements ActionListener { else if ( action == _change_node_font_item ) { setActionWhenNodeClicked( NodeClickAction.CHANGE_NODE_FONT ); } + else if ( action == _uncollapse_all_cb_item ) { + setActionWhenNodeClicked( NodeClickAction.UNCOLLAPSE_ALL ); + } + else if ( action == _order_subtree_cb_item ) { + setActionWhenNodeClicked( NodeClickAction.ORDER_SUBTREE ); + } else { throw new RuntimeException( "unknown action: " + action ); } diff --git a/forester/java/src/org/forester/archaeopteryx/MainFrame.java b/forester/java/src/org/forester/archaeopteryx/MainFrame.java index 0336c92..7411509 100644 --- a/forester/java/src/org/forester/archaeopteryx/MainFrame.java +++ b/forester/java/src/org/forester/archaeopteryx/MainFrame.java @@ -36,6 +36,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.NoSuchElementException; import javax.swing.Box; @@ -183,6 +184,7 @@ public abstract class MainFrame extends JFrame implements ActionListener { JMenuItem _confcolor_item; JMenuItem _color_rank_jmi; JMenuItem _collapse_species_specific_subtrees; + JMenuItem _obtain_detailed_taxonomic_information_jmi; JMenuItem _obtain_detailed_taxonomic_information_deleting_jmi; JMenuItem _obtain_seq_information_jmi; @@ -1291,8 +1293,9 @@ public abstract class MainFrame extends JFrame implements ActionListener { void colorRank() { if ( _mainpanel.getCurrentTreePanel() != null ) { - final String[] ranks = AptxUtil.getAllPossibleRanks(); - final String rank = ( String ) JOptionPane + final Map present_ranks = AptxUtil.getRankCounts( _mainpanel.getCurrentTreePanel().getPhylogeny()); + final String[] ranks = AptxUtil.getAllPossibleRanks(present_ranks); + String rank = ( String ) JOptionPane .showInputDialog( this, "What rank should the colorization be based on", "Rank Selection", @@ -1301,6 +1304,9 @@ public abstract class MainFrame extends JFrame implements ActionListener { ranks, null ); if ( !ForesterUtil.isEmpty( rank ) ) { + if ( rank.indexOf( '(' ) > 0 ) { + rank = rank.substring( 0, rank.indexOf( '(' ) ).trim(); + } _mainpanel.getCurrentTreePanel().colorRank( rank ); } } diff --git a/forester/java/src/org/forester/archaeopteryx/MainFrameApplication.java b/forester/java/src/org/forester/archaeopteryx/MainFrameApplication.java index fd79734..40fc4bc 100644 --- a/forester/java/src/org/forester/archaeopteryx/MainFrameApplication.java +++ b/forester/java/src/org/forester/archaeopteryx/MainFrameApplication.java @@ -42,6 +42,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import javax.swing.ButtonGroup; @@ -117,6 +118,7 @@ public final class MainFrameApplication extends MainFrame { // Application-only print menu items private JMenuItem _collapse_below_threshold; private JMenuItem _collapse_below_branch_length; + private JMenuItem _collapse_by_taxonomic_rank; private ButtonGroup _radio_group_1; private ButtonGroup _radio_group_2; // Others: @@ -317,10 +319,8 @@ public final class MainFrameApplication extends MainFrame { } } else { - final int r = JOptionPane.showConfirmDialog( null, - "Exit Archaeopteryx?", - "Exit?", - JOptionPane.YES_NO_OPTION ); + final int r = JOptionPane + .showConfirmDialog( null, "Exit Archaeopteryx?", "Exit?", JOptionPane.YES_NO_OPTION ); if ( r != JOptionPane.YES_OPTION ) { return; } @@ -334,10 +334,9 @@ public final class MainFrameApplication extends MainFrame { @Override public void componentResized( final ComponentEvent e ) { if ( _mainpanel.getCurrentTreePanel() != null ) { - _mainpanel.getCurrentTreePanel().calcParametersForPainting( _mainpanel.getCurrentTreePanel() - .getWidth(), - _mainpanel.getCurrentTreePanel() - .getHeight() ); + _mainpanel.getCurrentTreePanel() + .calcParametersForPainting( _mainpanel.getCurrentTreePanel().getWidth(), + _mainpanel.getCurrentTreePanel().getHeight() ); } } } ); @@ -436,6 +435,12 @@ public final class MainFrameApplication extends MainFrame { } collapseBelowThreshold(); } + else if ( o == _collapse_by_taxonomic_rank ) { + if ( isSubtreeDisplayed() ) { + return; + } + collapseByTaxonomicRank(); + } else if ( o == _collapse_below_branch_length ) { if ( isSubtreeDisplayed() ) { return; @@ -719,8 +724,8 @@ public final class MainFrameApplication extends MainFrame { JOptionPane.showMessageDialog( this, "Table contains " + t.getNumberOfRows() + " rows, but tree contains " + phy.getNumberOfExternalNodes() + " external nodes", - "Warning", - JOptionPane.WARNING_MESSAGE ); + "Warning", + JOptionPane.WARNING_MESSAGE ); } final DescriptiveStatistics stats = new BasicDescriptiveStatistics(); int not_found = 0; @@ -733,11 +738,10 @@ public final class MainFrameApplication extends MainFrame { row = t.findRow( node_name ); } catch ( final IllegalArgumentException e ) { - JOptionPane - .showMessageDialog( this, - e.getMessage(), - "Error Mapping Node Identifiers to Expression Value Identifiers", - JOptionPane.ERROR_MESSAGE ); + JOptionPane.showMessageDialog( this, + e.getMessage(), + "Error Mapping Node Identifiers to Expression Value Identifiers", + JOptionPane.ERROR_MESSAGE ); return; } if ( row < 0 ) { @@ -755,7 +759,7 @@ public final class MainFrameApplication extends MainFrame { catch ( final NumberFormatException e ) { JOptionPane.showMessageDialog( this, "Could not parse \"" + t.getValueAsString( col, row ) - + "\" into a decimal value", + + "\" into a decimal value", "Issue with Expression Value Table", JOptionPane.ERROR_MESSAGE ); return; @@ -766,15 +770,18 @@ public final class MainFrameApplication extends MainFrame { if ( !l.isEmpty() ) { if ( node.getNodeData().getProperties() != null ) { node.getNodeData().getProperties() - .removePropertiesWithGivenReferencePrefix( PhyloXmlUtil.VECTOR_PROPERTY_REF ); + .removePropertiesWithGivenReferencePrefix( PhyloXmlUtil.VECTOR_PROPERTY_REF ); } node.getNodeData().setVector( l ); } } } if ( not_found > 0 ) { - JOptionPane.showMessageDialog( this, "Could not fine expression values for " + not_found - + " external node(s)", "Warning", JOptionPane.WARNING_MESSAGE ); + JOptionPane + .showMessageDialog( this, + "Could not fine expression values for " + not_found + " external node(s)", + "Warning", + JOptionPane.WARNING_MESSAGE ); } getCurrentTreePanel().setStatisticsForExpressionValues( stats ); } @@ -803,10 +810,10 @@ public final class MainFrameApplication extends MainFrame { seqs = FastaParser.parse( fis2 ); try { fis2.close(); - } - catch ( final Exception e ) { - // Ignore. - } + } + catch ( final Exception e ) { + // Ignore. + } } else { JOptionPane.showMessageDialog( this, @@ -819,7 +826,7 @@ public final class MainFrameApplication extends MainFrame { fis1.close(); } catch ( final Exception e ) { - // Ignore. + // Ignore. } } catch ( final MsaFormatException e ) { @@ -896,8 +903,11 @@ public final class MainFrameApplication extends MainFrame { nodes = phy.getNodes( seq_name_split ); } if ( nodes.size() > 1 ) { - JOptionPane.showMessageDialog( this, "Split sequence name \"" + seq_name_split - + "\" is not unique", "Sequence name not unique", JOptionPane.ERROR_MESSAGE ); + JOptionPane.showMessageDialog( this, + "Split sequence name \"" + seq_name_split + + "\" is not unique", + "Sequence name not unique", + JOptionPane.ERROR_MESSAGE ); setArrowCursor(); return; } @@ -941,14 +951,18 @@ public final class MainFrameApplication extends MainFrame { JOptionPane.INFORMATION_MESSAGE ); } else { - JOptionPane.showMessageDialog( this, "Attached " + attached_counter - + " sequences out of a total of " + total_counter + " sequences.\n" + s, attached_counter - + " sequences attached", JOptionPane.WARNING_MESSAGE ); + JOptionPane.showMessageDialog( this, + "Attached " + attached_counter + " sequences out of a total of " + + total_counter + " sequences.\n" + s, + attached_counter + " sequences attached", + JOptionPane.WARNING_MESSAGE ); } } else { - JOptionPane.showMessageDialog( this, "No maching tree node for any of the " + total_counter - + " sequences", "Could not attach any sequences", JOptionPane.ERROR_MESSAGE ); + JOptionPane.showMessageDialog( this, + "No maching tree node for any of the " + total_counter + " sequences", + "Could not attach any sequences", + JOptionPane.ERROR_MESSAGE ); } } } @@ -1014,13 +1028,19 @@ public final class MainFrameApplication extends MainFrame { repaint(); } if ( to_be_removed.size() > 0 ) { - JOptionPane.showMessageDialog( this, "Collapsed " + to_be_removed.size() - + " branches with\nconfidence values below " + getMinNotCollapseConfidenceValue(), "Collapsed " - + to_be_removed.size() + " branches", JOptionPane.INFORMATION_MESSAGE ); + JOptionPane.showMessageDialog( this, + "Collapsed " + to_be_removed.size() + + " branches with\nconfidence values below " + + getMinNotCollapseConfidenceValue(), + "Collapsed " + to_be_removed.size() + " branches", + JOptionPane.INFORMATION_MESSAGE ); } else { - JOptionPane.showMessageDialog( this, "No branch collapsed,\nminimum confidence value per branch is " - + min_support, "No branch collapsed", JOptionPane.INFORMATION_MESSAGE ); + JOptionPane.showMessageDialog( this, + "No branch collapsed,\nminimum confidence value per branch is " + + min_support, + "No branch collapsed", + JOptionPane.INFORMATION_MESSAGE ); } } else { @@ -1031,18 +1051,38 @@ public final class MainFrameApplication extends MainFrame { } } + private void collapseByTaxonomicRank() { + if ( _mainpanel.getCurrentTreePanel() != null ) { + final Map present_ranks = AptxUtil.getRankCounts( _mainpanel.getCurrentTreePanel().getPhylogeny()); + final String[] ranks = AptxUtil.getAllPossibleRanks(present_ranks); + String rank = ( String ) JOptionPane + .showInputDialog( this, + "What rank should the collapsing be based on", + "Rank Selection", + JOptionPane.QUESTION_MESSAGE, + null, + ranks, + null ); + if ( !ForesterUtil.isEmpty( rank ) ) { + if ( rank.indexOf( '(' ) > 0 ) { + rank = rank.substring( 0, rank.indexOf( '(' ) ).trim(); + } + _mainpanel.getCurrentTreePanel().collapseByTaxonomicRank( rank ); + } + } + } + private void collapseBelowBranchLengthThreshold() { if ( getCurrentTreePanel() != null ) { final Phylogeny phy = getCurrentTreePanel().getPhylogeny(); if ( ( phy != null ) && !phy.isEmpty() ) { - final String s = ( String ) JOptionPane - .showInputDialog( this, - "Please enter the minimum branch length value\n", - "Minimal Branch Length Value", - JOptionPane.QUESTION_MESSAGE, - null, - null, - getMinNotCollapseBlValue() ); + final String s = ( String ) JOptionPane.showInputDialog( this, + "Please enter the minimum branch length value\n", + "Minimal Branch Length Value", + JOptionPane.QUESTION_MESSAGE, + null, + null, + getMinNotCollapseBlValue() ); if ( !ForesterUtil.isEmpty( s ) ) { boolean success = true; double m = 0.0; @@ -1141,9 +1181,12 @@ public final class MainFrameApplication extends MainFrame { repaint(); } if ( to_be_removed.size() > 0 ) { - JOptionPane.showMessageDialog( this, "Collapsed " + to_be_removed.size() - + " branches with\nbranch length values below " + getMinNotCollapseBlValue(), "Collapsed " - + to_be_removed.size() + " branches", JOptionPane.INFORMATION_MESSAGE ); + JOptionPane.showMessageDialog( this, + "Collapsed " + to_be_removed.size() + + " branches with\nbranch length values below " + + getMinNotCollapseBlValue(), + "Collapsed " + to_be_removed.size() + " branches", + JOptionPane.INFORMATION_MESSAGE ); } else { JOptionPane.showMessageDialog( this, @@ -1189,7 +1232,8 @@ public final class MainFrameApplication extends MainFrame { if ( getMsa() != null ) { final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getMsa(), getPhylogeneticInferenceOptions() - .copy(), this ); + .copy(), + this ); new Thread( inferrer ).start(); } else { @@ -1203,7 +1247,8 @@ public final class MainFrameApplication extends MainFrame { if ( getSeqs() != null ) { final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getSeqs(), getPhylogeneticInferenceOptions() - .copy(), this ); + .copy(), + this ); new Thread( inferrer ).start(); } else { @@ -1256,24 +1301,23 @@ public final class MainFrameApplication extends MainFrame { String all = "all "; if ( counter_failed > 0 ) { all = ""; - failed = "\nCould not extract taxonomic data for " + counter_failed - + " named external nodes:\n" + sb_failed; + failed = "\nCould not extract taxonomic data for " + counter_failed + " named external nodes:\n" + + sb_failed; } JOptionPane.showMessageDialog( this, "Extracted taxonomic data from " + all + counter - + " named external nodes:\n" + sb.toString() + failed, + + " named external nodes:\n" + sb.toString() + failed, "Taxonomic Data Extraction Completed", counter_failed > 0 ? JOptionPane.WARNING_MESSAGE : JOptionPane.INFORMATION_MESSAGE ); } else { - JOptionPane - .showMessageDialog( this, - "Could not extract any taxonomic data.\nMaybe node names are empty\n" - + "or not in the forms \"XYZ_CAEEL\", \"XYZ_6239\", or \"XYZ_Caenorhabditis_elegans\"\n" - + "or nodes already have taxonomic data?\n", - "No Taxonomic Data Extracted", - JOptionPane.ERROR_MESSAGE ); + JOptionPane.showMessageDialog( this, + "Could not extract any taxonomic data.\nMaybe node names are empty\n" + + "or not in the forms \"XYZ_CAEEL\", \"XYZ_6239\", or \"XYZ_Caenorhabditis_elegans\"\n" + + "or nodes already have taxonomic data?\n", + "No Taxonomic Data Extracted", + JOptionPane.ERROR_MESSAGE ); } } } @@ -1308,8 +1352,9 @@ public final class MainFrameApplication extends MainFrame { if ( getCurrentTreePanel() != null ) { final Phylogeny phy = getCurrentTreePanel().getPhylogeny(); if ( ( phy != null ) && !phy.isEmpty() ) { - PhylogenyMethods - .transferNodeNameToField( phy, PhylogenyMethods.PhylogenyNodeField.SEQUENCE_NAME, false ); + PhylogenyMethods.transferNodeNameToField( phy, + PhylogenyMethods.PhylogenyNodeField.SEQUENCE_NAME, + false ); } } } @@ -1339,7 +1384,7 @@ public final class MainFrameApplication extends MainFrame { if ( getMainPanel().getMainFrame() == null ) { // Must be "E" applet version. ( ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet() ) - .setSelectedTypeInTypeMenu( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ); + .setSelectedTypeInTypeMenu( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ); } else { getMainPanel().getMainFrame().setSelectedTypeInTypeMenu( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ); @@ -1484,8 +1529,9 @@ public final class MainFrameApplication extends MainFrame { else { try { final PhylogenyParser parser = ParserUtils - .createParserDependingOnFileType( file, getConfiguration() - .isValidatePhyloXmlAgainstSchema() ); + .createParserDependingOnFileType( file, + getConfiguration() + .isValidatePhyloXmlAgainstSchema() ); if ( parser instanceof NexusPhylogeniesParser ) { final NexusPhylogeniesParser nex = ( NexusPhylogeniesParser ) parser; setSpecialOptionsForNexParser( nex ); @@ -1535,13 +1581,12 @@ public final class MainFrameApplication extends MainFrame { getMainPanel() ); _mainpanel.getControlPanel().showWhole(); if ( nhx_or_nexus && one_desc ) { - JOptionPane - .showMessageDialog( this, - "One or more trees contain (a) node(s) with one descendant, " - + ForesterUtil.LINE_SEPARATOR - + "possibly indicating illegal parentheses within node names.", - "Warning: Possible Error in New Hampshire Formatted Data", - JOptionPane.WARNING_MESSAGE ); + JOptionPane.showMessageDialog( this, + "One or more trees contain (a) node(s) with one descendant, " + + ForesterUtil.LINE_SEPARATOR + + "possibly indicating illegal parentheses within node names.", + "Warning: Possible Error in New Hampshire Formatted Data", + JOptionPane.WARNING_MESSAGE ); } } } @@ -1564,8 +1609,8 @@ public final class MainFrameApplication extends MainFrame { if ( ( file != null ) && ( result == JFileChooser.APPROVE_OPTION ) ) { if ( _open_filechooser_for_species_tree.getFileFilter() == MainFrame.xmlfilter ) { try { - final Phylogeny[] trees = PhylogenyMethods.readPhylogenies( PhyloXmlParser - .createPhyloXmlParserXsdValidating(), file ); + final Phylogeny[] trees = PhylogenyMethods + .readPhylogenies( PhyloXmlParser.createPhyloXmlParserXsdValidating(), file ); t = trees[ 0 ]; } catch ( final Exception e ) { @@ -1586,8 +1631,8 @@ public final class MainFrameApplication extends MainFrame { // "*.*": else { try { - final Phylogeny[] trees = PhylogenyMethods.readPhylogenies( PhyloXmlParser - .createPhyloXmlParserXsdValidating(), file ); + final Phylogeny[] trees = PhylogenyMethods + .readPhylogenies( PhyloXmlParser.createPhyloXmlParserXsdValidating(), file ); t = trees[ 0 ]; } catch ( final Exception e ) { @@ -1610,23 +1655,22 @@ public final class MainFrameApplication extends MainFrame { if ( !node.getNodeData().isHasTaxonomy() ) { exception = true; t = null; - JOptionPane - .showMessageDialog( this, - "Species tree contains external node(s) without taxonomy information", - "Species tree not loaded", - JOptionPane.ERROR_MESSAGE ); + JOptionPane.showMessageDialog( this, + "Species tree contains external node(s) without taxonomy information", + "Species tree not loaded", + JOptionPane.ERROR_MESSAGE ); break; } else { if ( tax_set.contains( node.getNodeData().getTaxonomy() ) ) { exception = true; t = null; - JOptionPane.showMessageDialog( this, - "Taxonomy [" - + node.getNodeData().getTaxonomy().asSimpleText() - + "] is not unique in species tree", - "Species tree not loaded", - JOptionPane.ERROR_MESSAGE ); + JOptionPane + .showMessageDialog( this, + "Taxonomy [" + node.getNodeData().getTaxonomy().asSimpleText() + + "] is not unique in species tree", + "Species tree not loaded", + JOptionPane.ERROR_MESSAGE ); break; } else { @@ -1705,7 +1749,7 @@ public final class MainFrameApplication extends MainFrame { _file_jmenu.addSeparator(); final WebservicesManager webservices_manager = WebservicesManager.getInstance(); _load_phylogeny_from_webservice_menu_items = new JMenuItem[ webservices_manager - .getAvailablePhylogeniesWebserviceClients().size() ]; + .getAvailablePhylogeniesWebserviceClients().size() ]; for( int i = 0; i < webservices_manager.getAvailablePhylogeniesWebserviceClients().size(); ++i ) { final PhylogeniesWebserviceClient client = webservices_manager.getAvailablePhylogeniesWebserviceClient( i ); _load_phylogeny_from_webservice_menu_items[ i ] = new JMenuItem( client.getMenuName() ); @@ -1723,7 +1767,8 @@ public final class MainFrameApplication extends MainFrame { _save_all_item.setEnabled( false ); _file_jmenu.addSeparator(); _file_jmenu.add( _write_to_pdf_item = new JMenuItem( "Export to PDF file ..." ) ); - if ( AptxUtil.canWriteFormat( "tif" ) || AptxUtil.canWriteFormat( "tiff" ) || AptxUtil.canWriteFormat( "TIF" ) ) { + if ( AptxUtil.canWriteFormat( "tif" ) || AptxUtil.canWriteFormat( "tiff" ) + || AptxUtil.canWriteFormat( "TIF" ) ) { _file_jmenu.add( _write_to_tif_item = new JMenuItem( "Export to TIFF file..." ) ); } _file_jmenu.add( _write_to_png_item = new JMenuItem( "Export to PNG file..." ) ); @@ -1743,8 +1788,9 @@ public final class MainFrameApplication extends MainFrame { _file_jmenu.addSeparator(); _file_jmenu.add( _exit_item = new JMenuItem( "Exit" ) ); customizeJMenuItem( _open_item ); - _open_item - .setFont( new Font( _open_item.getFont().getFontName(), Font.BOLD, _open_item.getFont().getSize() + 4 ) ); + _open_item.setFont( new Font( _open_item.getFont().getFontName(), + Font.BOLD, + _open_item.getFont().getSize() + 4 ) ); customizeJMenuItem( _open_url_item ); for( int i = 0; i < webservices_manager.getAvailablePhylogeniesWebserviceClients().size(); ++i ) { customizeJMenuItem( _load_phylogeny_from_webservice_menu_items[ i ] ); @@ -1774,11 +1820,13 @@ public final class MainFrameApplication extends MainFrame { public void stateChanged( final ChangeEvent e ) { MainFrame.setOvPlacementColorChooseMenuItem( _overview_placment_mi, getOptions() ); MainFrame.setTextColorChooseMenuItem( _switch_colors_mi, getCurrentTreePanel() ); - MainFrame - .setTextMinSupportMenuItem( _choose_minimal_confidence_mi, getOptions(), getCurrentTreePanel() ); - MainFrame.setTextForFontChooserMenuItem( _choose_font_mi, MainFrame - .createCurrentFontDesc( getMainPanel().getTreeFontSet() ) ); - // MainFrame.setTextForGraphicsSizeChooserMenuItem( _print_size_mi, getOptions() ); + MainFrame.setTextMinSupportMenuItem( _choose_minimal_confidence_mi, + getOptions(), + getCurrentTreePanel() ); + MainFrame.setTextForFontChooserMenuItem( _choose_font_mi, + MainFrame.createCurrentFontDesc( getMainPanel() + .getTreeFontSet() ) ); + // MainFrame.setTextForGraphicsSizeChooserMenuItem( _print_size_mi, getOptions() ); MainFrame.setTextForPdfLineWidthChooserMenuItem( _choose_pdf_width_mi, getOptions() ); MainFrame.setCycleNodeFillMenuItem( _cycle_node_fill_mi, getOptions() ); MainFrame.setCycleNodeShapeMenuItem( _cycle_node_shape_mi, getOptions() ); @@ -1795,7 +1843,7 @@ public final class MainFrameApplication extends MainFrame { } ); _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( DISPLAY_SUBHEADER ), getConfiguration() ) ); _options_jmenu - .add( _ext_node_dependent_cladogram_rbmi = new JRadioButtonMenuItem( MainFrame.NONUNIFORM_CLADOGRAMS_LABEL ) ); + .add( _ext_node_dependent_cladogram_rbmi = new JRadioButtonMenuItem( MainFrame.NONUNIFORM_CLADOGRAMS_LABEL ) ); _options_jmenu.add( _uniform_cladograms_rbmi = new JRadioButtonMenuItem( MainFrame.UNIFORM_CLADOGRAMS_LABEL ) ); _options_jmenu.add( _non_lined_up_cladograms_rbmi = new JRadioButtonMenuItem( NON_LINED_UP_CLADOGRAMS_LABEL ) ); _radio_group_1 = new ButtonGroup(); @@ -1805,14 +1853,16 @@ public final class MainFrameApplication extends MainFrame { _options_jmenu.add( _show_overview_cbmi = new JCheckBoxMenuItem( SHOW_OVERVIEW_LABEL ) ); _options_jmenu.add( _show_scale_cbmi = new JCheckBoxMenuItem( DISPLAY_SCALE_LABEL ) ); _options_jmenu - .add( _show_default_node_shapes_internal_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_INT ) ); + .add( _show_default_node_shapes_internal_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_INT ) ); + _options_jmenu + .add( _show_default_node_shapes_external_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_EXT ) ); _options_jmenu - .add( _show_default_node_shapes_external_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_EXT ) ); + .add( _show_default_node_shapes_for_marked_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_NODE_BOXES_LABEL_MARKED ) ); _options_jmenu - .add( _show_default_node_shapes_for_marked_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_NODE_BOXES_LABEL_MARKED ) ); - _options_jmenu.add( _line_up_renderable_data_cbmi = new JCheckBoxMenuItem( MainFrame.LINE_UP_RENDERABLE_DATA ) ); + .add( _line_up_renderable_data_cbmi = new JCheckBoxMenuItem( MainFrame.LINE_UP_RENDERABLE_DATA ) ); if ( getConfiguration().doDisplayOption( Configuration.show_domain_architectures ) ) { - _options_jmenu.add( _right_line_up_domains_cbmi = new JCheckBoxMenuItem( MainFrame.RIGHT_LINE_UP_DOMAINS ) ); + _options_jmenu + .add( _right_line_up_domains_cbmi = new JCheckBoxMenuItem( MainFrame.RIGHT_LINE_UP_DOMAINS ) ); _options_jmenu.add( _show_domain_labels = new JCheckBoxMenuItem( MainFrame.SHOW_DOMAIN_LABELS_LABEL ) ); } _options_jmenu.add( _show_annotation_ref_source = new JCheckBoxMenuItem( SHOW_ANN_REF_SOURCE_LABEL ) ); @@ -1841,40 +1891,40 @@ public final class MainFrameApplication extends MainFrame { _options_jmenu.add( _search_with_regex_cbmi = new JCheckBoxMenuItem( MainFrame.SEARCH_REGEX_LABEL ) ); _search_with_regex_cbmi.setToolTipText( MainFrame.SEARCH_WITH_REGEX_TIP ); _options_jmenu.add( _inverse_search_result_cbmi = new JCheckBoxMenuItem( INVERSE_SEARCH_RESULT_LABEL ) ); - _options_jmenu.add( _color_all_found_nodes_when_coloring_subtree_cbmi = new JCheckBoxMenuItem( "Colorize All Found Nodes When Colorizing Subtree(s)" ) ); + _options_jmenu + .add( _color_all_found_nodes_when_coloring_subtree_cbmi = new JCheckBoxMenuItem( "Colorize All Found Nodes When Colorizing Subtree(s)" ) ); _options_jmenu.addSeparator(); - _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Graphics Export & Printing:" ), - getConfiguration() ) ); + _options_jmenu + .add( customizeMenuItemAsLabel( new JMenuItem( "Graphics Export & Printing:" ), getConfiguration() ) ); _options_jmenu.add( _antialias_print_cbmi = new JCheckBoxMenuItem( "Antialias" ) ); _options_jmenu.add( _print_black_and_white_cbmi = new JCheckBoxMenuItem( "Export in Black and White" ) ); - _options_jmenu - .add( _graphics_export_visible_only_cbmi = new JCheckBoxMenuItem( "Limit to Visible ('Screenshot') for PNG, JPG, and GIF export" ) ); + _options_jmenu + .add( _graphics_export_visible_only_cbmi = new JCheckBoxMenuItem( "Limit to Visible ('Screenshot') for PNG, JPG, and GIF export" ) ); _options_jmenu.add( _choose_pdf_width_mi = new JMenuItem( "" ) ); _options_jmenu.addSeparator(); _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Newick/NHX/Nexus Read:" ), getConfiguration() ) ); _options_jmenu - .add( _internal_number_are_confidence_for_nh_parsing_cbmi = new JCheckBoxMenuItem( "Internal Node Names are Confidence Values" ) ); + .add( _internal_number_are_confidence_for_nh_parsing_cbmi = new JCheckBoxMenuItem( "Internal Node Names are Confidence Values" ) ); _options_jmenu.add( _replace_underscores_cbmi = new JCheckBoxMenuItem( "Replace Underscores with Spaces" ) ); - _options_jmenu.add( _parse_beast_style_extended_nexus_tags_cbmi = new JCheckBoxMenuItem( "Parse BEAST-style extended Newick/Nexus tags" ) ); - - _parse_beast_style_extended_nexus_tags_cbmi.setToolTipText( "to parse elements in the form of \"[&!color=#800080]\" in Newick/Nexus formatted trees" ); - - _options_jmenu - .add( _allow_errors_in_distance_to_parent_cbmi = new JCheckBoxMenuItem( "Ignore Distance Values Format Errors" ) ); + .add( _parse_beast_style_extended_nexus_tags_cbmi = new JCheckBoxMenuItem( "Parse BEAST-style extended Newick/Nexus tags" ) ); + _parse_beast_style_extended_nexus_tags_cbmi + .setToolTipText( "to parse elements in the form of \"[&!color=#800080]\" in Newick/Nexus formatted trees" ); + _options_jmenu + .add( _allow_errors_in_distance_to_parent_cbmi = new JCheckBoxMenuItem( "Ignore Distance Values Format Errors" ) ); _options_jmenu.add( _extract_taxonomy_no_rbmi = new JRadioButtonMenuItem( "No Taxonomy Extraction" ) ); _options_jmenu - .add( _extract_taxonomy_pfam_strict_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style Node Names" ) ); + .add( _extract_taxonomy_pfam_strict_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style Node Names" ) ); _options_jmenu - .add( _extract_taxonomy_pfam_relaxed_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style like Node Names" ) ); + .add( _extract_taxonomy_pfam_relaxed_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style like Node Names" ) ); _options_jmenu - .add( _extract_taxonomy_agressive_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids/Scientific Names from Node Names" ) ); + .add( _extract_taxonomy_agressive_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids/Scientific Names from Node Names" ) ); _extract_taxonomy_pfam_strict_rbmi - .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"BCL2_MOUSE/123-304\" or \"BCL2_10090/123-304\"" ); + .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"BCL2_MOUSE/123-304\" or \"BCL2_10090/123-304\"" ); _extract_taxonomy_pfam_relaxed_rbmi - .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"bax_MOUSE\" or \"bax_10090\"" ); + .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"bax_MOUSE\" or \"bax_10090\"" ); _extract_taxonomy_agressive_rbmi - .setToolTipText( "To extract taxonomy codes/ids or scientific names from node names in the form of e.g. \"MOUSE\" or \"10090\" or \"xyz_Nematostella_vectensis\"" ); + .setToolTipText( "To extract taxonomy codes/ids or scientific names from node names in the form of e.g. \"MOUSE\" or \"10090\" or \"xyz_Nematostella_vectensis\"" ); _radio_group_2 = new ButtonGroup(); _radio_group_2.add( _extract_taxonomy_no_rbmi ); _radio_group_2.add( _extract_taxonomy_pfam_strict_rbmi ); @@ -1882,27 +1932,28 @@ public final class MainFrameApplication extends MainFrame { _radio_group_2.add( _extract_taxonomy_agressive_rbmi ); _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Newick/Nexus Save:" ), getConfiguration() ) ); _options_jmenu - .add( _use_brackets_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_BRACKETS_FOR_CONF_IN_NH_LABEL ) ); + .add( _use_brackets_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_BRACKETS_FOR_CONF_IN_NH_LABEL ) ); _use_brackets_for_conf_in_nh_export_cbmi - .setToolTipText( "e.g. \"0.1[90]\" for a branch with support 90 and a length of 0.1" ); + .setToolTipText( "e.g. \"0.1[90]\" for a branch with support 90 and a length of 0.1" ); _options_jmenu - .add( _use_internal_names_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_INTERNAL_NAMES_FOR_CONF_IN_NH_LABEL ) ); + .add( _use_internal_names_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_INTERNAL_NAMES_FOR_CONF_IN_NH_LABEL ) ); customizeJMenuItem( _choose_font_mi ); customizeJMenuItem( _choose_minimal_confidence_mi ); customizeJMenuItem( _switch_colors_mi ); customizeJMenuItem( _choose_pdf_width_mi ); customizeJMenuItem( _overview_placment_mi ); - customizeCheckBoxMenuItem( _show_default_node_shapes_external_cbmi, getOptions() - .isShowDefaultNodeShapesExternal() ); - customizeCheckBoxMenuItem( _show_default_node_shapes_internal_cbmi, getOptions() - .isShowDefaultNodeShapesInternal() ); - customizeCheckBoxMenuItem( _show_default_node_shapes_for_marked_cbmi, getOptions() - .isShowDefaultNodeShapesForMarkedNodes() ); + customizeCheckBoxMenuItem( _show_default_node_shapes_external_cbmi, + getOptions().isShowDefaultNodeShapesExternal() ); + customizeCheckBoxMenuItem( _show_default_node_shapes_internal_cbmi, + getOptions().isShowDefaultNodeShapesInternal() ); + customizeCheckBoxMenuItem( _show_default_node_shapes_for_marked_cbmi, + getOptions().isShowDefaultNodeShapesForMarkedNodes() ); customizeJMenuItem( _cycle_node_shape_mi ); customizeJMenuItem( _cycle_node_fill_mi ); customizeJMenuItem( _choose_node_size_mi ); customizeJMenuItem( _cycle_data_return ); - customizeCheckBoxMenuItem( _color_labels_same_as_parent_branch, getOptions().isColorLabelsSameAsParentBranch() ); + customizeCheckBoxMenuItem( _color_labels_same_as_parent_branch, + getOptions().isColorLabelsSameAsParentBranch() ); customizeCheckBoxMenuItem( _color_by_taxonomic_group_cbmi, getOptions().isColorByTaxonomicGroup() ); customizeCheckBoxMenuItem( _screen_antialias_cbmi, getOptions().isAntialiasScreen() ); customizeCheckBoxMenuItem( _background_gradient_cbmi, getOptions().isBackgroundColorGradient() ); @@ -1922,8 +1973,8 @@ public final class MainFrameApplication extends MainFrame { getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL ); customizeCheckBoxMenuItem( _antialias_print_cbmi, getOptions().isAntialiasPrint() ); customizeCheckBoxMenuItem( _print_black_and_white_cbmi, getOptions().isPrintBlackAndWhite() ); - customizeCheckBoxMenuItem( _internal_number_are_confidence_for_nh_parsing_cbmi, getOptions() - .isInternalNumberAreConfidenceForNhParsing() ); + customizeCheckBoxMenuItem( _internal_number_are_confidence_for_nh_parsing_cbmi, + getOptions().isInternalNumberAreConfidenceForNhParsing() ); customizeRadioButtonMenuItem( _extract_taxonomy_no_rbmi, getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.NO ); customizeRadioButtonMenuItem( _extract_taxonomy_pfam_strict_rbmi, @@ -1933,20 +1984,23 @@ public final class MainFrameApplication extends MainFrame { customizeRadioButtonMenuItem( _extract_taxonomy_agressive_rbmi, getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.AGGRESSIVE ); customizeCheckBoxMenuItem( _replace_underscores_cbmi, getOptions().isReplaceUnderscoresInNhParsing() ); - customizeCheckBoxMenuItem( _allow_errors_in_distance_to_parent_cbmi, getOptions() - .isReplaceUnderscoresInNhParsing() ); + customizeCheckBoxMenuItem( _allow_errors_in_distance_to_parent_cbmi, + getOptions().isReplaceUnderscoresInNhParsing() ); customizeCheckBoxMenuItem( _search_with_regex_cbmi, getOptions().isSearchWithRegex() ); customizeCheckBoxMenuItem( _search_whole_words_only_cbmi, getOptions().isMatchWholeTermsOnly() ); customizeCheckBoxMenuItem( _inverse_search_result_cbmi, getOptions().isInverseSearchResult() ); - customizeCheckBoxMenuItem( _color_all_found_nodes_when_coloring_subtree_cbmi, getOptions().isColorAllFoundNodesWhenColoringSubtree() ); - customizeCheckBoxMenuItem( _parse_beast_style_extended_nexus_tags_cbmi, getOptions().isParseBeastStyleExtendedNexusTags() ); - + customizeCheckBoxMenuItem( _color_all_found_nodes_when_coloring_subtree_cbmi, + getOptions().isColorAllFoundNodesWhenColoringSubtree() ); + customizeCheckBoxMenuItem( _parse_beast_style_extended_nexus_tags_cbmi, + getOptions().isParseBeastStyleExtendedNexusTags() ); customizeCheckBoxMenuItem( _graphics_export_visible_only_cbmi, getOptions().isGraphicsExportVisibleOnly() ); customizeCheckBoxMenuItem( _show_confidence_stddev_cbmi, getOptions().isShowConfidenceStddev() ); - customizeCheckBoxMenuItem( _use_brackets_for_conf_in_nh_export_cbmi, getOptions() - .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.IN_SQUARE_BRACKETS ); - customizeCheckBoxMenuItem( _use_internal_names_for_conf_in_nh_export_cbmi, getOptions() - .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.AS_INTERNAL_NODE_NAMES ); + customizeCheckBoxMenuItem( _use_brackets_for_conf_in_nh_export_cbmi, + getOptions() + .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.IN_SQUARE_BRACKETS ); + customizeCheckBoxMenuItem( _use_internal_names_for_conf_in_nh_export_cbmi, + getOptions() + .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.AS_INTERNAL_NODE_NAMES ); customizeCheckBoxMenuItem( _line_up_renderable_data_cbmi, getOptions().isLineUpRendarableNodeData() ); customizeCheckBoxMenuItem( _right_line_up_domains_cbmi, getOptions().isRightLineUpDomains() ); _jmenubar.add( _options_jmenu ); @@ -1962,11 +2016,11 @@ public final class MainFrameApplication extends MainFrame { _inference_menu.add( _inference_from_seqs_item = new JMenuItem( "From Unaligned Sequences..." ) ); customizeJMenuItem( _inference_from_seqs_item ); _inference_from_seqs_item - .setToolTipText( "Basic phylogenetic inference including multiple sequence alignment" ); + .setToolTipText( "Basic phylogenetic inference including multiple sequence alignment" ); } else { _inference_menu - .add( _inference_from_seqs_item = new JMenuItem( "From Unaligned Sequences (no program found)" ) ); + .add( _inference_from_seqs_item = new JMenuItem( "From Unaligned Sequences (no program found)" ) ); customizeJMenuItem( _inference_from_seqs_item ); _inference_from_seqs_item.setEnabled( false ); } @@ -1985,7 +2039,7 @@ public final class MainFrameApplication extends MainFrame { _tools_menu.addSeparator(); _tools_menu.add( _remove_visual_styles_item = new JMenuItem( "Delete All Visual Styles From Nodes" ) ); _remove_visual_styles_item - .setToolTipText( "To remove all node visual styles (fonts, colors) from the current phylogeny" ); + .setToolTipText( "To remove all node visual styles (fonts, colors) from the current phylogeny" ); customizeJMenuItem( _remove_visual_styles_item ); _tools_menu.add( _remove_branch_color_item = new JMenuItem( "Delete All Colors From Branches" ) ); _remove_branch_color_item.setToolTipText( "To remove all branch color values from the current phylogeny" ); @@ -2007,26 +2061,29 @@ public final class MainFrameApplication extends MainFrame { _tools_menu.add( _collapse_species_specific_subtrees = new JMenuItem( "Collapse Species-Specific Subtrees" ) ); customizeJMenuItem( _collapse_species_specific_subtrees ); _collapse_species_specific_subtrees.setToolTipText( "To (reversibly) collapse species-specific subtrees" ); + _tools_menu.add( _collapse_by_taxonomic_rank = new JMenuItem( "Collapse By Taxonomic Rank" ) ); + customizeJMenuItem( _collapse_by_taxonomic_rank ); + _collapse_by_taxonomic_rank.setToolTipText( "To (reversibly) collapse subtrees by taxonomic rank" ); _tools_menu - .add( _collapse_below_threshold = new JMenuItem( "Collapse Branches with Confidence Below Threshold into Multifurcations" ) ); + .add( _collapse_below_threshold = new JMenuItem( "Collapse Branches with Confidence Below Threshold into Multifurcations" ) ); customizeJMenuItem( _collapse_below_threshold ); _collapse_below_threshold - .setToolTipText( "To (permanently) collapse branches with confidence values below a threshold into multifurcations (in the case of multiple confidences per branch: without at least one confidence value above a threshold)" ); + .setToolTipText( "To (permanently) collapse branches with confidence values below a threshold into multifurcations (in the case of multiple confidences per branch: without at least one confidence value above a threshold)" ); // _tools_menu - .add( _collapse_below_branch_length = new JMenuItem( "Collapse Branches with Branch Lengths Below Threshold into Multifurcations" ) ); + .add( _collapse_below_branch_length = new JMenuItem( "Collapse Branches with Branch Lengths Below Threshold into Multifurcations" ) ); customizeJMenuItem( _collapse_below_branch_length ); _collapse_below_branch_length - .setToolTipText( "To (permanently) collapse branches with branches with branch lengths below a threshold into multifurcations" ); + .setToolTipText( "To (permanently) collapse branches with branches with branch lengths below a threshold into multifurcations" ); // _tools_menu.addSeparator(); _tools_menu - .add( _extract_tax_code_from_node_names_jmi = new JMenuItem( "Extract Taxonomic Data from Node Names" ) ); + .add( _extract_tax_code_from_node_names_jmi = new JMenuItem( "Extract Taxonomic Data from Node Names" ) ); customizeJMenuItem( _extract_tax_code_from_node_names_jmi ); _extract_tax_code_from_node_names_jmi - .setToolTipText( "To extract SwissProt/Uniprot taxonomic codes (mnemonics) from nodes names in the form of 'xyz_CAEEL', Uniprot/NCBI identifiers form of 'xyz_6239', or scientific names form of 'xyz_Caenorhabditis_elegans'" ); + .setToolTipText( "To extract SwissProt/Uniprot taxonomic codes (mnemonics) from nodes names in the form of 'xyz_CAEEL', Uniprot/NCBI identifiers form of 'xyz_6239', or scientific names form of 'xyz_Caenorhabditis_elegans'" ); _tools_menu - .add( _move_node_names_to_tax_sn_jmi = new JMenuItem( "Transfer Node Names to Taxonomic Scientific Names" ) ); + .add( _move_node_names_to_tax_sn_jmi = new JMenuItem( "Transfer Node Names to Taxonomic Scientific Names" ) ); customizeJMenuItem( _move_node_names_to_tax_sn_jmi ); _move_node_names_to_tax_sn_jmi.setToolTipText( "To interpret node names as taxonomic scientific names" ); _tools_menu.add( _move_node_names_to_seq_names_jmi = new JMenuItem( "Transfer Node Names to Sequence Names" ) ); @@ -2037,15 +2094,15 @@ public final class MainFrameApplication extends MainFrame { customizeJMenuItem( _obtain_seq_information_jmi ); _obtain_seq_information_jmi.setToolTipText( "To add additional sequence information" ); _tools_menu - .add( _obtain_detailed_taxonomic_information_jmi = new JMenuItem( OBTAIN_DETAILED_TAXONOMIC_INFORMATION ) ); + .add( _obtain_detailed_taxonomic_information_jmi = new JMenuItem( OBTAIN_DETAILED_TAXONOMIC_INFORMATION ) ); customizeJMenuItem( _obtain_detailed_taxonomic_information_jmi ); _obtain_detailed_taxonomic_information_jmi - .setToolTipText( "To add additional taxonomic information (from UniProt Taxonomy)" ); + .setToolTipText( "To add additional taxonomic information (from UniProt Taxonomy)" ); _tools_menu - .add( _obtain_detailed_taxonomic_information_deleting_jmi = new JMenuItem( "Obtain Detailed Taxonomic Information (deletes nodes!)" ) ); + .add( _obtain_detailed_taxonomic_information_deleting_jmi = new JMenuItem( "Obtain Detailed Taxonomic Information (deletes nodes!)" ) ); customizeJMenuItem( _obtain_detailed_taxonomic_information_deleting_jmi ); _obtain_detailed_taxonomic_information_deleting_jmi - .setToolTipText( "To add additional taxonomic information, deletes nodes for which taxonomy cannot found (from UniProt Taxonomy)" ); + .setToolTipText( "To add additional taxonomic information, deletes nodes for which taxonomy cannot found (from UniProt Taxonomy)" ); _tools_menu.addSeparator(); _tools_menu.add( _read_values_jmi = new JMenuItem( "Attach Vector/Expression Values" ) ); customizeJMenuItem( _read_values_jmi ); @@ -2054,7 +2111,7 @@ public final class MainFrameApplication extends MainFrame { _tools_menu.add( _read_seqs_jmi = new JMenuItem( "Attach Molecular Sequences" ) ); customizeJMenuItem( _read_seqs_jmi ); _read_seqs_jmi - .setToolTipText( "To attach molecular sequences to tree nodes (from Fasta-formatted file) (beta)" ); + .setToolTipText( "To attach molecular sequences to tree nodes (from Fasta-formatted file) (beta)" ); _jmenubar.add( _tools_menu ); } @@ -2085,10 +2142,11 @@ public final class MainFrameApplication extends MainFrame { URL url = null; Phylogeny[] phys = null; final String message = "Please enter a complete URL, for example \"http://purl.org/phylo/treebase/phylows/study/TB2:S15480?format=nexus\""; - final String url_string = JOptionPane.showInputDialog( this, - message, - "Use URL/webservice to obtain a phylogeny", - JOptionPane.QUESTION_MESSAGE ); + final String url_string = JOptionPane + .showInputDialog( this, + message, + "Use URL/webservice to obtain a phylogeny", + JOptionPane.QUESTION_MESSAGE ); boolean nhx_or_nexus = false; if ( ( url_string != null ) && ( url_string.length() > 0 ) ) { try { @@ -2098,8 +2156,9 @@ public final class MainFrameApplication extends MainFrame { parser = new TolParser(); } else { - parser = ParserUtils.createParserDependingOnUrlContents( url, getConfiguration() - .isValidatePhyloXmlAgainstSchema() ); + parser = ParserUtils + .createParserDependingOnUrlContents( url, + getConfiguration().isValidatePhyloXmlAgainstSchema() ); } if ( parser instanceof NexusPhylogeniesParser ) { nhx_or_nexus = true; @@ -2126,8 +2185,8 @@ public final class MainFrameApplication extends MainFrame { JOptionPane.showMessageDialog( this, "Could not read from " + url + "\n" + ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ), - "Failed to read URL", - JOptionPane.ERROR_MESSAGE ); + "Failed to read URL", + JOptionPane.ERROR_MESSAGE ); } catch ( final Exception e ) { JOptionPane.showMessageDialog( this, @@ -2198,11 +2257,10 @@ public final class MainFrameApplication extends MainFrame { static void warnIfNotPhyloXmlValidation( final Configuration c ) { if ( !c.isValidatePhyloXmlAgainstSchema() ) { - JOptionPane - .showMessageDialog( null, - ForesterUtil - .wordWrap( "phyloXML XSD-based validation is turned off [enable with line 'validate_against_phyloxml_xsd_schem: true' in configuration file]", - 80 ), + JOptionPane.showMessageDialog( null, + ForesterUtil.wordWrap( + "phyloXML XSD-based validation is turned off [enable with line 'validate_against_phyloxml_xsd_schem: true' in configuration file]", + 80 ), "Warning", JOptionPane.WARNING_MESSAGE ); } diff --git a/forester/java/src/org/forester/archaeopteryx/TreePanel.java b/forester/java/src/org/forester/archaeopteryx/TreePanel.java index a20689d..c60d06a 100644 --- a/forester/java/src/org/forester/archaeopteryx/TreePanel.java +++ b/forester/java/src/org/forester/archaeopteryx/TreePanel.java @@ -49,6 +49,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.font.FontRenderContext; +import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; @@ -68,6 +69,7 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; +import java.text.AttributedString; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; @@ -77,6 +79,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.SortedSet; @@ -313,6 +316,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee private float _y_distance = 0.0f; private int _length_of_longest_text; private int _longest_domain; + private Map _attributed_string_map = null; static { final DecimalFormatSymbols dfs = new DecimalFormatSymbols(); dfs.setDecimalSeparator( '.' ); @@ -1396,6 +1400,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee case GET_EXT_DESC_DATA: showExtDescNodeData( node ); break; + case UNCOLLAPSE_ALL: + uncollapseAll( node ); + break; + case ORDER_SUBTREE: + orderSubtree( node ); + break; default: throw new IllegalArgumentException( "unknown action: " + action ); } @@ -1801,6 +1811,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( title.equals( Configuration.clickto_options[ Configuration.sort_descendents ][ 0 ] ) ) { _node_popup_menu_items[ i ].setEnabled( node.getNumberOfDescendants() > 1 ); } + else if ( title.equals( Configuration.clickto_options[ Configuration.uncollapse_all ][ 0 ] ) ) { + _node_popup_menu_items[ i ].setEnabled( isCanUncollapseAll( node ) ); + } _node_popup_menu_items[ i ].addActionListener( this ); _node_popup_menu.add( _node_popup_menu_items[ i ] ); } @@ -1857,6 +1870,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } private final void nodeTaxonomyDataAsSB( final Taxonomy taxonomy, final StringBuilder sb ) { + if ( _control_panel.isShowTaxonomyRank() && !ForesterUtil.isEmpty( taxonomy.getRank() ) ) { + sb.append( "[" ); + sb.append( taxonomy.getRank() ); + sb.append( "] " ); + } if ( _control_panel.isShowTaxonomyCode() && !ForesterUtil.isEmpty( taxonomy.getTaxonomyCode() ) ) { sb.append( taxonomy.getTaxonomyCode() ); sb.append( " " ); @@ -2713,7 +2731,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee x += drawTaxonomyImage( node.getXcoord() + 2 + half_box_size, node.getYcoord(), node, g ); } if ( ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() || getControlPanel() - .isShowTaxonomyCommonNames() ) && node.getNodeData().isHasTaxonomy() ) { + .isShowTaxonomyCommonNames() || getControlPanel().isShowTaxonomyRank() ) && node.getNodeData().isHasTaxonomy() ) { x += paintTaxonomy( g, node, is_in_found_nodes, to_pdf, to_graphics_file, x ); } setColor( g, node, to_graphics_file, to_pdf, is_in_found_nodes, getTreeColorSet().getSequenceColor() ); @@ -2799,7 +2817,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } if ( sb_str.length() > 0 ) { - TreePanel.drawString( sb_str, pos_x, pos_y, g ); + if ( !isAllowAttributedStrings() ) { + TreePanel.drawString( sb_str, pos_x, pos_y, g ); + } + else { + drawStringX( sb_str, pos_x, pos_y, g ); + } } // GUILHEM_END _____________ if ( _sb.length() > 0 ) { @@ -2869,6 +2892,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return x; } + private final boolean isAllowAttributedStrings() { + return false; + } + final private void paintNodeDataUnrootedCirc( final Graphics2D g, final PhylogenyNode node, final boolean to_pdf, @@ -4693,6 +4720,29 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee repaint(); } } + + final void uncollapseAll( final PhylogenyNode node ) { + if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) { + JOptionPane.showMessageDialog( this, + "Cannot uncollapse in unrooted display type", + "Attempt to uncollapse in unrooted display", + JOptionPane.WARNING_MESSAGE ); + return; + } + if ( !node.isExternal() ) { + TreePanelUtil.uncollapseSubtree( node); + updateSetOfCollapsedExternalNodes(); + _phylogeny.recalculateNumberOfExternalDescendants( true ); + resetNodeIdToDistToLeafMap(); + calculateLongestExtNodeInfo(); + setNodeInPreorderToNull(); + _control_panel.displayedPhylogenyMightHaveChanged( true ); + resetPreferredSize(); + updateOvSizes(); + _main_panel.adjustJScrollPane(); + repaint(); + } + } final void collapseSpeciesSpecificSubtrees() { if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) { @@ -4711,6 +4761,44 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee repaint(); } + final void collapseByTaxonomicRank( final String rank ) { + if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) { + return; + } + setWaitCursor(); + + final int collapsed = TreePanelUtil.collapseByTaxonomicRank( _phylogeny, rank, this ); + + setArrowCursor(); + repaint(); + if ( collapsed > 0 ) { + String msg = "Collapsing via " + rank + " completed:\n"; + if ( collapsed > 1 ) { + msg += "collapsed " + collapsed + " subtrees"; + } + else { + msg += "collapsed one subtree"; + } + setEdited( true ); + JOptionPane.showMessageDialog( this, + msg, + "Taxonomy Rank-Collapsing Completed (" + rank + ")", + JOptionPane.INFORMATION_MESSAGE ); + } + else { + String msg = "Could not taxonomy rank-collapse any subtree via " + rank + ".\n"; + msg += "Possible solutions (given that suitable taxonomic information is present):\n"; + msg += "select a different rank (e.g. phylum, genus, ...)\n"; + msg += " and/or\n"; + msg += "execute:\n"; + msg += "1. \"" + MainFrameApplication.OBTAIN_DETAILED_TAXONOMIC_INFORMATION + "\" (Tools)\n"; + msg += "2. \"" + MainFrameApplication.INFER_ANCESTOR_TAXONOMIES + "\" (Analysis)"; + JOptionPane.showMessageDialog( this, msg, "Taxonomy Rank-Collapsing Failed", JOptionPane.WARNING_MESSAGE ); + } + } + + + final void colorRank( final String rank ) { if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) { return; @@ -4745,18 +4833,18 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setEdited( true ); JOptionPane.showMessageDialog( this, msg, - "Taxonomy Colorization Completed (" + rank + ")", + "Taxonomy Rank-Colorization Completed (" + rank + ")", JOptionPane.INFORMATION_MESSAGE ); } else { - String msg = "Could not taxonomy colorize any subtree via " + rank + ".\n"; + String msg = "Could not taxonomy rank-colorize any subtree via " + rank + ".\n"; msg += "Possible solutions (given that suitable taxonomic information is present):\n"; msg += "select a different rank (e.g. phylum, genus, ...)\n"; msg += " and/or\n"; msg += "execute:\n"; msg += "1. \"" + MainFrameApplication.OBTAIN_DETAILED_TAXONOMIC_INFORMATION + "\" (Tools)\n"; msg += "2. \"" + MainFrameApplication.INFER_ANCESTOR_TAXONOMIES + "\" (Analysis)"; - JOptionPane.showMessageDialog( this, msg, "Taxonomy Colorization Failed", JOptionPane.WARNING_MESSAGE ); + JOptionPane.showMessageDialog( this, msg, "Taxonomy Rank-Colorization Failed", JOptionPane.WARNING_MESSAGE ); } } @@ -5001,7 +5089,23 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final boolean isCanCollapse() { return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ); } - + + final boolean isCanUncollapseAll( final PhylogenyNode node ) { + if ( node.isExternal() || getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) { + return false; + } + if ( node.isCollapse() ) { + return true; + } + final PhylogenyNodeIterator it = new PreorderTreeIterator( node ); + while ( it.hasNext() ) { + if ( it.next().isCollapse() ) { + return true; + } + } + return false; + } + final boolean isCanColorSubtree() { return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ); } @@ -5911,6 +6015,29 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee updateSubSuperTreeButton(); } + final void orderSubtree( final PhylogenyNode node ) { + if ( node.isExternal() ) { + return; + } + DESCENDANT_SORT_PRIORITY pri = DESCENDANT_SORT_PRIORITY.NODE_NAME; + if ( getControlPanel().isShowTaxonomyScientificNames() || getControlPanel().isShowTaxonomyCode() ) { + pri = DESCENDANT_SORT_PRIORITY.TAXONOMY; + } + else if ( getControlPanel().isShowSeqNames() || getControlPanel().isShowSeqSymbols() || getControlPanel().isShowGeneNames() ) { + pri = DESCENDANT_SORT_PRIORITY.SEQUENCE; + } + PhylogenyMethods.orderAppearanceX( node, true, pri ); + + setNodeInPreorderToNull(); + getPhylogeny().externalNodesHaveChanged(); + getPhylogeny().clearHashIdToNodeMap(); + getPhylogeny().recalculateNumberOfExternalDescendants( true ); + resetNodeIdToDistToLeafMap(); + setEdited( true ); + getControlPanel().displayedPhylogenyMightHaveChanged( true ); + repaint(); + } + final void swap( final PhylogenyNode node ) { if ( node.isExternal() || ( node.getNumberOfDescendants() < 2 ) ) { return; @@ -6061,6 +6188,38 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final private static void drawString( final String str, final float x, final float y, final Graphics2D g ) { g.drawString( str, x, y ); } + + + final private void drawStringX( final String str, final float x, final float y, final Graphics2D g ) { + //TODO + //FIXME + if ( getAttributedStringMap() == null /*&& getAttributedStringMap().containsKey(str) */ ) { + final AttributedString as = new AttributedString(str); + //Font plainFont = new Font("Times New Roman", Font.PLAIN, 24); + + as.addAttribute(TextAttribute.FONT, g.getFont()); + as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 1, 3); + as.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 3, 4); + + as.addAttribute(TextAttribute.FOREGROUND, Color.BLUE, 1, 2); + as.addAttribute(TextAttribute.FOREGROUND, Color.PINK, 3, 5); + as.addAttribute(TextAttribute.STRIKETHROUGH, + TextAttribute.STRIKETHROUGH_ON, 2, 4); + g.drawString(as.getIterator(), x, y); + } + else { + g.drawString( str, x, y ); + } + } + + + private final Map getAttributedStringMap() { + return _attributed_string_map ; + } + + private final void setAttributedStringMap( final Map attributed_string_map ) { + _attributed_string_map = attributed_string_map; + } final private static boolean plusPressed( final int key_code ) { return ( ( key_code == KeyEvent.VK_ADD ) || ( key_code == KeyEvent.VK_PLUS ) diff --git a/forester/java/src/org/forester/archaeopteryx/TreePanelUtil.java b/forester/java/src/org/forester/archaeopteryx/TreePanelUtil.java index ac47498..a7d8d87 100644 --- a/forester/java/src/org/forester/archaeopteryx/TreePanelUtil.java +++ b/forester/java/src/org/forester/archaeopteryx/TreePanelUtil.java @@ -149,8 +149,8 @@ public class TreePanelUtil { } if ( cp.isShowSeqSymbols() && node.getNodeData().isHasSequence() && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) { - TreePanelUtil - .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getSymbol(), sb ); + TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getSymbol(), + sb ); } if ( cp.isShowGeneNames() && node.getNodeData().isHasSequence() && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getGeneName() ) ) { @@ -165,18 +165,20 @@ public class TreePanelUtil { } if ( cp.isShowTaxonomyCode() && node.getNodeData().isHasTaxonomy() && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) { - TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy() - .getTaxonomyCode(), sb ); + TreePanelUtil + .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getTaxonomyCode(), + sb ); } if ( cp.isShowTaxonomyScientificNames() && node.getNodeData().isHasTaxonomy() && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) { - TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy() - .getScientificName(), sb ); + TreePanelUtil + .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getScientificName(), + sb ); } if ( cp.isShowTaxonomyCommonNames() && node.getNodeData().isHasTaxonomy() && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) { - TreePanelUtil - .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getCommonName(), sb ); + TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getCommonName(), + sb ); } // if ( ( cp.isShowSeqNames() || cp.isShowSeqSymbols() || cp.isShowSequenceAcc() ) // && node.getNodeData().isHasSequence() @@ -236,6 +238,17 @@ public class TreePanelUtil { } } + final static void uncollapseSubtree( final PhylogenyNode node ) { + node.setCollapse( false ); + if ( node.isExternal() ) { + return; + } + final PhylogenyNodeIterator it = new PreorderTreeIterator( node ); + while ( it.hasNext() ) { + it.next().setCollapse( false ); + } + } + static void colorizeSubtree( final PhylogenyNode node, final BranchColor c ) { node.getBranchData().setBranchColor( c ); final List descs = PhylogenyMethods.getAllDescendants( node ); @@ -279,7 +292,8 @@ public class TreePanelUtil { if ( !n.getBranchData().isHasBranchColor() ) { final Taxonomy tax = PhylogenyMethods.getExternalDescendantsTaxonomy( n ); if ( tax != null ) { - n.getBranchData().setBranchColor( new BranchColor( tree_panel.calculateTaxonomyBasedColor( tax ) ) ); + n.getBranchData() + .setBranchColor( new BranchColor( tree_panel.calculateTaxonomyBasedColor( tax ) ) ); final List descs = PhylogenyMethods.getAllDescendants( n ); for( final PhylogenyNode desc : descs ) { desc.getBranchData() @@ -290,23 +304,106 @@ public class TreePanelUtil { } } - final static int colorPhylogenyAccordingToRanks( final Phylogeny tree, final String rank, final TreePanel tree_panel ) { + final static int collapseByTaxonomicRank( final Phylogeny tree, final String rank, final TreePanel tree_panel ) { + final Set true_lineage_set = new HashSet(); + for( final PhylogenyNodeIterator iter = tree.iteratorPreorder(); iter.hasNext(); ) { + iter.next().setCollapse( false ); + } + int collapsed = 0; + for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) { + final PhylogenyNode n = it.next(); + if ( !n.isExternal() && n.getNodeData().isHasTaxonomy() && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getRank() ) + && n.getNodeData().getTaxonomy().getRank().equalsIgnoreCase( rank ) /*&& !n.isRoot()*/ ) { + TreePanelUtil.collapseSubtree( n, true ); + ++collapsed; + if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) { + true_lineage_set.add( n.getNodeData().getTaxonomy().getScientificName() ); + System.out.println( "1 true_lineage_set added " + n.getNodeData().getTaxonomy().getScientificName() ); + } + } + } + for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) { + final PhylogenyNode node = it.next(); + if ( ( !node.isExternal() && !node.isCollapse() ) && node.getNodeData().isHasTaxonomy() + && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getLineage() ) /* && !node.isRoot()*/ ) { + boolean success = false; + if ( !true_lineage_set.isEmpty() ) { + for( final String lin : node.getNodeData().getTaxonomy().getLineage() ) { + if ( true_lineage_set.contains( lin ) ) { + //TreePanelUtil + // .colorizeSubtree( node, new BranchColor( true_lineage_to_color_map.get( lin ) ) ); + TreePanelUtil.collapseSubtree( node, true ); + ++collapsed; + success = true; + break; + } + } + } + if ( !success ) { + final Map lineage_to_rank_map = MainPanel.getLineageToRankMap(); + for( final String lin : node.getNodeData().getTaxonomy().getLineage() ) { + final Taxonomy temp_tax = new Taxonomy(); + temp_tax.setScientificName( lin ); + if ( lineage_to_rank_map.containsKey( lin ) + && !ForesterUtil.isEmpty( lineage_to_rank_map.get( lin ) ) + && lineage_to_rank_map.get( lin ).equalsIgnoreCase( rank ) ) { + //final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( temp_tax ) ); + //TreePanelUtil.colorizeSubtree( node, c ); + TreePanelUtil.collapseSubtree( node, true ); + ++collapsed; + true_lineage_set.add( lin ); + System.out.println( "2 true_lineage_set added " + lin ); + break; + } + else { + UniProtTaxonomy up = null; + try { + up = TaxonomyDataManager.obtainUniProtTaxonomy( temp_tax, null, null ); + } + catch ( final Exception e ) { + e.printStackTrace(); + } + if ( ( up != null ) && !ForesterUtil.isEmpty( up.getRank() ) ) { + lineage_to_rank_map.put( lin, up.getRank() ); + System.out.println( lin + "->" + up.getRank() ); + if ( up.getRank().equalsIgnoreCase( rank ) ) { + // final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( temp_tax ) ); + // TreePanelUtil.colorizeSubtree( node, c ); + TreePanelUtil.collapseSubtree( node, true ); + ++collapsed; + true_lineage_set.add( lin ); + System.out.println( "3 true_lineage_set added " + lin ); + break; + } + } + } + } + } + } + } + return collapsed; + } + + final static int colorPhylogenyAccordingToRanks( final Phylogeny tree, + final String rank, + final TreePanel tree_panel ) { final Map true_lineage_to_color_map = new HashMap(); int colorizations = 0; for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) { final PhylogenyNode n = it.next(); if ( n.getNodeData().isHasTaxonomy() && ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) - || !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) || !ForesterUtil - .isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) { + || !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) + || !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) { if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getRank() ) && n.getNodeData().getTaxonomy().getRank().equalsIgnoreCase( rank ) ) { - final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( n.getNodeData() - .getTaxonomy() ) ); + final BranchColor c = new BranchColor( tree_panel + .calculateTaxonomyBasedColor( n.getNodeData().getTaxonomy() ) ); TreePanelUtil.colorizeSubtree( n, c ); ++colorizations; if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) { - true_lineage_to_color_map.put( n.getNodeData().getTaxonomy().getScientificName(), c.getValue() ); + true_lineage_to_color_map.put( n.getNodeData().getTaxonomy().getScientificName(), + c.getValue() ); } } } @@ -319,8 +416,8 @@ public class TreePanelUtil { if ( !true_lineage_to_color_map.isEmpty() ) { for( final String lin : node.getNodeData().getTaxonomy().getLineage() ) { if ( true_lineage_to_color_map.containsKey( lin ) ) { - TreePanelUtil - .colorizeSubtree( node, new BranchColor( true_lineage_to_color_map.get( lin ) ) ); + TreePanelUtil.colorizeSubtree( node, + new BranchColor( true_lineage_to_color_map.get( lin ) ) ); ++colorizations; success = true; break; @@ -351,8 +448,10 @@ public class TreePanelUtil { } if ( ( up != null ) && !ForesterUtil.isEmpty( up.getRank() ) ) { lineage_to_rank_map.put( lin, up.getRank() ); + System.out.println( lin + "->" + up.getRank() ); if ( up.getRank().equalsIgnoreCase( rank ) ) { - final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( temp_tax ) ); + final BranchColor c = new BranchColor( tree_panel + .calculateTaxonomyBasedColor( temp_tax ) ); TreePanelUtil.colorizeSubtree( node, c ); ++colorizations; true_lineage_to_color_map.put( lin, c.getValue() ); @@ -367,7 +466,8 @@ public class TreePanelUtil { return colorizations; } - final static String createAnnotationString( final SortedSet annotations, final boolean show_ref_sources ) { + final static String createAnnotationString( final SortedSet annotations, + final boolean show_ref_sources ) { final SortedMap> m = new TreeMap>(); for( final Annotation an : annotations ) { final String ref_source = ForesterUtil.isEmpty( an.getRefSource() ) ? "?" : an.getRefSource(); @@ -435,8 +535,8 @@ public class TreePanelUtil { final static boolean isTaxonomyEmpty( final Taxonomy tax ) { return ( ( tax.getIdentifier() == null ) && ForesterUtil.isEmpty( tax.getTaxonomyCode() ) - && ForesterUtil.isEmpty( tax.getCommonName() ) && ForesterUtil.isEmpty( tax.getScientificName() ) && tax - .getSynonyms().isEmpty() ); + && ForesterUtil.isEmpty( tax.getCommonName() ) && ForesterUtil.isEmpty( tax.getScientificName() ) + && tax.getSynonyms().isEmpty() ); } static final int nodeDataIntoStringBuffer( final List data, final Options optz, final StringBuilder sb ) { diff --git a/forester/java/src/org/forester/io/parsers/phyloxml/PhyloXmlMapping.java b/forester/java/src/org/forester/io/parsers/phyloxml/PhyloXmlMapping.java index 1db3384..d9db39d 100644 --- a/forester/java/src/org/forester/io/parsers/phyloxml/PhyloXmlMapping.java +++ b/forester/java/src/org/forester/io/parsers/phyloxml/PhyloXmlMapping.java @@ -125,6 +125,7 @@ public final class PhyloXmlMapping { public static final String TAXONOMY_RANK = "rank"; public static final String TAXONOMY_SCIENTIFIC_NAME = "scientific_name"; public static final String TAXONOMY_SYNONYM = "synonym"; + public static final String TAXONOMY_LINEAGE = "lineage"; public static final String TYPE_ATTR = "type"; public static final String URI = "uri"; public static final String URI_DESC_ATTR = "desc"; diff --git a/forester/java/src/org/forester/io/parsers/phyloxml/data/TaxonomyParser.java b/forester/java/src/org/forester/io/parsers/phyloxml/data/TaxonomyParser.java index f55028f..74d11df 100644 --- a/forester/java/src/org/forester/io/parsers/phyloxml/data/TaxonomyParser.java +++ b/forester/java/src/org/forester/io/parsers/phyloxml/data/TaxonomyParser.java @@ -25,6 +25,8 @@ package org.forester.io.parsers.phyloxml.data; +import java.util.Arrays; + import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException; import org.forester.io.parsers.phyloxml.PhyloXmlMapping; import org.forester.io.parsers.phyloxml.XmlElement; @@ -77,6 +79,12 @@ public class TaxonomyParser implements PhylogenyDataPhyloXmlParser { else if ( child_element.getQualifiedName().equals( PhyloXmlMapping.URI ) ) { taxonomy.addUri( ( Uri ) UriParser.getInstance().parse( child_element ) ); } + else if ( child_element.getQualifiedName().equals( PhyloXmlMapping.TAXONOMY_LINEAGE ) ) { + final String[] lineage = child_element.getValueAsString().split( "," ); + if ( lineage != null && lineage.length > 0 ) { + taxonomy.setLineage( Arrays.asList(lineage) ); + } + } } } return taxonomy; diff --git a/forester/java/src/org/forester/phylogeny/PhylogenyMethods.java b/forester/java/src/org/forester/phylogeny/PhylogenyMethods.java index a5cf36a..09f9955 100644 --- a/forester/java/src/org/forester/phylogeny/PhylogenyMethods.java +++ b/forester/java/src/org/forester/phylogeny/PhylogenyMethods.java @@ -68,6 +68,8 @@ import org.forester.util.ForesterUtil; public class PhylogenyMethods { + private static boolean _order_changed; + private PhylogenyMethods() { // Hidden constructor. } @@ -814,13 +816,13 @@ public class PhylogenyMethods { 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(); + final PhylogenyNode temp = n.getChildNode1(); n.setChild1( n.getChildNode2() ); n.setChild2( temp ); + _order_changed = true; } else if ( order_ext_alphabetically ) { boolean all_ext = true; @@ -839,6 +841,27 @@ public class PhylogenyMethods { } } } + + public synchronized static void orderAppearanceX( final PhylogenyNode n, + final boolean order_ext_alphabetically, + final DESCENDANT_SORT_PRIORITY pri ) { + if ( n.isExternal() ) { + return; + } + else { + _order_changed = false; + orderAppearance( n, + true, + order_ext_alphabetically, + pri ); + if (!_order_changed ) { + orderAppearance( n, + false, + order_ext_alphabetically, + pri ); + } + } + } public static void postorderBranchColorAveragingExternalNodeBased( final Phylogeny p ) { for( final PhylogenyNodeIterator iter = p.iteratorPostorder(); iter.hasNext(); ) { diff --git a/forester/java/src/org/forester/phylogeny/data/Taxonomy.java b/forester/java/src/org/forester/phylogeny/data/Taxonomy.java index 4a333a2..8a2dc33 100644 --- a/forester/java/src/org/forester/phylogeny/data/Taxonomy.java +++ b/forester/java/src/org/forester/phylogeny/data/Taxonomy.java @@ -248,8 +248,8 @@ public class Taxonomy implements PhylogenyData, MultipleUris, Comparable 0 ) { + PhylogenyDataUtil.appendElement( writer, PhyloXmlMapping.TAXONOMY_LINEAGE, sb.toString(), indentation ); + } + } writer.write( ForesterUtil.LINE_SEPARATOR ); writer.write( indentation ); PhylogenyDataUtil.appendClose( writer, PhyloXmlMapping.TAXONOMY ); -- 1.7.10.2