in progress
[jalview.git] / forester / java / src / org / forester / archaeopteryx / MainFrameApplication.java
index 947ed2a..bccdd9d 100644 (file)
@@ -93,6 +93,8 @@ import org.forester.phylogeny.PhylogenyMethods;
 import org.forester.phylogeny.PhylogenyNode;\r
 import org.forester.phylogeny.PhylogenyNode.NH_CONVERSION_SUPPORT_VALUE_STYLE;\r
 import org.forester.phylogeny.data.Confidence;\r
+import org.forester.phylogeny.data.PhylogenyDataUtil;\r
+import org.forester.phylogeny.data.Sequence;\r
 import org.forester.phylogeny.data.Taxonomy;\r
 import org.forester.phylogeny.factories.ParserBasedPhylogenyFactory;\r
 import org.forester.phylogeny.factories.PhylogenyFactory;\r
@@ -123,6 +125,7 @@ public final class MainFrameApplication extends MainFrame {
     private final static SequencesFileFilter seqsfilter                            = new SequencesFileFilter();\r
     private final static DefaultFilter       defaultfilter                         = new DefaultFilter();\r
     private static final long                serialVersionUID                      = -799735726778865234L;\r
+    private static final boolean             PREPROCESS_TREES                      = false;\r
     private final JFileChooser               _values_filechooser;\r
     private final JFileChooser               _sequences_filechooser;\r
     private final JFileChooser               _open_filechooser;\r
@@ -140,11 +143,14 @@ public final class MainFrameApplication extends MainFrame {
     private JMenuItem                        _write_to_tif_item;\r
     private JMenuItem                        _write_to_png_item;\r
     private JMenuItem                        _write_to_bmp_item;\r
+    private JMenuItem                        _collapse_below_threshold;\r
+    private JMenuItem                        _collapse_below_branch_length;\r
     private File                             _current_dir;\r
     private ButtonGroup                      _radio_group_1;\r
     private ButtonGroup                      _radio_group_2;\r
     // Others:\r
     double                                   _min_not_collapse                     = Constants.MIN_NOT_COLLAPSE_DEFAULT;\r
+    double                                   _min_not_collapse_bl                  = 0.001;\r
     // Phylogeny Inference menu\r
     private JMenu                            _inference_menu;\r
     private JMenuItem                        _inference_from_msa_item;\r
@@ -383,8 +389,7 @@ public final class MainFrameApplication extends MainFrame {
                     _mainpanel.getCurrentTreePanel().calcParametersForPainting( _mainpanel.getCurrentTreePanel()\r
                                                                                         .getWidth(),\r
                                                                                 _mainpanel.getCurrentTreePanel()\r
-                                                                                        .getHeight(),\r
-                                                                                getOptions().isAllowFontSizeChange() );\r
+                                                                                        .getHeight() );\r
                 }\r
             }\r
         } );\r
@@ -543,6 +548,12 @@ public final class MainFrameApplication extends MainFrame {
                 }\r
                 collapseBelowThreshold();\r
             }\r
+            else if ( o == _collapse_below_branch_length ) {\r
+                if ( isSubtreeDisplayed() ) {\r
+                    return;\r
+                }\r
+                collapseBelowBranchLengthThreshold();\r
+            }\r
             else if ( ( o == _extract_taxonomy_pfam_strict_rbmi ) || ( o == _extract_taxonomy_pfam_relaxed_rbmi )\r
                     || ( o == _extract_taxonomy_agressive_rbmi ) ) {\r
                 if ( _replace_underscores_cbmi != null ) {\r
@@ -870,6 +881,8 @@ public final class MainFrameApplication extends MainFrame {
                 setTextForPdfLineWidthChooserMenuItem( _choose_pdf_width_mi, getOptions() );\r
                 MainFrame.setCycleNodeFillMenuItem( _cycle_node_fill_mi, getOptions() );\r
                 MainFrame.setCycleNodeShapeMenuItem( _cycle_node_shape_mi, getOptions() );\r
+                \r
+                MainFrame.setCycleDataReturnMenuItem( _cycle_data_return, getOptions() );\r
                 MainFrame.setTextNodeSizeMenuItem( _choose_node_size_mi, getOptions() );\r
                 try {\r
                     getMainPanel().getControlPanel().setVisibilityOfDomainStrucureCB();\r
@@ -889,18 +902,19 @@ public final class MainFrameApplication extends MainFrame {
         _radio_group_1.add( _ext_node_dependent_cladogram_rbmi );\r
         _radio_group_1.add( _uniform_cladograms_rbmi );\r
         _radio_group_1.add( _non_lined_up_cladograms_rbmi );\r
-        ///////\r
         _options_jmenu.add( _show_overview_cbmi = new JCheckBoxMenuItem( SHOW_OVERVIEW_LABEL ) );\r
         _options_jmenu.add( _show_scale_cbmi = new JCheckBoxMenuItem( DISPLAY_SCALE_LABEL ) );\r
         _options_jmenu\r
                 .add( _show_default_node_shapes_internal_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_INT ) );\r
         _options_jmenu\r
                 .add( _show_default_node_shapes_external_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_EXT ) );\r
+        _options_jmenu\r
+                .add( _show_default_node_shapes_for_marked_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_NODE_BOXES_LABEL_MARKED ) );\r
+        _options_jmenu.add( _line_up_renderable_data_cbmi = new JCheckBoxMenuItem( MainFrame.LINE_UP_RENDERABLE_DATA ) );\r
         if ( getConfiguration().doDisplayOption( Configuration.show_domain_architectures ) ) {\r
-            _options_jmenu.add( _show_domain_labels = new JCheckBoxMenuItem( SHOW_DOMAIN_LABELS_LABEL ) );\r
             _options_jmenu.add( _right_line_up_domains_cbmi = new JCheckBoxMenuItem( MainFrame.RIGHT_LINE_UP_DOMAINS ) );\r
+            _options_jmenu.add( _show_domain_labels = new JCheckBoxMenuItem( MainFrame.SHOW_DOMAIN_LABELS_LABEL ) );\r
         }\r
-        _options_jmenu.add( _line_up_renderable_data_cbmi = new JCheckBoxMenuItem( MainFrame.LINE_UP_RENDERABLE_DATA ) );\r
         _options_jmenu.add( _show_annotation_ref_source = new JCheckBoxMenuItem( SHOW_ANN_REF_SOURCE_LABEL ) );\r
         _options_jmenu.add( _show_confidence_stddev_cbmi = new JCheckBoxMenuItem( SHOW_CONF_STDDEV_LABEL ) );\r
         _options_jmenu.add( _color_by_taxonomic_group_cbmi = new JCheckBoxMenuItem( COLOR_BY_TAXONOMIC_GROUP ) );\r
@@ -918,11 +932,14 @@ public final class MainFrameApplication extends MainFrame {
         _options_jmenu.add( _overview_placment_mi = new JMenuItem( "" ) );\r
         _options_jmenu.add( _switch_colors_mi = new JMenuItem( "" ) );\r
         _options_jmenu.add( _choose_font_mi = new JMenuItem( "" ) );\r
-        ///////\r
+        _options_jmenu.addSeparator();\r
+        _options_jmenu.add( _cycle_data_return = new JMenuItem( "Cycle Data Return" ) );\r
         _options_jmenu.addSeparator();\r
         _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( SEARCH_SUBHEADER ), getConfiguration() ) );\r
         _options_jmenu.add( _search_case_senstive_cbmi = new JCheckBoxMenuItem( SEARCH_CASE_SENSITIVE_LABEL ) );\r
         _options_jmenu.add( _search_whole_words_only_cbmi = new JCheckBoxMenuItem( SEARCH_TERMS_ONLY_LABEL ) );\r
+        _options_jmenu.add( _search_with_regex_cbmi = new JCheckBoxMenuItem( MainFrame.SEARCH_REGEX_LABEL ) );\r
+        _search_with_regex_cbmi.setToolTipText( MainFrame.SEARCH_WITH_REGEX_TIP );\r
         _options_jmenu.add( _inverse_search_result_cbmi = new JCheckBoxMenuItem( INVERSE_SEARCH_RESULT_LABEL ) );\r
         _options_jmenu.addSeparator();\r
         _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Graphics Export & Printing:" ),\r
@@ -944,7 +961,6 @@ public final class MainFrameApplication extends MainFrame {
         _options_jmenu.add( _replace_underscores_cbmi = new JCheckBoxMenuItem( "Replace Underscores with Spaces" ) );\r
         _options_jmenu\r
                 .add( _allow_errors_in_distance_to_parent_cbmi = new JCheckBoxMenuItem( "Ignore Distance Values Format Errors" ) );\r
-        //\r
         _options_jmenu.add( _extract_taxonomy_no_rbmi = new JRadioButtonMenuItem( "No Taxonomy Extraction" ) );\r
         _options_jmenu\r
                 .add( _extract_taxonomy_pfam_strict_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style Node Names" ) );\r
@@ -963,7 +979,6 @@ public final class MainFrameApplication extends MainFrame {
         _radio_group_2.add( _extract_taxonomy_pfam_strict_rbmi );\r
         _radio_group_2.add( _extract_taxonomy_pfam_relaxed_rbmi );\r
         _radio_group_2.add( _extract_taxonomy_agressive_rbmi );\r
-        // \r
         _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Newick/Nexus Output:" ), getConfiguration() ) );\r
         _options_jmenu\r
                 .add( _use_brackets_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_BRACKETS_FOR_CONF_IN_NH_LABEL ) );\r
@@ -981,9 +996,13 @@ public final class MainFrameApplication extends MainFrame {
                 .isShowDefaultNodeShapesExternal() );\r
         customizeCheckBoxMenuItem( _show_default_node_shapes_internal_cbmi, getOptions()\r
                 .isShowDefaultNodeShapesInternal() );\r
+        customizeCheckBoxMenuItem( _show_default_node_shapes_for_marked_cbmi, getOptions()\r
+                .isShowDefaultNodeShapesForMarkedNodes() );\r
         customizeJMenuItem( _cycle_node_shape_mi );\r
         customizeJMenuItem( _cycle_node_fill_mi );\r
         customizeJMenuItem( _choose_node_size_mi );\r
+        customizeJMenuItem( _cycle_data_return);\r
+        \r
         customizeCheckBoxMenuItem( _color_labels_same_as_parent_branch, getOptions().isColorLabelsSameAsParentBranch() );\r
         customizeCheckBoxMenuItem( _color_by_taxonomic_group_cbmi, getOptions().isColorByTaxonomicGroup() );\r
         customizeCheckBoxMenuItem( _screen_antialias_cbmi, getOptions().isAntialiasScreen() );\r
@@ -1017,6 +1036,7 @@ public final class MainFrameApplication extends MainFrame {
         customizeCheckBoxMenuItem( _replace_underscores_cbmi, getOptions().isReplaceUnderscoresInNhParsing() );\r
         customizeCheckBoxMenuItem( _allow_errors_in_distance_to_parent_cbmi, getOptions()\r
                 .isReplaceUnderscoresInNhParsing() );\r
+        customizeCheckBoxMenuItem( _search_with_regex_cbmi, getOptions().isSearchWithRegex() );\r
         customizeCheckBoxMenuItem( _search_whole_words_only_cbmi, getOptions().isMatchWholeTermsOnly() );\r
         customizeCheckBoxMenuItem( _inverse_search_result_cbmi, getOptions().isInverseSearchResult() );\r
         customizeCheckBoxMenuItem( _graphics_export_visible_only_cbmi, getOptions().isGraphicsExportVisibleOnly() );\r
@@ -1087,11 +1107,19 @@ public final class MainFrameApplication extends MainFrame {
         _tools_menu.addSeparator();\r
         _tools_menu.add( _collapse_species_specific_subtrees = new JMenuItem( "Collapse Species-Specific Subtrees" ) );\r
         customizeJMenuItem( _collapse_species_specific_subtrees );\r
+        _collapse_species_specific_subtrees.setToolTipText( "To (reversibly) collapse species-specific subtrees" );\r
         _tools_menu\r
                 .add( _collapse_below_threshold = new JMenuItem( "Collapse Branches with Confidence Below Threshold into Multifurcations" ) );\r
         customizeJMenuItem( _collapse_below_threshold );\r
         _collapse_below_threshold\r
-                .setToolTipText( "To 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)" );\r
+                .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)" );\r
+        //\r
+        _tools_menu\r
+                .add( _collapse_below_branch_length = new JMenuItem( "Collapse Branches with Branch Lengths Below Threshold into Multifurcations" ) );\r
+        customizeJMenuItem( _collapse_below_branch_length );\r
+        _collapse_below_branch_length\r
+                .setToolTipText( "To (permanently) collapse branches with branches with branch lengths below a threshold into multifurcations" );\r
+        //\r
         _tools_menu.addSeparator();\r
         _tools_menu\r
                 .add( _extract_tax_code_from_node_names_jmi = new JMenuItem( "Extract Taxonomic Data from Node Names" ) );\r
@@ -1270,8 +1298,7 @@ public final class MainFrameApplication extends MainFrame {
 \r
     void writePhylogenyToGraphicsFile( final String file_name, final GraphicsExportType type ) {\r
         _mainpanel.getCurrentTreePanel().calcParametersForPainting( _mainpanel.getCurrentTreePanel().getWidth(),\r
-                                                                    _mainpanel.getCurrentTreePanel().getHeight(),\r
-                                                                    true );\r
+                                                                    _mainpanel.getCurrentTreePanel().getHeight() );\r
         String file_written_to = "";\r
         boolean error = false;\r
         try {\r
@@ -1670,7 +1697,65 @@ public final class MainFrameApplication extends MainFrame {
         }\r
     }\r
 \r
-    private void collapse( final Phylogeny phy, final double m ) {\r
+    private void collapseBl( final Phylogeny phy ) {\r
+        final PhylogenyNodeIterator it = phy.iteratorPostorder();\r
+        final List<PhylogenyNode> to_be_removed = new ArrayList<PhylogenyNode>();\r
+        double min_bl = Double.MAX_VALUE;\r
+        boolean bl_present = false;\r
+        while ( it.hasNext() ) {\r
+            final PhylogenyNode n = it.next();\r
+            if ( !n.isExternal() && !n.isRoot() ) {\r
+                final double bl = n.getDistanceToParent();\r
+                if ( bl != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) {\r
+                    bl_present = true;\r
+                    if ( bl < getMinNotCollapseBlValue() ) {\r
+                        to_be_removed.add( n );\r
+                    }\r
+                    if ( bl < min_bl ) {\r
+                        min_bl = bl;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        if ( bl_present ) {\r
+            for( final PhylogenyNode node : to_be_removed ) {\r
+                PhylogenyMethods.removeNode( node, phy );\r
+            }\r
+            if ( to_be_removed.size() > 0 ) {\r
+                phy.externalNodesHaveChanged();\r
+                phy.clearHashIdToNodeMap();\r
+                phy.recalculateNumberOfExternalDescendants( true );\r
+                getCurrentTreePanel().resetNodeIdToDistToLeafMap();\r
+                getCurrentTreePanel().updateSetOfCollapsedExternalNodes();\r
+                getCurrentTreePanel().calculateLongestExtNodeInfo();\r
+                getCurrentTreePanel().setNodeInPreorderToNull();\r
+                getCurrentTreePanel().recalculateMaxDistanceToRoot();\r
+                getCurrentTreePanel().resetPreferredSize();\r
+                getCurrentTreePanel().setEdited( true );\r
+                getCurrentTreePanel().repaint();\r
+                repaint();\r
+            }\r
+            if ( to_be_removed.size() > 0 ) {\r
+                JOptionPane.showMessageDialog( this, "Collapsed " + to_be_removed.size()\r
+                        + " branches with\nbranch length values below " + getMinNotCollapseBlValue(), "Collapsed "\r
+                        + to_be_removed.size() + " branches", JOptionPane.INFORMATION_MESSAGE );\r
+            }\r
+            else {\r
+                JOptionPane.showMessageDialog( this,\r
+                                               "No branch collapsed,\nminimum branch length is " + min_bl,\r
+                                               "No branch collapsed",\r
+                                               JOptionPane.INFORMATION_MESSAGE );\r
+            }\r
+        }\r
+        else {\r
+            JOptionPane.showMessageDialog( this,\r
+                                           "No branch collapsed because no branch length values present",\r
+                                           "No branch length values present",\r
+                                           JOptionPane.INFORMATION_MESSAGE );\r
+        }\r
+    }\r
+\r
+    private void collapse( final Phylogeny phy ) {\r
         final PhylogenyNodeIterator it = phy.iteratorPostorder();\r
         final List<PhylogenyNode> to_be_removed = new ArrayList<PhylogenyNode>();\r
         double min_support = Double.MAX_VALUE;\r
@@ -1760,7 +1845,43 @@ public final class MainFrameApplication extends MainFrame {
                     }\r
                     if ( success && ( m >= 0.0 ) ) {\r
                         setMinNotCollapseConfidenceValue( m );\r
-                        collapse( phy, m );\r
+                        collapse( phy );\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    private void collapseBelowBranchLengthThreshold() {\r
+        if ( getCurrentTreePanel() != null ) {\r
+            final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
+            if ( ( phy != null ) && !phy.isEmpty() ) {\r
+                final String s = ( String ) JOptionPane\r
+                        .showInputDialog( this,\r
+                                          "Please enter the minimum branch length value\n",\r
+                                          "Minimal Branch Length Value",\r
+                                          JOptionPane.QUESTION_MESSAGE,\r
+                                          null,\r
+                                          null,\r
+                                          getMinNotCollapseBlValue() );\r
+                if ( !ForesterUtil.isEmpty( s ) ) {\r
+                    boolean success = true;\r
+                    double m = 0.0;\r
+                    final String m_str = s.trim();\r
+                    if ( !ForesterUtil.isEmpty( m_str ) ) {\r
+                        try {\r
+                            m = Double.parseDouble( m_str );\r
+                        }\r
+                        catch ( final Exception ex ) {\r
+                            success = false;\r
+                        }\r
+                    }\r
+                    else {\r
+                        success = false;\r
+                    }\r
+                    if ( success && ( m >= 0.0 ) ) {\r
+                        setMinNotCollapseBlValue( m );\r
+                        collapseBl( phy );\r
                     }\r
                 }\r
             }\r
@@ -1916,6 +2037,10 @@ public final class MainFrameApplication extends MainFrame {
         return _min_not_collapse;\r
     }\r
 \r
+    private double getMinNotCollapseBlValue() {\r
+        return _min_not_collapse_bl;\r
+    }\r
+\r
     private PhylogeneticInferenceOptions getPhylogeneticInferenceOptions() {\r
         if ( _phylogenetic_inference_options == null ) {\r
             _phylogenetic_inference_options = new PhylogeneticInferenceOptions();\r
@@ -2024,8 +2149,7 @@ public final class MainFrameApplication extends MainFrame {
         }\r
         if ( !getOptions().isPrintUsingActualSize() ) {\r
             getCurrentTreePanel().calcParametersForPainting( getOptions().getPrintSizeX() - 80,\r
-                                                             getOptions().getPrintSizeY() - 140,\r
-                                                             true );\r
+                                                             getOptions().getPrintSizeY() - 140 );\r
             getCurrentTreePanel().resetPreferredSize();\r
             getCurrentTreePanel().repaint();\r
         }\r
@@ -2053,9 +2177,8 @@ public final class MainFrameApplication extends MainFrame {
 \r
     private void printPhylogenyToPdf( final String file_name ) {\r
         if ( !getOptions().isPrintUsingActualSize() ) {\r
-            getCurrentTreePanel().calcParametersForPainting( getOptions().getPrintSizeX(),\r
-                                                             getOptions().getPrintSizeY(),\r
-                                                             true );\r
+            getCurrentTreePanel()\r
+            .calcParametersForPainting( getOptions().getPrintSizeX(), getOptions().getPrintSizeY() );\r
             getCurrentTreePanel().resetPreferredSize();\r
             getCurrentTreePanel().repaint();\r
         }\r
@@ -2211,6 +2334,9 @@ public final class MainFrameApplication extends MainFrame {
                                 }\r
                             }\r
                         }\r
+                        if ( PREPROCESS_TREES ) {\r
+                            preProcessTreesUponReading( phys );\r
+                        }\r
                         AptxUtil.addPhylogeniesToTabs( phys,\r
                                                        file.getName(),\r
                                                        file.getAbsolutePath(),\r
@@ -2234,6 +2360,30 @@ public final class MainFrameApplication extends MainFrame {
         System.gc();\r
     }\r
 \r
+    private void preProcessTreesUponReading( final Phylogeny[] phys ) {\r
+        for( final Phylogeny phy : phys ) {\r
+            if ( ( phy != null ) && !phy.isEmpty() ) {\r
+                for( final PhylogenyNodeIterator it = phy.iteratorPreorder(); it.hasNext(); ) {\r
+                    final PhylogenyNode n = it.next();\r
+                    if ( n.isExternal() ) {\r
+                        if ( n.getNodeData().isHasSequence() ) {\r
+                            final Sequence s = n.getNodeData().getSequence();\r
+                            if ( ForesterUtil.isEmpty( s.getGeneName() ) || s.getGeneName().startsWith( "LOC" ) ) {\r
+                                if ( ( s.getAccession() != null )\r
+                                        && !ForesterUtil.isEmpty( s.getAccession().getValue() ) ) {\r
+                                    s.setGeneName( s.getAccession().getValue() );\r
+                                }\r
+                                else if ( !ForesterUtil.isEmpty( n.getName() ) ) {\r
+                                    s.setGeneName( n.getName() );\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
     private void readSpeciesTreeFromFile() {\r
         Phylogeny t = null;\r
         boolean exception = false;\r
@@ -2347,6 +2497,10 @@ public final class MainFrameApplication extends MainFrame {
         _min_not_collapse = min_not_collapse;\r
     }\r
 \r
+    private void setMinNotCollapseBlValue( final double min_not_collapse_bl ) {\r
+        _min_not_collapse_bl = min_not_collapse_bl;\r
+    }\r
+\r
     private void setPhylogeneticInferenceOptions( final PhylogeneticInferenceOptions phylogenetic_inference_options ) {\r
         _phylogenetic_inference_options = phylogenetic_inference_options;\r
     }\r