in progress, does NOT compile
[jalview.git] / forester / java / src / org / forester / archaeopteryx / MainFrameApplication.java
1 // $Id:\r
2 // FORESTER -- software libraries and applications\r
3 // for evolutionary biology research and applications.\r
4 //\r
5 // Copyright (C) 2008-2009 Christian M. Zmasek\r
6 // Copyright (C) 2008-2009 Burnham Institute for Medical Research\r
7 // Copyright (C) 2003-2007 Ethalinda K.S. Cannon\r
8 // All rights reserved\r
9 //\r
10 // This library is free software; you can redistribute it and/or\r
11 // modify it under the terms of the GNU Lesser General Public\r
12 // License as published by the Free Software Foundation; either\r
13 // version 2.1 of the License, or (at your option) any later version.\r
14 //\r
15 // This library is distributed in the hope that it will be useful,\r
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
18 // Lesser General Public License for more details.\r
19 //\r
20 // You should have received a copy of the GNU Lesser General Public\r
21 // License along with this library; if not, write to the Free Software\r
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\r
23 //\r
24 // Contact: phylosoft @ gmail . com\r
25 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester\r
26 \r
27 package org.forester.archaeopteryx;\r
28 \r
29 import java.awt.BorderLayout;\r
30 import java.awt.Font;\r
31 import java.awt.event.ActionEvent;\r
32 import java.awt.event.ComponentAdapter;\r
33 import java.awt.event.ComponentEvent;\r
34 import java.awt.event.WindowAdapter;\r
35 import java.awt.event.WindowEvent;\r
36 import java.io.File;\r
37 import java.io.FileInputStream;\r
38 import java.io.IOException;\r
39 import java.io.InputStream;\r
40 import java.net.MalformedURLException;\r
41 import java.net.URL;\r
42 import java.util.ArrayList;\r
43 import java.util.HashSet;\r
44 import java.util.List;\r
45 import java.util.Set;\r
46 \r
47 import javax.swing.ButtonGroup;\r
48 import javax.swing.JCheckBoxMenuItem;\r
49 import javax.swing.JFileChooser;\r
50 import javax.swing.JMenu;\r
51 import javax.swing.JMenuBar;\r
52 import javax.swing.JMenuItem;\r
53 import javax.swing.JOptionPane;\r
54 import javax.swing.JRadioButtonMenuItem;\r
55 import javax.swing.UIManager;\r
56 import javax.swing.UnsupportedLookAndFeelException;\r
57 import javax.swing.WindowConstants;\r
58 import javax.swing.event.ChangeEvent;\r
59 import javax.swing.event.ChangeListener;\r
60 import javax.swing.plaf.synth.SynthLookAndFeel;\r
61 \r
62 import org.forester.analysis.TaxonomyDataManager;\r
63 import org.forester.archaeopteryx.AptxUtil.GraphicsExportType;\r
64 import org.forester.archaeopteryx.Options.CLADOGRAM_TYPE;\r
65 import org.forester.archaeopteryx.Options.NODE_LABEL_DIRECTION;\r
66 import org.forester.archaeopteryx.Options.PHYLOGENY_GRAPHICS_TYPE;\r
67 import org.forester.archaeopteryx.tools.AncestralTaxonomyInferrer;\r
68 import org.forester.archaeopteryx.tools.InferenceManager;\r
69 import org.forester.archaeopteryx.tools.PhyloInferenceDialog;\r
70 import org.forester.archaeopteryx.tools.PhylogeneticInferenceOptions;\r
71 import org.forester.archaeopteryx.tools.PhylogeneticInferrer;\r
72 import org.forester.archaeopteryx.tools.SequenceDataRetriver;\r
73 import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient;\r
74 import org.forester.archaeopteryx.webservices.WebservicesManager;\r
75 import org.forester.io.parsers.FastaParser;\r
76 import org.forester.io.parsers.GeneralMsaParser;\r
77 import org.forester.io.parsers.PhylogenyParser;\r
78 import org.forester.io.parsers.nexus.NexusPhylogeniesParser;\r
79 import org.forester.io.parsers.nhx.NHXParser;\r
80 import org.forester.io.parsers.nhx.NHXParser.TAXONOMY_EXTRACTION;\r
81 import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException;\r
82 import org.forester.io.parsers.phyloxml.PhyloXmlParser;\r
83 import org.forester.io.parsers.phyloxml.PhyloXmlUtil;\r
84 import org.forester.io.parsers.tol.TolParser;\r
85 import org.forester.io.parsers.util.ParserUtils;\r
86 import org.forester.io.writers.PhylogenyWriter;\r
87 import org.forester.io.writers.SequenceWriter;\r
88 import org.forester.msa.Msa;\r
89 import org.forester.msa.MsaFormatException;\r
90 import org.forester.phylogeny.Phylogeny;\r
91 import org.forester.phylogeny.PhylogenyMethods;\r
92 import org.forester.phylogeny.PhylogenyNode;\r
93 import org.forester.phylogeny.PhylogenyNode.NH_CONVERSION_SUPPORT_VALUE_STYLE;\r
94 import org.forester.phylogeny.data.Confidence;\r
95 import org.forester.phylogeny.data.PhylogenyDataUtil;\r
96 import org.forester.phylogeny.data.Sequence;\r
97 import org.forester.phylogeny.data.Taxonomy;\r
98 import org.forester.phylogeny.factories.ParserBasedPhylogenyFactory;\r
99 import org.forester.phylogeny.factories.PhylogenyFactory;\r
100 import org.forester.phylogeny.iterators.PhylogenyNodeIterator;\r
101 import org.forester.sequence.MolecularSequence;\r
102 import org.forester.util.BasicDescriptiveStatistics;\r
103 import org.forester.util.BasicTable;\r
104 import org.forester.util.BasicTableParser;\r
105 import org.forester.util.DescriptiveStatistics;\r
106 import org.forester.util.ForesterUtil;\r
107 \r
108 public final class MainFrameApplication extends MainFrame {\r
109 \r
110     public static MainFrameApplication createInstance( final Phylogeny[] phys, final Configuration config ) {\r
111         return new MainFrameApplication( phys, config );\r
112     }\r
113 \r
114     static MainFrame createInstance( final Phylogeny[] phys, final Configuration config, final String title ) {\r
115         return new MainFrameApplication( phys, config, title );\r
116     }\r
117 \r
118     public static MainFrame createInstance( final Phylogeny[] phys,\r
119                                             final Configuration config,\r
120                                             final String title,\r
121                                             final File current_dir ) {\r
122         return new MainFrameApplication( phys, config, title, current_dir );\r
123     }\r
124 \r
125     static MainFrame createInstance( final Phylogeny[] phys, final String config_file_name, final String title ) {\r
126         return new MainFrameApplication( phys, config_file_name, title );\r
127     }\r
128 \r
129     static void warnIfNotPhyloXmlValidation( final Configuration c ) {\r
130         if ( !c.isValidatePhyloXmlAgainstSchema() ) {\r
131             JOptionPane\r
132                     .showMessageDialog( null,\r
133                                         ForesterUtil\r
134                                                 .wordWrap( "phyloXML XSD-based validation is turned off [enable with line 'validate_against_phyloxml_xsd_schem: true' in configuration file]",\r
135                                                            80 ),\r
136                                         "Warning",\r
137                                         JOptionPane.WARNING_MESSAGE );\r
138         }\r
139     }\r
140     static final String                  INFER_ANCESTOR_TAXONOMIES             = "Infer Ancestor Taxonomies";\r
141     static final String                  OBTAIN_DETAILED_TAXONOMIC_INFORMATION = "Obtain Detailed Taxonomic Information";\r
142     private final static int             FRAME_X_SIZE                          = 800;\r
143     private final static int             FRAME_Y_SIZE                          = 800;\r
144     // Filters for the file-open dialog (classes defined in this file)\r
145     private static final long            serialVersionUID                      = -799735726778865234L;\r
146     private static final boolean         PREPROCESS_TREES                      = false;\r
147     private final JFileChooser           _values_filechooser;\r
148     private final JFileChooser           _sequences_filechooser;\r
149     private final JFileChooser           _open_filechooser;\r
150     private final JFileChooser           _msa_filechooser;\r
151     private final JFileChooser           _seqs_pi_filechooser;\r
152     private final JFileChooser           _open_filechooser_for_species_tree;\r
153     // Application-only print menu items\r
154     private JMenuItem                    _collapse_below_threshold;\r
155     private JMenuItem                    _collapse_below_branch_length;\r
156     private ButtonGroup                  _radio_group_1;\r
157     private ButtonGroup                  _radio_group_2;\r
158     // Others:\r
159     double                               _min_not_collapse                     = Constants.MIN_NOT_COLLAPSE_DEFAULT;\r
160     double                               _min_not_collapse_bl                  = 0.001;\r
161     // Phylogeny Inference menu\r
162     private JMenu                        _inference_menu;\r
163     private JMenuItem                    _inference_from_msa_item;\r
164     private JMenuItem                    _inference_from_seqs_item;\r
165     // Phylogeny Inference\r
166     private PhylogeneticInferenceOptions _phylogenetic_inference_options       = null;\r
167     private Msa                          _msa                                  = null;\r
168     private File                         _msa_file                             = null;\r
169     private List<MolecularSequence>      _seqs                                 = null;\r
170     private File                         _seqs_file                            = null;\r
171     JMenuItem                            _read_values_jmi;\r
172     JMenuItem                            _read_seqs_jmi;\r
173 \r
174     private MainFrameApplication( final Phylogeny[] phys, final Configuration config ) {\r
175         _configuration = config;\r
176         if ( _configuration == null ) {\r
177             throw new IllegalArgumentException( "configuration is null" );\r
178         }\r
179         setVisible( false );\r
180         setOptions( Options.createInstance( _configuration ) );\r
181         _mainpanel = new MainPanel( _configuration, this );\r
182         _open_filechooser = null;\r
183         _open_filechooser_for_species_tree = null;\r
184         _save_filechooser = null;\r
185         _writetopdf_filechooser = null;\r
186         _writetographics_filechooser = null;\r
187         _msa_filechooser = null;\r
188         _seqs_pi_filechooser = null;\r
189         _values_filechooser = null;\r
190         _sequences_filechooser = null;\r
191         _jmenubar = new JMenuBar();\r
192         buildFileMenu();\r
193         buildTypeMenu();\r
194         _contentpane = getContentPane();\r
195         _contentpane.setLayout( new BorderLayout() );\r
196         _contentpane.add( _mainpanel, BorderLayout.CENTER );\r
197         // App is this big\r
198         setSize( MainFrameApplication.FRAME_X_SIZE, MainFrameApplication.FRAME_Y_SIZE );\r
199         // The window listener\r
200         setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );\r
201         addWindowListener( new WindowAdapter() {\r
202 \r
203             @Override\r
204             public void windowClosing( final WindowEvent e ) {\r
205                 exit();\r
206             }\r
207         } );\r
208         //   setVisible( true );\r
209         if ( ( phys != null ) && ( phys.length > 0 ) ) {\r
210             AptxUtil.addPhylogeniesToTabs( phys, "", null, _configuration, _mainpanel );\r
211             validate();\r
212             getMainPanel().getControlPanel().showWholeAll();\r
213             getMainPanel().getControlPanel().showWhole();\r
214         }\r
215         //activateSaveAllIfNeeded();\r
216         // ...and its children\r
217         _contentpane.repaint();\r
218     }\r
219 \r
220     private MainFrameApplication( final Phylogeny[] phys, final Configuration config, final String title ) {\r
221         this( phys, config, title, null );\r
222     }\r
223 \r
224     private MainFrameApplication( final Phylogeny[] phys,\r
225                                   final Configuration config,\r
226                                   final String title,\r
227                                   final File current_dir ) {\r
228         super();\r
229         _configuration = config;\r
230         if ( _configuration == null ) {\r
231             throw new IllegalArgumentException( "configuration is null" );\r
232         }\r
233         try {\r
234             boolean synth_exception = false;\r
235             if ( Constants.__SYNTH_LF ) {\r
236                 try {\r
237                     final SynthLookAndFeel synth = new SynthLookAndFeel();\r
238                     synth.load( MainFrameApplication.class.getResourceAsStream( "/resources/synth_look_and_feel_1.xml" ),\r
239                                 MainFrameApplication.class );\r
240                     UIManager.setLookAndFeel( synth );\r
241                 }\r
242                 catch ( final Exception ex ) {\r
243                     synth_exception = true;\r
244                     ForesterUtil.printWarningMessage( Constants.PRG_NAME,\r
245                                                       "could not create synth look and feel: "\r
246                                                               + ex.getLocalizedMessage() );\r
247                 }\r
248             }\r
249             if ( !Constants.__SYNTH_LF || synth_exception ) {\r
250                 if ( _configuration.isUseNativeUI() ) {\r
251                     UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );\r
252                 }\r
253                 else {\r
254                     UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName() );\r
255                 }\r
256             }\r
257             //UIManager.setLookAndFeel( "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel" );\r
258         }\r
259         catch ( final UnsupportedLookAndFeelException e ) {\r
260             AptxUtil.dieWithSystemError( "unsupported look and feel: " + e.toString() );\r
261         }\r
262         catch ( final ClassNotFoundException e ) {\r
263             AptxUtil.dieWithSystemError( "class not found exception: " + e.toString() );\r
264         }\r
265         catch ( final InstantiationException e ) {\r
266             AptxUtil.dieWithSystemError( "instantiation exception: " + e.toString() );\r
267         }\r
268         catch ( final IllegalAccessException e ) {\r
269             AptxUtil.dieWithSystemError( "illegal access exception: " + e.toString() );\r
270         }\r
271         if ( ( current_dir != null ) && current_dir.canRead() && current_dir.isDirectory() ) {\r
272             setCurrentDir( current_dir );\r
273         }\r
274         // hide until everything is ready\r
275         setVisible( false );\r
276         setOptions( Options.createInstance( _configuration ) );\r
277         setInferenceManager( InferenceManager.createInstance( _configuration ) );\r
278         setPhylogeneticInferenceOptions( PhylogeneticInferenceOptions.createInstance( _configuration ) );\r
279         //     _textframe = null; #~~~~\r
280         // set title\r
281         setTitle( Constants.PRG_NAME + " " + Constants.VERSION + " (" + Constants.PRG_DATE + ")" );\r
282         _mainpanel = new MainPanel( _configuration, this );\r
283         // The file dialogs\r
284         _open_filechooser = new JFileChooser();\r
285         _open_filechooser.setCurrentDirectory( new File( "." ) );\r
286         _open_filechooser.setMultiSelectionEnabled( false );\r
287         _open_filechooser.addChoosableFileFilter( MainFrame.xmlfilter );\r
288         _open_filechooser.addChoosableFileFilter( MainFrame.nhxfilter );\r
289         _open_filechooser.addChoosableFileFilter( MainFrame.nhfilter );\r
290         _open_filechooser.addChoosableFileFilter( MainFrame.nexusfilter );\r
291         _open_filechooser.addChoosableFileFilter( MainFrame.tolfilter );\r
292         _open_filechooser.addChoosableFileFilter( _open_filechooser.getAcceptAllFileFilter() );\r
293         _open_filechooser.setFileFilter( MainFrame.defaultfilter );\r
294         _open_filechooser_for_species_tree = new JFileChooser();\r
295         _open_filechooser_for_species_tree.setCurrentDirectory( new File( "." ) );\r
296         _open_filechooser_for_species_tree.setMultiSelectionEnabled( false );\r
297         _open_filechooser_for_species_tree.addChoosableFileFilter( MainFrame.xmlfilter );\r
298         _open_filechooser_for_species_tree.addChoosableFileFilter( MainFrame.tolfilter );\r
299         _open_filechooser_for_species_tree.setFileFilter( MainFrame.xmlfilter );\r
300         _save_filechooser = new JFileChooser();\r
301         _save_filechooser.setCurrentDirectory( new File( "." ) );\r
302         _save_filechooser.setMultiSelectionEnabled( false );\r
303         _save_filechooser.setFileFilter( MainFrame.xmlfilter );\r
304         _save_filechooser.addChoosableFileFilter( MainFrame.nhfilter );\r
305         _save_filechooser.addChoosableFileFilter( MainFrame.nexusfilter );\r
306         _save_filechooser.addChoosableFileFilter( _save_filechooser.getAcceptAllFileFilter() );\r
307         _writetopdf_filechooser = new JFileChooser();\r
308         _writetopdf_filechooser.addChoosableFileFilter( MainFrame.pdffilter );\r
309         _writetographics_filechooser = new JFileChooser();\r
310         _writetographics_filechooser.addChoosableFileFilter( MainFrame.graphicsfilefilter );\r
311         // Msa:\r
312         _msa_filechooser = new JFileChooser();\r
313         _msa_filechooser.setName( "Read Multiple Sequence Alignment File" );\r
314         _msa_filechooser.setCurrentDirectory( new File( "." ) );\r
315         _msa_filechooser.setMultiSelectionEnabled( false );\r
316         _msa_filechooser.addChoosableFileFilter( _msa_filechooser.getAcceptAllFileFilter() );\r
317         _msa_filechooser.addChoosableFileFilter( MainFrame.msafilter );\r
318         // Seqs:\r
319         _seqs_pi_filechooser = new JFileChooser();\r
320         _seqs_pi_filechooser.setName( "Read Sequences File" );\r
321         _seqs_pi_filechooser.setCurrentDirectory( new File( "." ) );\r
322         _seqs_pi_filechooser.setMultiSelectionEnabled( false );\r
323         _seqs_pi_filechooser.addChoosableFileFilter( _seqs_pi_filechooser.getAcceptAllFileFilter() );\r
324         _seqs_pi_filechooser.addChoosableFileFilter( MainFrame.seqsfilter );\r
325         // Expression\r
326         _values_filechooser = new JFileChooser();\r
327         _values_filechooser.setCurrentDirectory( new File( "." ) );\r
328         _values_filechooser.setMultiSelectionEnabled( false );\r
329         // Sequences\r
330         _sequences_filechooser = new JFileChooser();\r
331         _sequences_filechooser.setCurrentDirectory( new File( "." ) );\r
332         _sequences_filechooser.setMultiSelectionEnabled( false );\r
333         // build the menu bar\r
334         _jmenubar = new JMenuBar();\r
335         if ( !_configuration.isUseNativeUI() ) {\r
336             _jmenubar.setBackground( getConfiguration().getGuiMenuBackgroundColor() );\r
337         }\r
338         buildFileMenu();\r
339         if ( Constants.__ALLOW_PHYLOGENETIC_INFERENCE ) {\r
340             buildPhylogeneticInferenceMenu();\r
341         }\r
342         buildAnalysisMenu();\r
343         buildToolsMenu();\r
344         buildViewMenu();\r
345         buildFontSizeMenu();\r
346         buildOptionsMenu();\r
347         buildTypeMenu();\r
348         buildHelpMenu();\r
349         setJMenuBar( _jmenubar );\r
350         _jmenubar.add( _help_jmenu );\r
351         _contentpane = getContentPane();\r
352         _contentpane.setLayout( new BorderLayout() );\r
353         _contentpane.add( _mainpanel, BorderLayout.CENTER );\r
354         // App is this big\r
355         setSize( MainFrameApplication.FRAME_X_SIZE, MainFrameApplication.FRAME_Y_SIZE );\r
356         //        addWindowFocusListener( new WindowAdapter() {\r
357         //\r
358         //            @Override\r
359         //            public void windowGainedFocus( WindowEvent e ) {\r
360         //                requestFocusInWindow();\r
361         //            }\r
362         //        } );\r
363         // The window listener\r
364         setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );\r
365         addWindowListener( new WindowAdapter() {\r
366 \r
367             @Override\r
368             public void windowClosing( final WindowEvent e ) {\r
369                 if ( isUnsavedDataPresent() ) {\r
370                     final int r = JOptionPane.showConfirmDialog( null,\r
371                                                                  "Exit despite potentially unsaved changes?",\r
372                                                                  "Exit?",\r
373                                                                  JOptionPane.YES_NO_OPTION );\r
374                     if ( r != JOptionPane.YES_OPTION ) {\r
375                         return;\r
376                     }\r
377                 }\r
378                 else {\r
379                     final int r = JOptionPane.showConfirmDialog( null,\r
380                                                                  "Exit Archaeopteryx?",\r
381                                                                  "Exit?",\r
382                                                                  JOptionPane.YES_NO_OPTION );\r
383                     if ( r != JOptionPane.YES_OPTION ) {\r
384                         return;\r
385                     }\r
386                 }\r
387                 exit();\r
388             }\r
389         } );\r
390         // The component listener\r
391         addComponentListener( new ComponentAdapter() {\r
392 \r
393             @Override\r
394             public void componentResized( final ComponentEvent e ) {\r
395                 if ( _mainpanel.getCurrentTreePanel() != null ) {\r
396                     _mainpanel.getCurrentTreePanel().calcParametersForPainting( _mainpanel.getCurrentTreePanel()\r
397                                                                                         .getWidth(),\r
398                                                                                 _mainpanel.getCurrentTreePanel()\r
399                                                                                         .getHeight() );\r
400                 }\r
401             }\r
402         } );\r
403         requestFocusInWindow();\r
404         // addKeyListener( this );\r
405         setVisible( true );\r
406         if ( ( phys != null ) && ( phys.length > 0 ) ) {\r
407             AptxUtil.addPhylogeniesToTabs( phys, title, null, _configuration, _mainpanel );\r
408             validate();\r
409             getMainPanel().getControlPanel().showWholeAll();\r
410             getMainPanel().getControlPanel().showWhole();\r
411         }\r
412         activateSaveAllIfNeeded();\r
413         // ...and its children\r
414         _contentpane.repaint();\r
415         System.gc();\r
416     }\r
417 \r
418     private MainFrameApplication( final Phylogeny[] phys, final String config_file, final String title ) {\r
419         // Reads the config file (false, false => not url, not applet):\r
420         this( phys, new Configuration( config_file, false, false, true ), title );\r
421     }\r
422 \r
423     @Override\r
424     public void actionPerformed( final ActionEvent e ) {\r
425         try {\r
426             super.actionPerformed( e );\r
427             final Object o = e.getSource();\r
428             // Handle app-specific actions here:\r
429             if ( o == _open_item ) {\r
430                 readPhylogeniesFromFile();\r
431             }\r
432             if ( o == _open_url_item ) {\r
433                 readPhylogeniesFromURL();\r
434             }\r
435             else if ( o == _new_item ) {\r
436                 newTree();\r
437             }\r
438            \r
439             else if ( o == _close_item ) {\r
440                 closeCurrentPane();\r
441             }\r
442           \r
443             else if ( o == _load_species_tree_item ) {\r
444                 readSpeciesTreeFromFile();\r
445             }\r
446             else if ( o == _lineage_inference ) {\r
447                 if ( isSubtreeDisplayed() ) {\r
448                     JOptionPane.showMessageDialog( this,\r
449                                                    "Subtree is shown.",\r
450                                                    "Cannot infer ancestral taxonomies",\r
451                                                    JOptionPane.ERROR_MESSAGE );\r
452                     return;\r
453                 }\r
454                 executeLineageInference();\r
455             }\r
456             else if ( o == _obtain_detailed_taxonomic_information_jmi ) {\r
457                 if ( isSubtreeDisplayed() ) {\r
458                     return;\r
459                 }\r
460                 obtainDetailedTaxonomicInformation();\r
461             }\r
462             else if ( o == _obtain_detailed_taxonomic_information_deleting_jmi ) {\r
463                 if ( isSubtreeDisplayed() ) {\r
464                     return;\r
465                 }\r
466                 obtainDetailedTaxonomicInformationDelete();\r
467             }\r
468             else if ( o == _obtain_seq_information_jmi ) {\r
469                 obtainSequenceInformation();\r
470             }\r
471             else if ( o == _read_values_jmi ) {\r
472                 if ( isSubtreeDisplayed() ) {\r
473                     return;\r
474                 }\r
475                 addExpressionValuesFromFile();\r
476             }\r
477             else if ( o == _read_seqs_jmi ) {\r
478                 if ( isSubtreeDisplayed() ) {\r
479                     return;\r
480                 }\r
481                 addSequencesFromFile();\r
482             }\r
483             else if ( o == _move_node_names_to_tax_sn_jmi ) {\r
484                 moveNodeNamesToTaxSn();\r
485             }\r
486             else if ( o == _move_node_names_to_seq_names_jmi ) {\r
487                 moveNodeNamesToSeqNames();\r
488             }\r
489             else if ( o == _extract_tax_code_from_node_names_jmi ) {\r
490                 extractTaxDataFromNodeNames();\r
491             }\r
492             else if ( o == _internal_number_are_confidence_for_nh_parsing_cbmi ) {\r
493                 updateOptions( getOptions() );\r
494             }\r
495             else if ( o == _replace_underscores_cbmi ) {\r
496                 if ( ( _extract_taxonomy_no_rbmi != null ) && !_extract_taxonomy_no_rbmi.isSelected() ) {\r
497                     _extract_taxonomy_no_rbmi.setSelected( true );\r
498                 }\r
499                 updateOptions( getOptions() );\r
500             }\r
501             else if ( o == _allow_errors_in_distance_to_parent_cbmi ) {\r
502                 updateOptions( getOptions() );\r
503             }\r
504             else if ( o == _collapse_below_threshold ) {\r
505                 if ( isSubtreeDisplayed() ) {\r
506                     return;\r
507                 }\r
508                 collapseBelowThreshold();\r
509             }\r
510             else if ( o == _collapse_below_branch_length ) {\r
511                 if ( isSubtreeDisplayed() ) {\r
512                     return;\r
513                 }\r
514                 collapseBelowBranchLengthThreshold();\r
515             }\r
516             else if ( ( o == _extract_taxonomy_pfam_strict_rbmi ) || ( o == _extract_taxonomy_pfam_relaxed_rbmi )\r
517                     || ( o == _extract_taxonomy_agressive_rbmi ) ) {\r
518                 if ( _replace_underscores_cbmi != null ) {\r
519                     _replace_underscores_cbmi.setSelected( false );\r
520                 }\r
521                 updateOptions( getOptions() );\r
522             }\r
523             else if ( o == _extract_taxonomy_no_rbmi ) {\r
524                 updateOptions( getOptions() );\r
525             }\r
526             else if ( o == _inference_from_msa_item ) {\r
527                 executePhyleneticInference( false );\r
528             }\r
529             else if ( o == _inference_from_seqs_item ) {\r
530                 executePhyleneticInference( true );\r
531             }\r
532             _contentpane.repaint();\r
533         }\r
534         catch ( final Exception ex ) {\r
535             AptxUtil.unexpectedException( ex );\r
536         }\r
537         catch ( final Error err ) {\r
538             AptxUtil.unexpectedError( err );\r
539         }\r
540     }\r
541 \r
542     private void addExpressionValuesFromFile() {\r
543         if ( ( getCurrentTreePanel() == null ) || ( getCurrentTreePanel().getPhylogeny() == null ) ) {\r
544             JOptionPane.showMessageDialog( this,\r
545                                            "Need to load evolutionary tree first",\r
546                                            "Can Not Read Expression Values",\r
547                                            JOptionPane.WARNING_MESSAGE );\r
548             return;\r
549         }\r
550         final File my_dir = getCurrentDir();\r
551         if ( my_dir != null ) {\r
552             _values_filechooser.setCurrentDirectory( my_dir );\r
553         }\r
554         final int result = _values_filechooser.showOpenDialog( _contentpane );\r
555         final File file = _values_filechooser.getSelectedFile();\r
556         if ( ( file != null ) && ( file.length() > 0 ) && ( result == JFileChooser.APPROVE_OPTION ) ) {\r
557             BasicTable<String> t = null;\r
558             try {\r
559                 t = BasicTableParser.parse( file, '\t' );\r
560                 if ( t.getNumberOfColumns() < 2 ) {\r
561                     t = BasicTableParser.parse( file, ',' );\r
562                 }\r
563                 if ( t.getNumberOfColumns() < 2 ) {\r
564                     t = BasicTableParser.parse( file, ' ' );\r
565                 }\r
566             }\r
567             catch ( final IOException e ) {\r
568                 JOptionPane.showMessageDialog( this,\r
569                                                e.getMessage(),\r
570                                                "Could Not Read Expression Value Table",\r
571                                                JOptionPane.ERROR_MESSAGE );\r
572                 return;\r
573             }\r
574             if ( t.getNumberOfColumns() < 2 ) {\r
575                 JOptionPane.showMessageDialog( this,\r
576                                                "Table contains " + t.getNumberOfColumns() + " column(s)",\r
577                                                "Problem with Expression Value Table",\r
578                                                JOptionPane.ERROR_MESSAGE );\r
579                 return;\r
580             }\r
581             if ( t.getNumberOfRows() < 1 ) {\r
582                 JOptionPane.showMessageDialog( this,\r
583                                                "Table contains zero rows",\r
584                                                "Problem with Expression Value Table",\r
585                                                JOptionPane.ERROR_MESSAGE );\r
586                 return;\r
587             }\r
588             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
589             if ( t.getNumberOfRows() != phy.getNumberOfExternalNodes() ) {\r
590                 JOptionPane.showMessageDialog( this,\r
591                                                "Table contains " + t.getNumberOfRows() + " rows, but tree contains "\r
592                                                        + phy.getNumberOfExternalNodes() + " external nodes",\r
593                                                "Warning",\r
594                                                JOptionPane.WARNING_MESSAGE );\r
595             }\r
596             final DescriptiveStatistics stats = new BasicDescriptiveStatistics();\r
597             int not_found = 0;\r
598             for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) {\r
599                 final PhylogenyNode node = iter.next();\r
600                 final String node_name = node.getName();\r
601                 if ( !ForesterUtil.isEmpty( node_name ) ) {\r
602                     int row = -1;\r
603                     try {\r
604                         row = t.findRow( node_name );\r
605                     }\r
606                     catch ( final IllegalArgumentException e ) {\r
607                         JOptionPane\r
608                                 .showMessageDialog( this,\r
609                                                     e.getMessage(),\r
610                                                     "Error Mapping Node Identifiers to Expression Value Identifiers",\r
611                                                     JOptionPane.ERROR_MESSAGE );\r
612                         return;\r
613                     }\r
614                     if ( row < 0 ) {\r
615                         if ( node.isExternal() ) {\r
616                             not_found++;\r
617                         }\r
618                         continue;\r
619                     }\r
620                     final List<Double> l = new ArrayList<Double>();\r
621                     for( int col = 1; col < t.getNumberOfColumns(); ++col ) {\r
622                         double d = -100;\r
623                         try {\r
624                             d = Double.parseDouble( t.getValueAsString( col, row ) );\r
625                         }\r
626                         catch ( final NumberFormatException e ) {\r
627                             JOptionPane.showMessageDialog( this,\r
628                                                            "Could not parse \"" + t.getValueAsString( col, row )\r
629                                                                    + "\" into a decimal value",\r
630                                                            "Issue with Expression Value Table",\r
631                                                            JOptionPane.ERROR_MESSAGE );\r
632                             return;\r
633                         }\r
634                         stats.addValue( d );\r
635                         l.add( d );\r
636                     }\r
637                     if ( !l.isEmpty() ) {\r
638                         if ( node.getNodeData().getProperties() != null ) {\r
639                             node.getNodeData().getProperties()\r
640                                     .removePropertiesWithGivenReferencePrefix( PhyloXmlUtil.VECTOR_PROPERTY_REF );\r
641                         }\r
642                         node.getNodeData().setVector( l );\r
643                     }\r
644                 }\r
645             }\r
646             if ( not_found > 0 ) {\r
647                 JOptionPane.showMessageDialog( this, "Could not fine expression values for " + not_found\r
648                         + " external node(s)", "Warning", JOptionPane.WARNING_MESSAGE );\r
649             }\r
650             getCurrentTreePanel().setStatisticsForExpressionValues( stats );\r
651         }\r
652     }\r
653 \r
654     private void addSequencesFromFile() {\r
655         if ( ( getCurrentTreePanel() == null ) || ( getCurrentTreePanel().getPhylogeny() == null ) ) {\r
656             JOptionPane.showMessageDialog( this,\r
657                                            "Need to load evolutionary tree first",\r
658                                            "Can Not Read Sequences",\r
659                                            JOptionPane.WARNING_MESSAGE );\r
660             return;\r
661         }\r
662         final File my_dir = getCurrentDir();\r
663         if ( my_dir != null ) {\r
664             _sequences_filechooser.setCurrentDirectory( my_dir );\r
665         }\r
666         final int result = _sequences_filechooser.showOpenDialog( _contentpane );\r
667         final File file = _sequences_filechooser.getSelectedFile();\r
668         List<MolecularSequence> seqs = null;\r
669         if ( ( file != null ) && !file.isDirectory() && ( result == JFileChooser.APPROVE_OPTION ) ) {\r
670             try {\r
671                 if ( FastaParser.isLikelyFasta( new FileInputStream( file ) ) ) {\r
672                     seqs = FastaParser.parse( new FileInputStream( file ) );\r
673                 }\r
674                 else {\r
675                     JOptionPane.showMessageDialog( this,\r
676                                                    "Format does not appear to be Fasta",\r
677                                                    "Multiple sequence file format error",\r
678                                                    JOptionPane.ERROR_MESSAGE );\r
679                     return;\r
680                 }\r
681             }\r
682             catch ( final MsaFormatException e ) {\r
683                 setArrowCursor();\r
684                 JOptionPane.showMessageDialog( this,\r
685                                                e.getLocalizedMessage(),\r
686                                                "Multiple sequence file format error",\r
687                                                JOptionPane.ERROR_MESSAGE );\r
688                 return;\r
689             }\r
690             catch ( final IOException e ) {\r
691                 setArrowCursor();\r
692                 JOptionPane.showMessageDialog( this,\r
693                                                e.getLocalizedMessage(),\r
694                                                "Failed to read multiple sequence file",\r
695                                                JOptionPane.ERROR_MESSAGE );\r
696                 return;\r
697             }\r
698             catch ( final Exception e ) {\r
699                 setArrowCursor();\r
700                 e.printStackTrace();\r
701                 JOptionPane.showMessageDialog( this,\r
702                                                e.getLocalizedMessage(),\r
703                                                "Unexpected error during reading of multiple sequence file",\r
704                                                JOptionPane.ERROR_MESSAGE );\r
705                 return;\r
706             }\r
707             if ( ( seqs == null ) || ( seqs.size() < 1 ) ) {\r
708                 JOptionPane.showMessageDialog( this,\r
709                                                "Multiple sequence file is empty",\r
710                                                "Empty multiple sequence file",\r
711                                                JOptionPane.ERROR_MESSAGE );\r
712                 setArrowCursor();\r
713                 return;\r
714             }\r
715         }\r
716         if ( seqs != null ) {\r
717             for( final MolecularSequence seq : seqs ) {\r
718                 System.out.println( seq.getIdentifier() );\r
719             }\r
720             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
721             int total_counter = 0;\r
722             int attached_counter = 0;\r
723             for( final MolecularSequence seq : seqs ) {\r
724                 ++total_counter;\r
725                 final String seq_name = seq.getIdentifier();\r
726                 if ( !ForesterUtil.isEmpty( seq_name ) ) {\r
727                     List<PhylogenyNode> nodes = phy.getNodesViaSequenceName( seq_name );\r
728                     if ( nodes.isEmpty() ) {\r
729                         nodes = phy.getNodesViaSequenceSymbol( seq_name );\r
730                     }\r
731                     if ( nodes.isEmpty() ) {\r
732                         nodes = phy.getNodesViaGeneName( seq_name );\r
733                     }\r
734                     if ( nodes.isEmpty() ) {\r
735                         nodes = phy.getNodes( seq_name );\r
736                     }\r
737                     if ( nodes.size() > 1 ) {\r
738                         JOptionPane.showMessageDialog( this,\r
739                                                        "Sequence name \"" + seq_name + "\" is not unique",\r
740                                                        "Sequence name not unique",\r
741                                                        JOptionPane.ERROR_MESSAGE );\r
742                         setArrowCursor();\r
743                         return;\r
744                     }\r
745                     final String[] a = seq_name.split( "\\s" );\r
746                     if ( nodes.isEmpty() && ( a.length > 1 ) ) {\r
747                         final String seq_name_split = a[ 0 ];\r
748                         nodes = phy.getNodesViaSequenceName( seq_name_split );\r
749                         if ( nodes.isEmpty() ) {\r
750                             nodes = phy.getNodesViaSequenceSymbol( seq_name_split );\r
751                         }\r
752                         if ( nodes.isEmpty() ) {\r
753                             nodes = phy.getNodes( seq_name_split );\r
754                         }\r
755                         if ( nodes.size() > 1 ) {\r
756                             JOptionPane.showMessageDialog( this, "Split sequence name \"" + seq_name_split\r
757                                     + "\" is not unique", "Sequence name not unique", JOptionPane.ERROR_MESSAGE );\r
758                             setArrowCursor();\r
759                             return;\r
760                         }\r
761                     }\r
762                     if ( nodes.size() == 1 ) {\r
763                         ++attached_counter;\r
764                         final PhylogenyNode n = nodes.get( 0 );\r
765                         if ( !n.getNodeData().isHasSequence() ) {\r
766                             n.getNodeData().addSequence( new org.forester.phylogeny.data.Sequence() );\r
767                         }\r
768                         n.getNodeData().getSequence().setMolecularSequence( seq.getMolecularSequenceAsString() );\r
769                         if ( ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) {\r
770                             n.getNodeData().getSequence().setName( seq_name );\r
771                         }\r
772                     }\r
773                 }\r
774             }\r
775             if ( attached_counter > 0 ) {\r
776                 int ext_nodes = 0;\r
777                 int ext_nodes_with_seq = 0;\r
778                 for( final PhylogenyNodeIterator iter = phy.iteratorExternalForward(); iter.hasNext(); ) {\r
779                     ++ext_nodes;\r
780                     final PhylogenyNode n = iter.next();\r
781                     if ( n.getNodeData().isHasSequence()\r
782                             && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) {\r
783                         ++ext_nodes_with_seq;\r
784                     }\r
785                 }\r
786                 final String s;\r
787                 if ( ext_nodes == ext_nodes_with_seq ) {\r
788                     s = "All " + ext_nodes_with_seq + " external nodes now have a molecular sequence attached to them.";\r
789                 }\r
790                 else {\r
791                     s = ext_nodes_with_seq + " out of " + ext_nodes\r
792                             + " external nodes now have a molecular sequence attached to them.";\r
793                 }\r
794                 if ( ( attached_counter == total_counter ) && ( ext_nodes == ext_nodes_with_seq ) ) {\r
795                     JOptionPane.showMessageDialog( this,\r
796                                                    "Attached all " + total_counter + " sequences to tree nodes.\n" + s,\r
797                                                    "All sequences attached",\r
798                                                    JOptionPane.INFORMATION_MESSAGE );\r
799                 }\r
800                 else {\r
801                     JOptionPane.showMessageDialog( this, "Attached " + attached_counter\r
802                             + " sequences out of a total of " + total_counter + " sequences.\n" + s, attached_counter\r
803                             + " sequences attached", JOptionPane.WARNING_MESSAGE );\r
804                 }\r
805             }\r
806             else {\r
807                 JOptionPane.showMessageDialog( this, "No maching tree node for any of the " + total_counter\r
808                         + " sequences", "Could not attach any sequences", JOptionPane.ERROR_MESSAGE );\r
809             }\r
810         }\r
811     }\r
812 \r
813     void buildAnalysisMenu() {\r
814         _analysis_menu = MainFrame.createMenu( "Analysis", getConfiguration() );\r
815         _analysis_menu.add( _gsdi_item = new JMenuItem( "GSDI (Generalized Speciation Duplication Inference)" ) );\r
816         _analysis_menu.add( _gsdir_item = new JMenuItem( "GSDIR (GSDI with re-rooting)" ) );\r
817         _analysis_menu.add( _load_species_tree_item = new JMenuItem( "Load Species Tree..." ) );\r
818         customizeJMenuItem( _gsdi_item );\r
819         customizeJMenuItem( _gsdir_item );\r
820         customizeJMenuItem( _load_species_tree_item );\r
821         _analysis_menu.addSeparator();\r
822         _analysis_menu.add( _lineage_inference = new JMenuItem( INFER_ANCESTOR_TAXONOMIES ) );\r
823         customizeJMenuItem( _lineage_inference );\r
824         _lineage_inference.setToolTipText( "Inference of ancestor taxonomies/lineages" );\r
825         _jmenubar.add( _analysis_menu );\r
826     }\r
827 \r
828     @Override\r
829     void buildFileMenu() {\r
830         _file_jmenu = MainFrame.createMenu( "File", getConfiguration() );\r
831         _file_jmenu.add( _open_item = new JMenuItem( "Read Tree from File..." ) );\r
832         _file_jmenu.addSeparator();\r
833         _file_jmenu.add( _open_url_item = new JMenuItem( "Read Tree from URL/Webservice..." ) );\r
834         _file_jmenu.addSeparator();\r
835         final WebservicesManager webservices_manager = WebservicesManager.getInstance();\r
836         _load_phylogeny_from_webservice_menu_items = new JMenuItem[ webservices_manager\r
837                 .getAvailablePhylogeniesWebserviceClients().size() ];\r
838         for( int i = 0; i < webservices_manager.getAvailablePhylogeniesWebserviceClients().size(); ++i ) {\r
839             final PhylogeniesWebserviceClient client = webservices_manager.getAvailablePhylogeniesWebserviceClient( i );\r
840             _load_phylogeny_from_webservice_menu_items[ i ] = new JMenuItem( client.getMenuName() );\r
841             _file_jmenu.add( _load_phylogeny_from_webservice_menu_items[ i ] );\r
842         }\r
843         if ( getConfiguration().isEditable() ) {\r
844             _file_jmenu.addSeparator();\r
845             _file_jmenu.add( _new_item = new JMenuItem( "New" ) );\r
846             _new_item.setToolTipText( "to create a new tree with one node, as source for manual tree construction" );\r
847         }\r
848         _file_jmenu.addSeparator();\r
849         _file_jmenu.add( _save_item = new JMenuItem( "Save Tree As..." ) );\r
850         _file_jmenu.add( _save_all_item = new JMenuItem( "Save All Trees As..." ) );\r
851         _save_all_item.setToolTipText( "Write all phylogenies to one file." );\r
852         _save_all_item.setEnabled( false );\r
853         _file_jmenu.addSeparator();\r
854         _file_jmenu.add( _write_to_pdf_item = new JMenuItem( "Export to PDF file ..." ) );\r
855         if ( AptxUtil.canWriteFormat( "tif" ) || AptxUtil.canWriteFormat( "tiff" ) || AptxUtil.canWriteFormat( "TIF" ) ) {\r
856             _file_jmenu.add( _write_to_tif_item = new JMenuItem( "Export to TIFF file..." ) );\r
857         }\r
858         _file_jmenu.add( _write_to_png_item = new JMenuItem( "Export to PNG file..." ) );\r
859         _file_jmenu.add( _write_to_jpg_item = new JMenuItem( "Export to JPG file..." ) );\r
860         if ( AptxUtil.canWriteFormat( "gif" ) ) {\r
861             _file_jmenu.add( _write_to_gif_item = new JMenuItem( "Export to GIF file..." ) );\r
862         }\r
863         if ( AptxUtil.canWriteFormat( "bmp" ) ) {\r
864             _file_jmenu.add( _write_to_bmp_item = new JMenuItem( "Export to BMP file..." ) );\r
865         }\r
866         _file_jmenu.addSeparator();\r
867         _file_jmenu.add( _print_item = new JMenuItem( "Print..." ) );\r
868         _file_jmenu.addSeparator();\r
869         _file_jmenu.add( _close_item = new JMenuItem( "Close Tab" ) );\r
870         _close_item.setToolTipText( "To close the current pane." );\r
871         _close_item.setEnabled( true );\r
872         _file_jmenu.addSeparator();\r
873         _file_jmenu.add( _exit_item = new JMenuItem( "Exit" ) );\r
874         customizeJMenuItem( _open_item );\r
875         _open_item\r
876                 .setFont( new Font( _open_item.getFont().getFontName(), Font.BOLD, _open_item.getFont().getSize() + 4 ) );\r
877         customizeJMenuItem( _open_url_item );\r
878         for( int i = 0; i < webservices_manager.getAvailablePhylogeniesWebserviceClients().size(); ++i ) {\r
879             customizeJMenuItem( _load_phylogeny_from_webservice_menu_items[ i ] );\r
880         }\r
881         customizeJMenuItem( _save_item );\r
882         if ( getConfiguration().isEditable() ) {\r
883             customizeJMenuItem( _new_item );\r
884         }\r
885         customizeJMenuItem( _close_item );\r
886         customizeJMenuItem( _save_all_item );\r
887         customizeJMenuItem( _write_to_pdf_item );\r
888         customizeJMenuItem( _write_to_png_item );\r
889         customizeJMenuItem( _write_to_jpg_item );\r
890         customizeJMenuItem( _write_to_gif_item );\r
891         customizeJMenuItem( _write_to_tif_item );\r
892         customizeJMenuItem( _write_to_bmp_item );\r
893         customizeJMenuItem( _print_item );\r
894         customizeJMenuItem( _exit_item );\r
895         _jmenubar.add( _file_jmenu );\r
896     }\r
897 \r
898     void buildOptionsMenu() {\r
899         _options_jmenu = MainFrame.createMenu( OPTIONS_HEADER, getConfiguration() );\r
900         _options_jmenu.addChangeListener( new ChangeListener() {\r
901 \r
902             @Override\r
903             public void stateChanged( final ChangeEvent e ) {\r
904                 MainFrame.setOvPlacementColorChooseMenuItem( _overview_placment_mi, getOptions() );\r
905                 MainFrame.setTextColorChooseMenuItem( _switch_colors_mi, getCurrentTreePanel() );\r
906                 MainFrame\r
907                         .setTextMinSupportMenuItem( _choose_minimal_confidence_mi, getOptions(), getCurrentTreePanel() );\r
908                 MainFrame.setTextForFontChooserMenuItem( _choose_font_mi, MainFrame\r
909                         .createCurrentFontDesc( getMainPanel().getTreeFontSet() ) );\r
910                 MainFrame.setTextForGraphicsSizeChooserMenuItem( _print_size_mi, getOptions() );\r
911                 MainFrame.setTextForPdfLineWidthChooserMenuItem( _choose_pdf_width_mi, getOptions() );\r
912                 MainFrame.setCycleNodeFillMenuItem( _cycle_node_fill_mi, getOptions() );\r
913                 MainFrame.setCycleNodeShapeMenuItem( _cycle_node_shape_mi, getOptions() );\r
914                 MainFrame.setCycleDataReturnMenuItem( _cycle_data_return, getOptions() );\r
915                 MainFrame.setTextNodeSizeMenuItem( _choose_node_size_mi, getOptions() );\r
916                 try {\r
917                     getMainPanel().getControlPanel().setVisibilityOfDomainStrucureCB();\r
918                     getMainPanel().getControlPanel().setVisibilityOfX();\r
919                 }\r
920                 catch ( final Exception ignore ) {\r
921                     // do nothing, not important.\r
922                 }\r
923             }\r
924         } );\r
925         _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( DISPLAY_SUBHEADER ), getConfiguration() ) );\r
926         _options_jmenu\r
927                 .add( _ext_node_dependent_cladogram_rbmi = new JRadioButtonMenuItem( MainFrame.NONUNIFORM_CLADOGRAMS_LABEL ) );\r
928         _options_jmenu.add( _uniform_cladograms_rbmi = new JRadioButtonMenuItem( MainFrame.UNIFORM_CLADOGRAMS_LABEL ) );\r
929         _options_jmenu.add( _non_lined_up_cladograms_rbmi = new JRadioButtonMenuItem( NON_LINED_UP_CLADOGRAMS_LABEL ) );\r
930         _radio_group_1 = new ButtonGroup();\r
931         _radio_group_1.add( _ext_node_dependent_cladogram_rbmi );\r
932         _radio_group_1.add( _uniform_cladograms_rbmi );\r
933         _radio_group_1.add( _non_lined_up_cladograms_rbmi );\r
934         _options_jmenu.add( _show_overview_cbmi = new JCheckBoxMenuItem( SHOW_OVERVIEW_LABEL ) );\r
935         _options_jmenu.add( _show_scale_cbmi = new JCheckBoxMenuItem( DISPLAY_SCALE_LABEL ) );\r
936         _options_jmenu\r
937                 .add( _show_default_node_shapes_internal_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_INT ) );\r
938         _options_jmenu\r
939                 .add( _show_default_node_shapes_external_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_EXT ) );\r
940         _options_jmenu\r
941                 .add( _show_default_node_shapes_for_marked_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_NODE_BOXES_LABEL_MARKED ) );\r
942         _options_jmenu.add( _line_up_renderable_data_cbmi = new JCheckBoxMenuItem( MainFrame.LINE_UP_RENDERABLE_DATA ) );\r
943         if ( getConfiguration().doDisplayOption( Configuration.show_domain_architectures ) ) {\r
944             _options_jmenu.add( _right_line_up_domains_cbmi = new JCheckBoxMenuItem( MainFrame.RIGHT_LINE_UP_DOMAINS ) );\r
945             _options_jmenu.add( _show_domain_labels = new JCheckBoxMenuItem( MainFrame.SHOW_DOMAIN_LABELS_LABEL ) );\r
946         }\r
947         _options_jmenu.add( _show_annotation_ref_source = new JCheckBoxMenuItem( SHOW_ANN_REF_SOURCE_LABEL ) );\r
948         _options_jmenu.add( _show_confidence_stddev_cbmi = new JCheckBoxMenuItem( SHOW_CONF_STDDEV_LABEL ) );\r
949         _options_jmenu.add( _color_by_taxonomic_group_cbmi = new JCheckBoxMenuItem( COLOR_BY_TAXONOMIC_GROUP ) );\r
950         _options_jmenu.add( _color_labels_same_as_parent_branch = new JCheckBoxMenuItem( COLOR_LABELS_LABEL ) );\r
951         _color_labels_same_as_parent_branch.setToolTipText( MainFrame.COLOR_LABELS_TIP );\r
952         _options_jmenu.add( _abbreviate_scientific_names = new JCheckBoxMenuItem( ABBREV_SN_LABEL ) );\r
953         _options_jmenu.add( _label_direction_cbmi = new JCheckBoxMenuItem( LABEL_DIRECTION_LABEL ) );\r
954         _label_direction_cbmi.setToolTipText( LABEL_DIRECTION_TIP );\r
955         _options_jmenu.add( _screen_antialias_cbmi = new JCheckBoxMenuItem( SCREEN_ANTIALIAS_LABEL ) );\r
956         _options_jmenu.add( _background_gradient_cbmi = new JCheckBoxMenuItem( BG_GRAD_LABEL ) );\r
957         _options_jmenu.add( _cycle_node_shape_mi = new JMenuItem( MainFrame.CYCLE_NODE_SHAPE_LABEL ) );\r
958         _options_jmenu.add( _cycle_node_fill_mi = new JMenuItem( MainFrame.CYCLE_NODE_FILL_LABEL ) );\r
959         _options_jmenu.add( _choose_node_size_mi = new JMenuItem( MainFrame.CHOOSE_NODE_SIZE_LABEL ) );\r
960         _options_jmenu.add( _choose_minimal_confidence_mi = new JMenuItem( "" ) );\r
961         _options_jmenu.add( _overview_placment_mi = new JMenuItem( "" ) );\r
962         _options_jmenu.add( _switch_colors_mi = new JMenuItem( "" ) );\r
963         _options_jmenu.add( _choose_font_mi = new JMenuItem( "" ) );\r
964         _options_jmenu.addSeparator();\r
965         _options_jmenu.add( _cycle_data_return = new JMenuItem( "Cycle Data Return" ) );\r
966         _options_jmenu.addSeparator();\r
967         _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( SEARCH_SUBHEADER ), getConfiguration() ) );\r
968         _options_jmenu.add( _search_case_senstive_cbmi = new JCheckBoxMenuItem( SEARCH_CASE_SENSITIVE_LABEL ) );\r
969         _options_jmenu.add( _search_whole_words_only_cbmi = new JCheckBoxMenuItem( SEARCH_TERMS_ONLY_LABEL ) );\r
970         _options_jmenu.add( _search_with_regex_cbmi = new JCheckBoxMenuItem( MainFrame.SEARCH_REGEX_LABEL ) );\r
971         _search_with_regex_cbmi.setToolTipText( MainFrame.SEARCH_WITH_REGEX_TIP );\r
972         _options_jmenu.add( _inverse_search_result_cbmi = new JCheckBoxMenuItem( INVERSE_SEARCH_RESULT_LABEL ) );\r
973         _options_jmenu.addSeparator();\r
974         _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Graphics Export & Printing:" ),\r
975                                                       getConfiguration() ) );\r
976         _options_jmenu.add( _antialias_print_cbmi = new JCheckBoxMenuItem( "Antialias" ) );\r
977         _options_jmenu.add( _print_black_and_white_cbmi = new JCheckBoxMenuItem( "Export in Black and White" ) );\r
978         _options_jmenu\r
979                 .add( _print_using_actual_size_cbmi = new JCheckBoxMenuItem( "Use Current Image Size for PDF export and Printing" ) );\r
980         _options_jmenu\r
981                 .add( _graphics_export_using_actual_size_cbmi = new JCheckBoxMenuItem( "Use Current Image Size for PNG, JPG, and GIF export" ) );\r
982         _options_jmenu\r
983                 .add( _graphics_export_visible_only_cbmi = new JCheckBoxMenuItem( "Limit to Visible ('Screenshot') for PNG, JPG, and GIF export" ) );\r
984         _options_jmenu.add( _print_size_mi = new JMenuItem( "" ) );\r
985         _options_jmenu.add( _choose_pdf_width_mi = new JMenuItem( "" ) );\r
986         _options_jmenu.addSeparator();\r
987         _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Newick/NHX/Nexus Input:" ), getConfiguration() ) );\r
988         _options_jmenu\r
989                 .add( _internal_number_are_confidence_for_nh_parsing_cbmi = new JCheckBoxMenuItem( "Internal Node Names are Confidence Values" ) );\r
990         _options_jmenu.add( _replace_underscores_cbmi = new JCheckBoxMenuItem( "Replace Underscores with Spaces" ) );\r
991         _options_jmenu\r
992                 .add( _allow_errors_in_distance_to_parent_cbmi = new JCheckBoxMenuItem( "Ignore Distance Values Format Errors" ) );\r
993         _options_jmenu.add( _extract_taxonomy_no_rbmi = new JRadioButtonMenuItem( "No Taxonomy Extraction" ) );\r
994         _options_jmenu\r
995                 .add( _extract_taxonomy_pfam_strict_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style Node Names" ) );\r
996         _options_jmenu\r
997                 .add( _extract_taxonomy_pfam_relaxed_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style like Node Names" ) );\r
998         _options_jmenu\r
999                 .add( _extract_taxonomy_agressive_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids/Scientific Names from Node Names" ) );\r
1000         _extract_taxonomy_pfam_strict_rbmi\r
1001                 .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"BCL2_MOUSE/123-304\" or \"BCL2_10090/123-304\"" );\r
1002         _extract_taxonomy_pfam_relaxed_rbmi\r
1003                 .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"bax_MOUSE\" or \"bax_10090\"" );\r
1004         _extract_taxonomy_agressive_rbmi\r
1005                 .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\"" );\r
1006         _radio_group_2 = new ButtonGroup();\r
1007         _radio_group_2.add( _extract_taxonomy_no_rbmi );\r
1008         _radio_group_2.add( _extract_taxonomy_pfam_strict_rbmi );\r
1009         _radio_group_2.add( _extract_taxonomy_pfam_relaxed_rbmi );\r
1010         _radio_group_2.add( _extract_taxonomy_agressive_rbmi );\r
1011         _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Newick/Nexus Output:" ), getConfiguration() ) );\r
1012         _options_jmenu\r
1013                 .add( _use_brackets_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_BRACKETS_FOR_CONF_IN_NH_LABEL ) );\r
1014         _use_brackets_for_conf_in_nh_export_cbmi\r
1015                 .setToolTipText( "e.g. \"0.1[90]\" for a branch with support 90 and a length of 0.1" );\r
1016         _options_jmenu\r
1017                 .add( _use_internal_names_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_INTERNAL_NAMES_FOR_CONF_IN_NH_LABEL ) );\r
1018         customizeJMenuItem( _choose_font_mi );\r
1019         customizeJMenuItem( _choose_minimal_confidence_mi );\r
1020         customizeJMenuItem( _switch_colors_mi );\r
1021         customizeJMenuItem( _print_size_mi );\r
1022         customizeJMenuItem( _choose_pdf_width_mi );\r
1023         customizeJMenuItem( _overview_placment_mi );\r
1024         customizeCheckBoxMenuItem( _show_default_node_shapes_external_cbmi, getOptions()\r
1025                 .isShowDefaultNodeShapesExternal() );\r
1026         customizeCheckBoxMenuItem( _show_default_node_shapes_internal_cbmi, getOptions()\r
1027                 .isShowDefaultNodeShapesInternal() );\r
1028         customizeCheckBoxMenuItem( _show_default_node_shapes_for_marked_cbmi, getOptions()\r
1029                 .isShowDefaultNodeShapesForMarkedNodes() );\r
1030         customizeJMenuItem( _cycle_node_shape_mi );\r
1031         customizeJMenuItem( _cycle_node_fill_mi );\r
1032         customizeJMenuItem( _choose_node_size_mi );\r
1033         customizeJMenuItem( _cycle_data_return );\r
1034         customizeCheckBoxMenuItem( _color_labels_same_as_parent_branch, getOptions().isColorLabelsSameAsParentBranch() );\r
1035         customizeCheckBoxMenuItem( _color_by_taxonomic_group_cbmi, getOptions().isColorByTaxonomicGroup() );\r
1036         customizeCheckBoxMenuItem( _screen_antialias_cbmi, getOptions().isAntialiasScreen() );\r
1037         customizeCheckBoxMenuItem( _background_gradient_cbmi, getOptions().isBackgroundColorGradient() );\r
1038         customizeCheckBoxMenuItem( _show_domain_labels, getOptions().isShowDomainLabels() );\r
1039         customizeCheckBoxMenuItem( _show_annotation_ref_source, getOptions().isShowAnnotationRefSource() );\r
1040         customizeCheckBoxMenuItem( _abbreviate_scientific_names, getOptions().isAbbreviateScientificTaxonNames() );\r
1041         customizeCheckBoxMenuItem( _search_case_senstive_cbmi, getOptions().isSearchCaseSensitive() );\r
1042         customizeCheckBoxMenuItem( _show_scale_cbmi, getOptions().isShowScale() );\r
1043         customizeRadioButtonMenuItem( _non_lined_up_cladograms_rbmi,\r
1044                                       getOptions().getCladogramType() == CLADOGRAM_TYPE.NON_LINED_UP );\r
1045         customizeRadioButtonMenuItem( _uniform_cladograms_rbmi,\r
1046                                       getOptions().getCladogramType() == CLADOGRAM_TYPE.TOTAL_NODE_SUM_DEP );\r
1047         customizeRadioButtonMenuItem( _ext_node_dependent_cladogram_rbmi,\r
1048                                       getOptions().getCladogramType() == CLADOGRAM_TYPE.EXT_NODE_SUM_DEP );\r
1049         customizeCheckBoxMenuItem( _show_overview_cbmi, getOptions().isShowOverview() );\r
1050         customizeCheckBoxMenuItem( _label_direction_cbmi,\r
1051                                    getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL );\r
1052         customizeCheckBoxMenuItem( _antialias_print_cbmi, getOptions().isAntialiasPrint() );\r
1053         customizeCheckBoxMenuItem( _print_black_and_white_cbmi, getOptions().isPrintBlackAndWhite() );\r
1054         customizeCheckBoxMenuItem( _internal_number_are_confidence_for_nh_parsing_cbmi, getOptions()\r
1055                 .isInternalNumberAreConfidenceForNhParsing() );\r
1056         customizeRadioButtonMenuItem( _extract_taxonomy_no_rbmi,\r
1057                                       getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.NO );\r
1058         customizeRadioButtonMenuItem( _extract_taxonomy_pfam_strict_rbmi,\r
1059                                       getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT );\r
1060         customizeRadioButtonMenuItem( _extract_taxonomy_pfam_relaxed_rbmi,\r
1061                                       getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.PFAM_STYLE_RELAXED );\r
1062         customizeRadioButtonMenuItem( _extract_taxonomy_agressive_rbmi,\r
1063                                       getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.AGGRESSIVE );\r
1064         customizeCheckBoxMenuItem( _replace_underscores_cbmi, getOptions().isReplaceUnderscoresInNhParsing() );\r
1065         customizeCheckBoxMenuItem( _allow_errors_in_distance_to_parent_cbmi, getOptions()\r
1066                 .isReplaceUnderscoresInNhParsing() );\r
1067         customizeCheckBoxMenuItem( _search_with_regex_cbmi, getOptions().isSearchWithRegex() );\r
1068         customizeCheckBoxMenuItem( _search_whole_words_only_cbmi, getOptions().isMatchWholeTermsOnly() );\r
1069         customizeCheckBoxMenuItem( _inverse_search_result_cbmi, getOptions().isInverseSearchResult() );\r
1070         customizeCheckBoxMenuItem( _graphics_export_visible_only_cbmi, getOptions().isGraphicsExportVisibleOnly() );\r
1071         customizeCheckBoxMenuItem( _print_using_actual_size_cbmi, getOptions().isPrintUsingActualSize() );\r
1072         customizeCheckBoxMenuItem( _graphics_export_using_actual_size_cbmi, getOptions()\r
1073                 .isGraphicsExportUsingActualSize() );\r
1074         customizeCheckBoxMenuItem( _show_confidence_stddev_cbmi, getOptions().isShowConfidenceStddev() );\r
1075         customizeCheckBoxMenuItem( _use_brackets_for_conf_in_nh_export_cbmi, getOptions()\r
1076                 .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.IN_SQUARE_BRACKETS );\r
1077         customizeCheckBoxMenuItem( _use_internal_names_for_conf_in_nh_export_cbmi, getOptions()\r
1078                 .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.AS_INTERNAL_NODE_NAMES );\r
1079         customizeCheckBoxMenuItem( _line_up_renderable_data_cbmi, getOptions().isLineUpRendarableNodeData() );\r
1080         customizeCheckBoxMenuItem( _right_line_up_domains_cbmi, getOptions().isRightLineUpDomains() );\r
1081         _jmenubar.add( _options_jmenu );\r
1082     }\r
1083 \r
1084     void buildPhylogeneticInferenceMenu() {\r
1085         final InferenceManager im = getInferenceManager();\r
1086         _inference_menu = MainFrame.createMenu( "Inference", getConfiguration() );\r
1087         _inference_menu.add( _inference_from_msa_item = new JMenuItem( "From Multiple Sequence Alignment..." ) );\r
1088         customizeJMenuItem( _inference_from_msa_item );\r
1089         _inference_from_msa_item.setToolTipText( "Basic phylogenetic inference from MSA" );\r
1090         if ( im.canDoMsa() ) {\r
1091             _inference_menu.add( _inference_from_seqs_item = new JMenuItem( "From Unaligned Sequences..." ) );\r
1092             customizeJMenuItem( _inference_from_seqs_item );\r
1093             _inference_from_seqs_item\r
1094                     .setToolTipText( "Basic phylogenetic inference including multiple sequence alignment" );\r
1095         }\r
1096         else {\r
1097             _inference_menu\r
1098                     .add( _inference_from_seqs_item = new JMenuItem( "From Unaligned Sequences (no program found)" ) );\r
1099             customizeJMenuItem( _inference_from_seqs_item );\r
1100             _inference_from_seqs_item.setEnabled( false );\r
1101         }\r
1102         _jmenubar.add( _inference_menu );\r
1103     }\r
1104 \r
1105     void buildToolsMenu() {\r
1106         _tools_menu = createMenu( "Tools", getConfiguration() );\r
1107         _tools_menu.add( _confcolor_item = new JMenuItem( "Colorize Branches Depending on Confidence" ) );\r
1108         customizeJMenuItem( _confcolor_item );\r
1109         _tools_menu.add( _color_rank_jmi = new JMenuItem( "Colorize Subtrees via Taxonomic Rank" ) );\r
1110         customizeJMenuItem( _color_rank_jmi );\r
1111         _color_rank_jmi.setToolTipText( "for example, at \"Class\" level, colorize mammal specific subtree red" );\r
1112         _tools_menu.add( _taxcolor_item = new JMenuItem( "Taxonomy Colorize Branches" ) );\r
1113         customizeJMenuItem( _taxcolor_item );\r
1114         _tools_menu.addSeparator();\r
1115         _tools_menu.add( _remove_visual_styles_item = new JMenuItem( "Delete All Visual Styles From Nodes" ) );\r
1116         _remove_visual_styles_item\r
1117                 .setToolTipText( "To remove all node visual styles (fonts, colors) from the current phylogeny" );\r
1118         customizeJMenuItem( _remove_visual_styles_item );\r
1119         _tools_menu.add( _remove_branch_color_item = new JMenuItem( "Delete All Colors From Branches" ) );\r
1120         _remove_branch_color_item.setToolTipText( "To remove all branch color values from the current phylogeny" );\r
1121         customizeJMenuItem( _remove_branch_color_item );\r
1122         _tools_menu.addSeparator();\r
1123         _tools_menu.add( _annotate_item = new JMenuItem( "Annotate Sequences of Selected Nodes" ) );\r
1124         customizeJMenuItem( _annotate_item );\r
1125         _tools_menu.addSeparator();\r
1126         _tools_menu.add( _midpoint_root_item = new JMenuItem( "Midpoint-Root" ) );\r
1127         customizeJMenuItem( _midpoint_root_item );\r
1128         _tools_menu.addSeparator();\r
1129         _tools_menu.add( _delete_selected_nodes_item = new JMenuItem( "Delete Selected Nodes" ) );\r
1130         _delete_selected_nodes_item.setToolTipText( "To delete all selected external nodes" );\r
1131         customizeJMenuItem( _delete_selected_nodes_item );\r
1132         _tools_menu.add( _delete_not_selected_nodes_item = new JMenuItem( "Retain Selected Nodes" ) );\r
1133         _delete_not_selected_nodes_item.setToolTipText( "To delete all not selected external nodes" );\r
1134         customizeJMenuItem( _delete_not_selected_nodes_item );\r
1135         _tools_menu.addSeparator();\r
1136         _tools_menu.add( _collapse_species_specific_subtrees = new JMenuItem( "Collapse Species-Specific Subtrees" ) );\r
1137         customizeJMenuItem( _collapse_species_specific_subtrees );\r
1138         _collapse_species_specific_subtrees.setToolTipText( "To (reversibly) collapse species-specific subtrees" );\r
1139         _tools_menu\r
1140                 .add( _collapse_below_threshold = new JMenuItem( "Collapse Branches with Confidence Below Threshold into Multifurcations" ) );\r
1141         customizeJMenuItem( _collapse_below_threshold );\r
1142         _collapse_below_threshold\r
1143                 .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
1144         //\r
1145         _tools_menu\r
1146                 .add( _collapse_below_branch_length = new JMenuItem( "Collapse Branches with Branch Lengths Below Threshold into Multifurcations" ) );\r
1147         customizeJMenuItem( _collapse_below_branch_length );\r
1148         _collapse_below_branch_length\r
1149                 .setToolTipText( "To (permanently) collapse branches with branches with branch lengths below a threshold into multifurcations" );\r
1150         //\r
1151         _tools_menu.addSeparator();\r
1152         _tools_menu\r
1153                 .add( _extract_tax_code_from_node_names_jmi = new JMenuItem( "Extract Taxonomic Data from Node Names" ) );\r
1154         customizeJMenuItem( _extract_tax_code_from_node_names_jmi );\r
1155         _extract_tax_code_from_node_names_jmi\r
1156                 .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'" );\r
1157         _tools_menu\r
1158                 .add( _move_node_names_to_tax_sn_jmi = new JMenuItem( "Transfer Node Names to Taxonomic Scientific Names" ) );\r
1159         customizeJMenuItem( _move_node_names_to_tax_sn_jmi );\r
1160         _move_node_names_to_tax_sn_jmi.setToolTipText( "To interpret node names as taxonomic scientific names" );\r
1161         _tools_menu.add( _move_node_names_to_seq_names_jmi = new JMenuItem( "Transfer Node Names to Sequence Names" ) );\r
1162         customizeJMenuItem( _move_node_names_to_seq_names_jmi );\r
1163         _move_node_names_to_seq_names_jmi.setToolTipText( "To interpret node names as sequence (protein, gene) names" );\r
1164         _tools_menu.addSeparator();\r
1165         _tools_menu.add( _obtain_seq_information_jmi = new JMenuItem( "Obtain Sequence Information" ) );\r
1166         customizeJMenuItem( _obtain_seq_information_jmi );\r
1167         _obtain_seq_information_jmi.setToolTipText( "To add additional sequence information" );\r
1168         _tools_menu\r
1169                 .add( _obtain_detailed_taxonomic_information_jmi = new JMenuItem( OBTAIN_DETAILED_TAXONOMIC_INFORMATION ) );\r
1170         customizeJMenuItem( _obtain_detailed_taxonomic_information_jmi );\r
1171         _obtain_detailed_taxonomic_information_jmi\r
1172                 .setToolTipText( "To add additional taxonomic information (from UniProt Taxonomy)" );\r
1173         _tools_menu\r
1174                 .add( _obtain_detailed_taxonomic_information_deleting_jmi = new JMenuItem( "Obtain Detailed Taxonomic Information (deletes nodes!)" ) );\r
1175         customizeJMenuItem( _obtain_detailed_taxonomic_information_deleting_jmi );\r
1176         _obtain_detailed_taxonomic_information_deleting_jmi\r
1177                 .setToolTipText( "To add additional taxonomic information, deletes nodes for which taxonomy cannot found (from UniProt Taxonomy)" );\r
1178         _tools_menu.addSeparator();\r
1179         _tools_menu.add( _read_values_jmi = new JMenuItem( "Attach Vector/Expression Values" ) );\r
1180         customizeJMenuItem( _read_values_jmi );\r
1181         _read_values_jmi.setToolTipText( "To attach vector (e.g. gene expression) values to tree nodes (beta)" );\r
1182         _jmenubar.add( _tools_menu );\r
1183         _tools_menu.add( _read_seqs_jmi = new JMenuItem( "Attach Molecular Sequences" ) );\r
1184         customizeJMenuItem( _read_seqs_jmi );\r
1185         _read_seqs_jmi\r
1186                 .setToolTipText( "To attach molecular sequences to tree nodes (from Fasta-formatted file) (beta)" );\r
1187         _jmenubar.add( _tools_menu );\r
1188     }\r
1189 \r
1190     @Override\r
1191     void close() {\r
1192         if ( isUnsavedDataPresent() ) {\r
1193             final int r = JOptionPane.showConfirmDialog( this,\r
1194                                                          "Exit despite potentially unsaved changes?",\r
1195                                                          "Exit?",\r
1196                                                          JOptionPane.YES_NO_OPTION );\r
1197             if ( r != JOptionPane.YES_OPTION ) {\r
1198                 return;\r
1199             }\r
1200         }\r
1201         exit();\r
1202     }\r
1203 \r
1204     private void closeCurrentPane() {\r
1205         if ( getMainPanel().getCurrentTreePanel() != null ) {\r
1206             if ( getMainPanel().getCurrentTreePanel().isEdited() ) {\r
1207                 final int r = JOptionPane.showConfirmDialog( this,\r
1208                                                              "Close tab despite potentially unsaved changes?",\r
1209                                                              "Close Tab?",\r
1210                                                              JOptionPane.YES_NO_OPTION );\r
1211                 if ( r != JOptionPane.YES_OPTION ) {\r
1212                     return;\r
1213                 }\r
1214             }\r
1215             getMainPanel().closeCurrentPane();\r
1216             activateSaveAllIfNeeded();\r
1217         }\r
1218     }\r
1219 \r
1220     private void collapse( final Phylogeny phy ) {\r
1221         final PhylogenyNodeIterator it = phy.iteratorPostorder();\r
1222         final List<PhylogenyNode> to_be_removed = new ArrayList<PhylogenyNode>();\r
1223         double min_support = Double.MAX_VALUE;\r
1224         boolean conf_present = false;\r
1225         while ( it.hasNext() ) {\r
1226             final PhylogenyNode n = it.next();\r
1227             if ( !n.isExternal() && !n.isRoot() ) {\r
1228                 final List<Confidence> c = n.getBranchData().getConfidences();\r
1229                 if ( ( c != null ) && ( c.size() > 0 ) ) {\r
1230                     conf_present = true;\r
1231                     double max = 0;\r
1232                     for( final Confidence confidence : c ) {\r
1233                         if ( confidence.getValue() > max ) {\r
1234                             max = confidence.getValue();\r
1235                         }\r
1236                     }\r
1237                     if ( max < getMinNotCollapseConfidenceValue() ) {\r
1238                         to_be_removed.add( n );\r
1239                     }\r
1240                     if ( max < min_support ) {\r
1241                         min_support = max;\r
1242                     }\r
1243                 }\r
1244             }\r
1245         }\r
1246         if ( conf_present ) {\r
1247             for( final PhylogenyNode node : to_be_removed ) {\r
1248                 PhylogenyMethods.removeNode( node, phy );\r
1249             }\r
1250             if ( to_be_removed.size() > 0 ) {\r
1251                 phy.externalNodesHaveChanged();\r
1252                 phy.clearHashIdToNodeMap();\r
1253                 phy.recalculateNumberOfExternalDescendants( true );\r
1254                 getCurrentTreePanel().resetNodeIdToDistToLeafMap();\r
1255                 getCurrentTreePanel().updateSetOfCollapsedExternalNodes();\r
1256                 getCurrentTreePanel().calculateLongestExtNodeInfo();\r
1257                 getCurrentTreePanel().setNodeInPreorderToNull();\r
1258                 getCurrentTreePanel().recalculateMaxDistanceToRoot();\r
1259                 getCurrentTreePanel().resetPreferredSize();\r
1260                 getCurrentTreePanel().setEdited( true );\r
1261                 getCurrentTreePanel().repaint();\r
1262                 repaint();\r
1263             }\r
1264             if ( to_be_removed.size() > 0 ) {\r
1265                 JOptionPane.showMessageDialog( this, "Collapsed " + to_be_removed.size()\r
1266                         + " branches with\nconfidence values below " + getMinNotCollapseConfidenceValue(), "Collapsed "\r
1267                         + to_be_removed.size() + " branches", JOptionPane.INFORMATION_MESSAGE );\r
1268             }\r
1269             else {\r
1270                 JOptionPane.showMessageDialog( this, "No branch collapsed,\nminimum confidence value per branch is "\r
1271                         + min_support, "No branch collapsed", JOptionPane.INFORMATION_MESSAGE );\r
1272             }\r
1273         }\r
1274         else {\r
1275             JOptionPane.showMessageDialog( this,\r
1276                                            "No branch collapsed because no confidence values present",\r
1277                                            "No confidence values present",\r
1278                                            JOptionPane.INFORMATION_MESSAGE );\r
1279         }\r
1280     }\r
1281 \r
1282     private void collapseBelowBranchLengthThreshold() {\r
1283         if ( getCurrentTreePanel() != null ) {\r
1284             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
1285             if ( ( phy != null ) && !phy.isEmpty() ) {\r
1286                 final String s = ( String ) JOptionPane\r
1287                         .showInputDialog( this,\r
1288                                           "Please enter the minimum branch length value\n",\r
1289                                           "Minimal Branch Length Value",\r
1290                                           JOptionPane.QUESTION_MESSAGE,\r
1291                                           null,\r
1292                                           null,\r
1293                                           getMinNotCollapseBlValue() );\r
1294                 if ( !ForesterUtil.isEmpty( s ) ) {\r
1295                     boolean success = true;\r
1296                     double m = 0.0;\r
1297                     final String m_str = s.trim();\r
1298                     if ( !ForesterUtil.isEmpty( m_str ) ) {\r
1299                         try {\r
1300                             m = Double.parseDouble( m_str );\r
1301                         }\r
1302                         catch ( final Exception ex ) {\r
1303                             success = false;\r
1304                         }\r
1305                     }\r
1306                     else {\r
1307                         success = false;\r
1308                     }\r
1309                     if ( success && ( m >= 0.0 ) ) {\r
1310                         setMinNotCollapseBlValue( m );\r
1311                         collapseBl( phy );\r
1312                     }\r
1313                 }\r
1314             }\r
1315         }\r
1316     }\r
1317 \r
1318     private void collapseBelowThreshold() {\r
1319         if ( getCurrentTreePanel() != null ) {\r
1320             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
1321             if ( ( phy != null ) && !phy.isEmpty() ) {\r
1322                 final String s = ( String ) JOptionPane.showInputDialog( this,\r
1323                                                                          "Please enter the minimum confidence value\n",\r
1324                                                                          "Minimal Confidence Value",\r
1325                                                                          JOptionPane.QUESTION_MESSAGE,\r
1326                                                                          null,\r
1327                                                                          null,\r
1328                                                                          getMinNotCollapseConfidenceValue() );\r
1329                 if ( !ForesterUtil.isEmpty( s ) ) {\r
1330                     boolean success = true;\r
1331                     double m = 0.0;\r
1332                     final String m_str = s.trim();\r
1333                     if ( !ForesterUtil.isEmpty( m_str ) ) {\r
1334                         try {\r
1335                             m = Double.parseDouble( m_str );\r
1336                         }\r
1337                         catch ( final Exception ex ) {\r
1338                             success = false;\r
1339                         }\r
1340                     }\r
1341                     else {\r
1342                         success = false;\r
1343                     }\r
1344                     if ( success && ( m >= 0.0 ) ) {\r
1345                         setMinNotCollapseConfidenceValue( m );\r
1346                         collapse( phy );\r
1347                     }\r
1348                 }\r
1349             }\r
1350         }\r
1351     }\r
1352 \r
1353     private void collapseBl( final Phylogeny phy ) {\r
1354         final PhylogenyNodeIterator it = phy.iteratorPostorder();\r
1355         final List<PhylogenyNode> to_be_removed = new ArrayList<PhylogenyNode>();\r
1356         double min_bl = Double.MAX_VALUE;\r
1357         boolean bl_present = false;\r
1358         while ( it.hasNext() ) {\r
1359             final PhylogenyNode n = it.next();\r
1360             if ( !n.isExternal() && !n.isRoot() ) {\r
1361                 final double bl = n.getDistanceToParent();\r
1362                 if ( bl != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) {\r
1363                     bl_present = true;\r
1364                     if ( bl < getMinNotCollapseBlValue() ) {\r
1365                         to_be_removed.add( n );\r
1366                     }\r
1367                     if ( bl < min_bl ) {\r
1368                         min_bl = bl;\r
1369                     }\r
1370                 }\r
1371             }\r
1372         }\r
1373         if ( bl_present ) {\r
1374             for( final PhylogenyNode node : to_be_removed ) {\r
1375                 PhylogenyMethods.removeNode( node, phy );\r
1376             }\r
1377             if ( to_be_removed.size() > 0 ) {\r
1378                 phy.externalNodesHaveChanged();\r
1379                 phy.clearHashIdToNodeMap();\r
1380                 phy.recalculateNumberOfExternalDescendants( true );\r
1381                 getCurrentTreePanel().resetNodeIdToDistToLeafMap();\r
1382                 getCurrentTreePanel().updateSetOfCollapsedExternalNodes();\r
1383                 getCurrentTreePanel().calculateLongestExtNodeInfo();\r
1384                 getCurrentTreePanel().setNodeInPreorderToNull();\r
1385                 getCurrentTreePanel().recalculateMaxDistanceToRoot();\r
1386                 getCurrentTreePanel().resetPreferredSize();\r
1387                 getCurrentTreePanel().setEdited( true );\r
1388                 getCurrentTreePanel().repaint();\r
1389                 repaint();\r
1390             }\r
1391             if ( to_be_removed.size() > 0 ) {\r
1392                 JOptionPane.showMessageDialog( this, "Collapsed " + to_be_removed.size()\r
1393                         + " branches with\nbranch length values below " + getMinNotCollapseBlValue(), "Collapsed "\r
1394                         + to_be_removed.size() + " branches", JOptionPane.INFORMATION_MESSAGE );\r
1395             }\r
1396             else {\r
1397                 JOptionPane.showMessageDialog( this,\r
1398                                                "No branch collapsed,\nminimum branch length is " + min_bl,\r
1399                                                "No branch collapsed",\r
1400                                                JOptionPane.INFORMATION_MESSAGE );\r
1401             }\r
1402         }\r
1403         else {\r
1404             JOptionPane.showMessageDialog( this,\r
1405                                            "No branch collapsed because no branch length values present",\r
1406                                            "No branch length values present",\r
1407                                            JOptionPane.INFORMATION_MESSAGE );\r
1408         }\r
1409     }\r
1410 \r
1411     private PhyloXmlParser createPhyloXmlParser() {\r
1412         PhyloXmlParser xml_parser = null;\r
1413         if ( getConfiguration().isValidatePhyloXmlAgainstSchema() ) {\r
1414             try {\r
1415                 xml_parser = PhyloXmlParser.createPhyloXmlParserXsdValidating();\r
1416             }\r
1417             catch ( final Exception e ) {\r
1418                 JOptionPane.showMessageDialog( this,\r
1419                                                e.getLocalizedMessage(),\r
1420                                                "failed to create validating XML parser",\r
1421                                                JOptionPane.WARNING_MESSAGE );\r
1422             }\r
1423         }\r
1424         if ( xml_parser == null ) {\r
1425             xml_parser = PhyloXmlParser.createPhyloXmlParser();\r
1426         }\r
1427         return xml_parser;\r
1428     }\r
1429 \r
1430     public void end() {\r
1431         _mainpanel.terminate();\r
1432         _contentpane.removeAll();\r
1433         setVisible( false );\r
1434         dispose();\r
1435     }\r
1436 \r
1437     void executeLineageInference() {\r
1438         if ( ( _mainpanel.getCurrentPhylogeny() == null ) || ( _mainpanel.getCurrentPhylogeny().isEmpty() ) ) {\r
1439             return;\r
1440         }\r
1441         if ( !_mainpanel.getCurrentPhylogeny().isRooted() ) {\r
1442             JOptionPane.showMessageDialog( this,\r
1443                                            "Phylogeny is not rooted.",\r
1444                                            "Cannot infer ancestral taxonomies",\r
1445                                            JOptionPane.ERROR_MESSAGE );\r
1446             return;\r
1447         }\r
1448         final AncestralTaxonomyInferrer inferrer = new AncestralTaxonomyInferrer( this,\r
1449                                                                                   _mainpanel.getCurrentTreePanel(),\r
1450                                                                                   _mainpanel.getCurrentPhylogeny()\r
1451                                                                                           .copy() );\r
1452         new Thread( inferrer ).start();\r
1453     }\r
1454 \r
1455     private void executePhyleneticInference( final boolean from_unaligned_seqs ) {\r
1456         final PhyloInferenceDialog dialog = new PhyloInferenceDialog( this,\r
1457                                                                       getPhylogeneticInferenceOptions(),\r
1458                                                                       from_unaligned_seqs );\r
1459         dialog.activate();\r
1460         if ( dialog.getValue() == JOptionPane.OK_OPTION ) {\r
1461             if ( !from_unaligned_seqs ) {\r
1462                 if ( getMsa() != null ) {\r
1463                     final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getMsa(),\r
1464                                                                                     getPhylogeneticInferenceOptions()\r
1465                                                                                             .copy(), this );\r
1466                     new Thread( inferrer ).start();\r
1467                 }\r
1468                 else {\r
1469                     JOptionPane.showMessageDialog( this,\r
1470                                                    "No multiple sequence alignment selected",\r
1471                                                    "Phylogenetic Inference Not Launched",\r
1472                                                    JOptionPane.WARNING_MESSAGE );\r
1473                 }\r
1474             }\r
1475             else {\r
1476                 if ( getSeqs() != null ) {\r
1477                     final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getSeqs(),\r
1478                                                                                     getPhylogeneticInferenceOptions()\r
1479                                                                                             .copy(), this );\r
1480                     new Thread( inferrer ).start();\r
1481                 }\r
1482                 else {\r
1483                     JOptionPane.showMessageDialog( this,\r
1484                                                    "No input sequences selected",\r
1485                                                    "Phylogenetic Inference Not Launched",\r
1486                                                    JOptionPane.WARNING_MESSAGE );\r
1487                 }\r
1488             }\r
1489         }\r
1490     }\r
1491 \r
1492     void exit() {\r
1493         removeAllTextFrames();\r
1494         _mainpanel.terminate();\r
1495         _contentpane.removeAll();\r
1496         setVisible( false );\r
1497         dispose();\r
1498         // System.exit( 0 ); //TODO reconfirm that this is OK, then remove.\r
1499     }\r
1500 \r
1501     private void extractTaxDataFromNodeNames() throws PhyloXmlDataFormatException {\r
1502         final StringBuilder sb = new StringBuilder();\r
1503         final StringBuilder sb_failed = new StringBuilder();\r
1504         int counter = 0;\r
1505         int counter_failed = 0;\r
1506         if ( getCurrentTreePanel() != null ) {\r
1507             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
1508             if ( ( phy != null ) && !phy.isEmpty() ) {\r
1509                 final PhylogenyNodeIterator it = phy.iteratorExternalForward();\r
1510                 while ( it.hasNext() ) {\r
1511                     final PhylogenyNode n = it.next();\r
1512                     final String name = n.getName().trim();\r
1513                     if ( !ForesterUtil.isEmpty( name ) ) {\r
1514                         final String nt = ParserUtils.extractTaxonomyDataFromNodeName( n,\r
1515                                                                                        TAXONOMY_EXTRACTION.AGGRESSIVE );\r
1516                         if ( !ForesterUtil.isEmpty( nt ) ) {\r
1517                             if ( counter < 15 ) {\r
1518                                 sb.append( name + ": " + nt + "\n" );\r
1519                             }\r
1520                             else if ( counter == 15 ) {\r
1521                                 sb.append( "...\n" );\r
1522                             }\r
1523                             counter++;\r
1524                         }\r
1525                         else {\r
1526                             if ( counter_failed < 15 ) {\r
1527                                 sb_failed.append( name + "\n" );\r
1528                             }\r
1529                             else if ( counter_failed == 15 ) {\r
1530                                 sb_failed.append( "...\n" );\r
1531                             }\r
1532                             counter_failed++;\r
1533                         }\r
1534                     }\r
1535                 }\r
1536                 if ( counter > 0 ) {\r
1537                     String failed = "";\r
1538                     String all = "all ";\r
1539                     if ( counter_failed > 0 ) {\r
1540                         all = "";\r
1541                         failed = "\nCould not extract taxonomic data for " + counter_failed\r
1542                                 + " named external nodes:\n" + sb_failed;\r
1543                     }\r
1544                     JOptionPane.showMessageDialog( this,\r
1545                                                    "Extracted taxonomic data from " + all + counter\r
1546                                                            + " named external nodes:\n" + sb.toString() + failed,\r
1547                                                    "Taxonomic Data Extraction Completed",\r
1548                                                    counter_failed > 0 ? JOptionPane.WARNING_MESSAGE\r
1549                                                            : JOptionPane.INFORMATION_MESSAGE );\r
1550                 }\r
1551                 else {\r
1552                     JOptionPane\r
1553                             .showMessageDialog( this,\r
1554                                                 "Could not extract any taxonomic data.\nMaybe node names are empty\n"\r
1555                                                         + "or not in the forms \"XYZ_CAEEL\", \"XYZ_6239\", or \"XYZ_Caenorhabditis_elegans\"\n"\r
1556                                                         + "or nodes already have taxonomic data?\n",\r
1557                                                 "No Taxonomic Data Extracted",\r
1558                                                 JOptionPane.ERROR_MESSAGE );\r
1559                 }\r
1560             }\r
1561         }\r
1562     }\r
1563 \r
1564     @Override\r
1565     public MainPanel getMainPanel() {\r
1566         return _mainpanel;\r
1567     }\r
1568 \r
1569     private double getMinNotCollapseBlValue() {\r
1570         return _min_not_collapse_bl;\r
1571     }\r
1572 \r
1573     private double getMinNotCollapseConfidenceValue() {\r
1574         return _min_not_collapse;\r
1575     }\r
1576 \r
1577     public Msa getMsa() {\r
1578         return _msa;\r
1579     }\r
1580 \r
1581     public File getMsaFile() {\r
1582         return _msa_file;\r
1583     }\r
1584 \r
1585     private PhylogeneticInferenceOptions getPhylogeneticInferenceOptions() {\r
1586         if ( _phylogenetic_inference_options == null ) {\r
1587             _phylogenetic_inference_options = new PhylogeneticInferenceOptions();\r
1588         }\r
1589         return _phylogenetic_inference_options;\r
1590     }\r
1591 \r
1592     public List<MolecularSequence> getSeqs() {\r
1593         return _seqs;\r
1594     }\r
1595 \r
1596     public File getSeqsFile() {\r
1597         return _seqs_file;\r
1598     }\r
1599 \r
1600     private boolean isUnsavedDataPresent() {\r
1601         final List<TreePanel> tps = getMainPanel().getTreePanels();\r
1602         for( final TreePanel tp : tps ) {\r
1603             if ( tp.isEdited() ) {\r
1604                 return true;\r
1605             }\r
1606         }\r
1607         return false;\r
1608     }\r
1609 \r
1610     private void moveNodeNamesToSeqNames() throws PhyloXmlDataFormatException {\r
1611         if ( getCurrentTreePanel() != null ) {\r
1612             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
1613             if ( ( phy != null ) && !phy.isEmpty() ) {\r
1614                 PhylogenyMethods\r
1615                         .transferNodeNameToField( phy, PhylogenyMethods.PhylogenyNodeField.SEQUENCE_NAME, false );\r
1616             }\r
1617         }\r
1618     }\r
1619 \r
1620     private void moveNodeNamesToTaxSn() throws PhyloXmlDataFormatException {\r
1621         if ( getCurrentTreePanel() != null ) {\r
1622             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
1623             if ( ( phy != null ) && !phy.isEmpty() ) {\r
1624                 PhylogenyMethods.transferNodeNameToField( phy,\r
1625                                                           PhylogenyMethods.PhylogenyNodeField.TAXONOMY_SCIENTIFIC_NAME,\r
1626                                                           false );\r
1627             }\r
1628         }\r
1629     }\r
1630 \r
1631     private void newTree() {\r
1632         final Phylogeny[] phys = new Phylogeny[ 1 ];\r
1633         final Phylogeny phy = new Phylogeny();\r
1634         final PhylogenyNode node = new PhylogenyNode();\r
1635         phy.setRoot( node );\r
1636         phy.setRooted( true );\r
1637         phys[ 0 ] = phy;\r
1638         AptxUtil.addPhylogeniesToTabs( phys, "", "", getConfiguration(), getMainPanel() );\r
1639         _mainpanel.getControlPanel().showWhole();\r
1640         _mainpanel.getCurrentTreePanel().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );\r
1641         _mainpanel.getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );\r
1642         if ( getMainPanel().getMainFrame() == null ) {\r
1643             // Must be "E" applet version.\r
1644             ( ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet() )\r
1645                     .setSelectedTypeInTypeMenu( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );\r
1646         }\r
1647         else {\r
1648             getMainPanel().getMainFrame().setSelectedTypeInTypeMenu( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );\r
1649         }\r
1650         activateSaveAllIfNeeded();\r
1651         System.gc();\r
1652     }\r
1653 \r
1654     private void obtainDetailedTaxonomicInformation() {\r
1655         if ( getCurrentTreePanel() != null ) {\r
1656             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
1657             if ( ( phy != null ) && !phy.isEmpty() ) {\r
1658                 final TaxonomyDataManager t = new TaxonomyDataManager( this,\r
1659                                                                        _mainpanel.getCurrentTreePanel(),\r
1660                                                                        phy.copy(),\r
1661                                                                        false,\r
1662                                                                        true );\r
1663                 new Thread( t ).start();\r
1664             }\r
1665         }\r
1666     }\r
1667 \r
1668     private void obtainDetailedTaxonomicInformationDelete() {\r
1669         if ( getCurrentTreePanel() != null ) {\r
1670             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
1671             if ( ( phy != null ) && !phy.isEmpty() ) {\r
1672                 final TaxonomyDataManager t = new TaxonomyDataManager( this,\r
1673                                                                        _mainpanel.getCurrentTreePanel(),\r
1674                                                                        phy.copy(),\r
1675                                                                        true,\r
1676                                                                        true );\r
1677                 new Thread( t ).start();\r
1678             }\r
1679         }\r
1680     }\r
1681 \r
1682     private void obtainSequenceInformation() {\r
1683         if ( getCurrentTreePanel() != null ) {\r
1684             final Phylogeny phy = getCurrentTreePanel().getPhylogeny();\r
1685             if ( ( phy != null ) && !phy.isEmpty() ) {\r
1686                 final SequenceDataRetriver u = new SequenceDataRetriver( this,\r
1687                                                                          _mainpanel.getCurrentTreePanel(),\r
1688                                                                          phy.copy() );\r
1689                 new Thread( u ).start();\r
1690             }\r
1691         }\r
1692     }\r
1693 \r
1694     private void preProcessTreesUponReading( final Phylogeny[] phys ) {\r
1695         for( final Phylogeny phy : phys ) {\r
1696             if ( ( phy != null ) && !phy.isEmpty() ) {\r
1697                 for( final PhylogenyNodeIterator it = phy.iteratorPreorder(); it.hasNext(); ) {\r
1698                     final PhylogenyNode n = it.next();\r
1699                     if ( n.isExternal() ) {\r
1700                         if ( n.getNodeData().isHasSequence() ) {\r
1701                             final Sequence s = n.getNodeData().getSequence();\r
1702                             if ( ForesterUtil.isEmpty( s.getGeneName() ) || s.getGeneName().startsWith( "LOC" ) ) {\r
1703                                 if ( ( s.getAccession() != null )\r
1704                                         && !ForesterUtil.isEmpty( s.getAccession().getValue() ) ) {\r
1705                                     s.setGeneName( s.getAccession().getValue() );\r
1706                                 }\r
1707                                 else if ( !ForesterUtil.isEmpty( n.getName() ) ) {\r
1708                                     s.setGeneName( n.getName() );\r
1709                                 }\r
1710                             }\r
1711                         }\r
1712                     }\r
1713                 }\r
1714             }\r
1715         }\r
1716     }\r
1717 \r
1718    \r
1719 \r
1720     public void readMsaFromFile() {\r
1721         // Set an initial directory if none set yet\r
1722         final File my_dir = getCurrentDir();\r
1723         _msa_filechooser.setMultiSelectionEnabled( false );\r
1724         // Open file-open dialog and set current directory\r
1725         if ( my_dir != null ) {\r
1726             _msa_filechooser.setCurrentDirectory( my_dir );\r
1727         }\r
1728         final int result = _msa_filechooser.showOpenDialog( _contentpane );\r
1729         // All done: get the msa\r
1730         final File file = _msa_filechooser.getSelectedFile();\r
1731         setCurrentDir( _msa_filechooser.getCurrentDirectory() );\r
1732         if ( ( file != null ) && !file.isDirectory() && ( result == JFileChooser.APPROVE_OPTION ) ) {\r
1733             setMsaFile( null );\r
1734             setMsa( null );\r
1735             Msa msa = null;\r
1736             try {\r
1737                 final InputStream is = new FileInputStream( file );\r
1738                 if ( FastaParser.isLikelyFasta( file ) ) {\r
1739                     msa = FastaParser.parseMsa( is );\r
1740                 }\r
1741                 else {\r
1742                     msa = GeneralMsaParser.parse( is );\r
1743                 }\r
1744             }\r
1745             catch ( final MsaFormatException e ) {\r
1746                 setArrowCursor();\r
1747                 JOptionPane.showMessageDialog( this,\r
1748                                                e.getLocalizedMessage(),\r
1749                                                "Multiple sequence alignment format error",\r
1750                                                JOptionPane.ERROR_MESSAGE );\r
1751                 return;\r
1752             }\r
1753             catch ( final IOException e ) {\r
1754                 setArrowCursor();\r
1755                 JOptionPane.showMessageDialog( this,\r
1756                                                e.getLocalizedMessage(),\r
1757                                                "Failed to read multiple sequence alignment",\r
1758                                                JOptionPane.ERROR_MESSAGE );\r
1759                 return;\r
1760             }\r
1761             catch ( final IllegalArgumentException e ) {\r
1762                 setArrowCursor();\r
1763                 JOptionPane.showMessageDialog( this,\r
1764                                                e.getLocalizedMessage(),\r
1765                                                "Unexpected error during reading of multiple sequence alignment",\r
1766                                                JOptionPane.ERROR_MESSAGE );\r
1767                 return;\r
1768             }\r
1769             catch ( final Exception e ) {\r
1770                 setArrowCursor();\r
1771                 e.printStackTrace();\r
1772                 JOptionPane.showMessageDialog( this,\r
1773                                                e.getLocalizedMessage(),\r
1774                                                "Unexpected error during reading of multiple sequence alignment",\r
1775                                                JOptionPane.ERROR_MESSAGE );\r
1776                 return;\r
1777             }\r
1778             if ( ( msa == null ) || ( msa.getNumberOfSequences() < 1 ) ) {\r
1779                 JOptionPane.showMessageDialog( this,\r
1780                                                "Multiple sequence alignment is empty",\r
1781                                                "Illegal Multiple Sequence Alignment",\r
1782                                                JOptionPane.ERROR_MESSAGE );\r
1783                 return;\r
1784             }\r
1785             if ( msa.getNumberOfSequences() < 4 ) {\r
1786                 JOptionPane.showMessageDialog( this,\r
1787                                                "Multiple sequence alignment needs to contain at least 3 sequences",\r
1788                                                "Illegal multiple sequence alignment",\r
1789                                                JOptionPane.ERROR_MESSAGE );\r
1790                 return;\r
1791             }\r
1792             if ( msa.getLength() < 2 ) {\r
1793                 JOptionPane.showMessageDialog( this,\r
1794                                                "Multiple sequence alignment needs to contain at least 2 residues",\r
1795                                                "Illegal multiple sequence alignment",\r
1796                                                JOptionPane.ERROR_MESSAGE );\r
1797                 return;\r
1798             }\r
1799             System.gc();\r
1800             setMsaFile( _msa_filechooser.getSelectedFile() );\r
1801             setMsa( msa );\r
1802         }\r
1803     }\r
1804 \r
1805     private void readPhylogeniesFromFile() {\r
1806         boolean exception = false;\r
1807         Phylogeny[] phys = null;\r
1808         // Set an initial directory if none set yet\r
1809         final File my_dir = getCurrentDir();\r
1810         _open_filechooser.setMultiSelectionEnabled( true );\r
1811         // Open file-open dialog and set current directory\r
1812         if ( my_dir != null ) {\r
1813             _open_filechooser.setCurrentDirectory( my_dir );\r
1814         }\r
1815         final int result = _open_filechooser.showOpenDialog( _contentpane );\r
1816         // All done: get the file\r
1817         final File[] files = _open_filechooser.getSelectedFiles();\r
1818         setCurrentDir( _open_filechooser.getCurrentDirectory() );\r
1819         boolean nhx_or_nexus = false;\r
1820         if ( ( files != null ) && ( files.length > 0 ) && ( result == JFileChooser.APPROVE_OPTION ) ) {\r
1821             for( final File file : files ) {\r
1822                 if ( ( file != null ) && !file.isDirectory() ) {\r
1823                     if ( _mainpanel.getCurrentTreePanel() != null ) {\r
1824                         _mainpanel.getCurrentTreePanel().setWaitCursor();\r
1825                     }\r
1826                     else {\r
1827                         _mainpanel.setWaitCursor();\r
1828                     }\r
1829                     if ( ( _open_filechooser.getFileFilter() == MainFrame.nhfilter )\r
1830                             || ( _open_filechooser.getFileFilter() == MainFrame.nhxfilter ) ) {\r
1831                         try {\r
1832                             final NHXParser nhx = new NHXParser();\r
1833                             setSpecialOptionsForNhxParser( nhx );\r
1834                             phys = PhylogenyMethods.readPhylogenies( nhx, file );\r
1835                             nhx_or_nexus = true;\r
1836                         }\r
1837                         catch ( final Exception e ) {\r
1838                             exception = true;\r
1839                             exceptionOccuredDuringOpenFile( e );\r
1840                         }\r
1841                     }\r
1842                     else if ( _open_filechooser.getFileFilter() == MainFrame.xmlfilter ) {\r
1843                         warnIfNotPhyloXmlValidation( getConfiguration() );\r
1844                         try {\r
1845                             final PhyloXmlParser xml_parser = createPhyloXmlParser();\r
1846                             phys = PhylogenyMethods.readPhylogenies( xml_parser, file );\r
1847                         }\r
1848                         catch ( final Exception e ) {\r
1849                             exception = true;\r
1850                             exceptionOccuredDuringOpenFile( e );\r
1851                         }\r
1852                     }\r
1853                     else if ( _open_filechooser.getFileFilter() == MainFrame.tolfilter ) {\r
1854                         try {\r
1855                             phys = PhylogenyMethods.readPhylogenies( new TolParser(), file );\r
1856                         }\r
1857                         catch ( final Exception e ) {\r
1858                             exception = true;\r
1859                             exceptionOccuredDuringOpenFile( e );\r
1860                         }\r
1861                     }\r
1862                     else if ( _open_filechooser.getFileFilter() == MainFrame.nexusfilter ) {\r
1863                         try {\r
1864                             final NexusPhylogeniesParser nex = new NexusPhylogeniesParser();\r
1865                             setSpecialOptionsForNexParser( nex );\r
1866                             phys = PhylogenyMethods.readPhylogenies( nex, file );\r
1867                             nhx_or_nexus = true;\r
1868                         }\r
1869                         catch ( final Exception e ) {\r
1870                             exception = true;\r
1871                             exceptionOccuredDuringOpenFile( e );\r
1872                         }\r
1873                     }\r
1874                     // "*.*":\r
1875                     else {\r
1876                         try {\r
1877                             final PhylogenyParser parser = ParserUtils\r
1878                                     .createParserDependingOnFileType( file, getConfiguration()\r
1879                                             .isValidatePhyloXmlAgainstSchema() );\r
1880                             if ( parser instanceof NexusPhylogeniesParser ) {\r
1881                                 final NexusPhylogeniesParser nex = ( NexusPhylogeniesParser ) parser;\r
1882                                 setSpecialOptionsForNexParser( nex );\r
1883                                 nhx_or_nexus = true;\r
1884                             }\r
1885                             else if ( parser instanceof NHXParser ) {\r
1886                                 final NHXParser nhx = ( NHXParser ) parser;\r
1887                                 setSpecialOptionsForNhxParser( nhx );\r
1888                                 nhx_or_nexus = true;\r
1889                             }\r
1890                             else if ( parser instanceof PhyloXmlParser ) {\r
1891                                 warnIfNotPhyloXmlValidation( getConfiguration() );\r
1892                             }\r
1893                             phys = PhylogenyMethods.readPhylogenies( parser, file );\r
1894                         }\r
1895                         catch ( final Exception e ) {\r
1896                             exception = true;\r
1897                             exceptionOccuredDuringOpenFile( e );\r
1898                         }\r
1899                     }\r
1900                     if ( _mainpanel.getCurrentTreePanel() != null ) {\r
1901                         _mainpanel.getCurrentTreePanel().setArrowCursor();\r
1902                     }\r
1903                     else {\r
1904                         _mainpanel.setArrowCursor();\r
1905                     }\r
1906                     if ( !exception && ( phys != null ) && ( phys.length > 0 ) ) {\r
1907                         boolean one_desc = false;\r
1908                         if ( nhx_or_nexus ) {\r
1909                             for( final Phylogeny phy : phys ) {\r
1910                                 if ( getOptions().isInternalNumberAreConfidenceForNhParsing() ) {\r
1911                                     PhylogenyMethods.transferInternalNodeNamesToConfidence( phy, "" );\r
1912                                 }\r
1913                                 if ( PhylogenyMethods.getMinimumDescendentsPerInternalNodes( phy ) == 1 ) {\r
1914                                     one_desc = true;\r
1915                                     break;\r
1916                                 }\r
1917                             }\r
1918                         }\r
1919                         if ( PREPROCESS_TREES ) {\r
1920                             preProcessTreesUponReading( phys );\r
1921                         }\r
1922                         AptxUtil.addPhylogeniesToTabs( phys,\r
1923                                                        file.getName(),\r
1924                                                        file.getAbsolutePath(),\r
1925                                                        getConfiguration(),\r
1926                                                        getMainPanel() );\r
1927                         _mainpanel.getControlPanel().showWhole();\r
1928                         if ( nhx_or_nexus && one_desc ) {\r
1929                             JOptionPane\r
1930                                     .showMessageDialog( this,\r
1931                                                         "One or more trees contain (a) node(s) with one descendant, "\r
1932                                                                 + ForesterUtil.LINE_SEPARATOR\r
1933                                                                 + "possibly indicating illegal parentheses within node names.",\r
1934                                                         "Warning: Possible Error in New Hampshire Formatted Data",\r
1935                                                         JOptionPane.WARNING_MESSAGE );\r
1936                         }\r
1937                     }\r
1938                 }\r
1939             }\r
1940         }\r
1941         activateSaveAllIfNeeded();\r
1942         System.gc();\r
1943     }\r
1944 \r
1945     void readPhylogeniesFromURL() {\r
1946         URL url = null;\r
1947         Phylogeny[] phys = null;\r
1948         final String message = "Please enter a complete URL, for example \"http://purl.org/phylo/treebase/phylows/study/TB2:S15480?format=nexus\"";\r
1949         final String url_string = JOptionPane.showInputDialog( this,\r
1950                                                                message,\r
1951                                                                "Use URL/webservice to obtain a phylogeny",\r
1952                                                                JOptionPane.QUESTION_MESSAGE );\r
1953         boolean nhx_or_nexus = false;\r
1954         if ( ( url_string != null ) && ( url_string.length() > 0 ) ) {\r
1955             try {\r
1956                 url = new URL( url_string );\r
1957                 PhylogenyParser parser = null;\r
1958                 if ( url.getHost().toLowerCase().indexOf( "tolweb" ) >= 0 ) {\r
1959                     parser = new TolParser();\r
1960                 }\r
1961                 else {\r
1962                     parser = ParserUtils.createParserDependingOnUrlContents( url, getConfiguration()\r
1963                             .isValidatePhyloXmlAgainstSchema() );\r
1964                 }\r
1965                 if ( parser instanceof NexusPhylogeniesParser ) {\r
1966                     nhx_or_nexus = true;\r
1967                 }\r
1968                 else if ( parser instanceof NHXParser ) {\r
1969                     nhx_or_nexus = true;\r
1970                 }\r
1971                 if ( _mainpanel.getCurrentTreePanel() != null ) {\r
1972                     _mainpanel.getCurrentTreePanel().setWaitCursor();\r
1973                 }\r
1974                 else {\r
1975                     _mainpanel.setWaitCursor();\r
1976                 }\r
1977                 final PhylogenyFactory factory = ParserBasedPhylogenyFactory.getInstance();\r
1978                 phys = factory.create( url.openStream(), parser );\r
1979             }\r
1980             catch ( final MalformedURLException e ) {\r
1981                 JOptionPane.showMessageDialog( this,\r
1982                                                "Malformed URL: " + url + "\n" + e.getLocalizedMessage(),\r
1983                                                "Malformed URL",\r
1984                                                JOptionPane.ERROR_MESSAGE );\r
1985             }\r
1986             catch ( final IOException e ) {\r
1987                 JOptionPane.showMessageDialog( this,\r
1988                                                "Could not read from " + url + "\n"\r
1989                                                        + ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ),\r
1990                                                "Failed to read URL",\r
1991                                                JOptionPane.ERROR_MESSAGE );\r
1992             }\r
1993             catch ( final Exception e ) {\r
1994                 JOptionPane.showMessageDialog( this,\r
1995                                                ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ),\r
1996                                                "Unexpected Exception",\r
1997                                                JOptionPane.ERROR_MESSAGE );\r
1998             }\r
1999             finally {\r
2000                 if ( _mainpanel.getCurrentTreePanel() != null ) {\r
2001                     _mainpanel.getCurrentTreePanel().setArrowCursor();\r
2002                 }\r
2003                 else {\r
2004                     _mainpanel.setArrowCursor();\r
2005                 }\r
2006             }\r
2007             if ( ( phys != null ) && ( phys.length > 0 ) ) {\r
2008                 if ( nhx_or_nexus && getOptions().isInternalNumberAreConfidenceForNhParsing() ) {\r
2009                     for( final Phylogeny phy : phys ) {\r
2010                         PhylogenyMethods.transferInternalNodeNamesToConfidence( phy, "" );\r
2011                     }\r
2012                 }\r
2013                 AptxUtil.addPhylogeniesToTabs( phys,\r
2014                                                new File( url.getFile() ).getName(),\r
2015                                                new File( url.getFile() ).toString(),\r
2016                                                getConfiguration(),\r
2017                                                getMainPanel() );\r
2018                 _mainpanel.getControlPanel().showWhole();\r
2019             }\r
2020         }\r
2021         activateSaveAllIfNeeded();\r
2022         System.gc();\r
2023     }\r
2024 \r
2025     public void readSeqsFromFileforPI() {\r
2026         // Set an initial directory if none set yet\r
2027         final File my_dir = getCurrentDir();\r
2028         _seqs_pi_filechooser.setMultiSelectionEnabled( false );\r
2029         // Open file-open dialog and set current directory\r
2030         if ( my_dir != null ) {\r
2031             _seqs_pi_filechooser.setCurrentDirectory( my_dir );\r
2032         }\r
2033         final int result = _seqs_pi_filechooser.showOpenDialog( _contentpane );\r
2034         // All done: get the seqs\r
2035         final File file = _seqs_pi_filechooser.getSelectedFile();\r
2036         setCurrentDir( _seqs_pi_filechooser.getCurrentDirectory() );\r
2037         if ( ( file != null ) && !file.isDirectory() && ( result == JFileChooser.APPROVE_OPTION ) ) {\r
2038             setSeqsFile( null );\r
2039             setSeqs( null );\r
2040             List<MolecularSequence> seqs = null;\r
2041             try {\r
2042                 if ( FastaParser.isLikelyFasta( new FileInputStream( file ) ) ) {\r
2043                     seqs = FastaParser.parse( new FileInputStream( file ) );\r
2044                     for( final MolecularSequence seq : seqs ) {\r
2045                         System.out.println( SequenceWriter.toFasta( seq, 60 ) );\r
2046                     }\r
2047                 }\r
2048                 else {\r
2049                     //TODO error\r
2050                 }\r
2051             }\r
2052             catch ( final MsaFormatException e ) {\r
2053                 setArrowCursor();\r
2054                 JOptionPane.showMessageDialog( this,\r
2055                                                e.getLocalizedMessage(),\r
2056                                                "Multiple sequence file format error",\r
2057                                                JOptionPane.ERROR_MESSAGE );\r
2058                 return;\r
2059             }\r
2060             catch ( final IOException e ) {\r
2061                 setArrowCursor();\r
2062                 JOptionPane.showMessageDialog( this,\r
2063                                                e.getLocalizedMessage(),\r
2064                                                "Failed to read multiple sequence file",\r
2065                                                JOptionPane.ERROR_MESSAGE );\r
2066                 return;\r
2067             }\r
2068             catch ( final IllegalArgumentException e ) {\r
2069                 setArrowCursor();\r
2070                 JOptionPane.showMessageDialog( this,\r
2071                                                e.getLocalizedMessage(),\r
2072                                                "Unexpected error during reading of multiple sequence file",\r
2073                                                JOptionPane.ERROR_MESSAGE );\r
2074                 return;\r
2075             }\r
2076             catch ( final Exception e ) {\r
2077                 setArrowCursor();\r
2078                 e.printStackTrace();\r
2079                 JOptionPane.showMessageDialog( this,\r
2080                                                e.getLocalizedMessage(),\r
2081                                                "Unexpected error during reading of multiple sequence file",\r
2082                                                JOptionPane.ERROR_MESSAGE );\r
2083                 return;\r
2084             }\r
2085             if ( ( seqs == null ) || ( seqs.size() < 1 ) ) {\r
2086                 JOptionPane.showMessageDialog( this,\r
2087                                                "Multiple sequence file is empty",\r
2088                                                "Illegal multiple sequence file",\r
2089                                                JOptionPane.ERROR_MESSAGE );\r
2090                 return;\r
2091             }\r
2092             if ( seqs.size() < 4 ) {\r
2093                 JOptionPane.showMessageDialog( this,\r
2094                                                "Multiple sequence file needs to contain at least 3 sequences",\r
2095                                                "Illegal multiple sequence file",\r
2096                                                JOptionPane.ERROR_MESSAGE );\r
2097                 return;\r
2098             }\r
2099             //  if ( msa.getLength() < 2 ) {\r
2100             //       JOptionPane.showMessageDialog( this,\r
2101             //                                      "Multiple sequence alignment needs to contain at least 2 residues",\r
2102             //                                      "Illegal multiple sequence file",\r
2103             //                                      JOptionPane.ERROR_MESSAGE );\r
2104             //       return;\r
2105             //   }\r
2106             System.gc();\r
2107             setSeqsFile( _seqs_pi_filechooser.getSelectedFile() );\r
2108             setSeqs( seqs );\r
2109         }\r
2110     }\r
2111 \r
2112     private void readSpeciesTreeFromFile() {\r
2113         Phylogeny t = null;\r
2114         boolean exception = false;\r
2115         final File my_dir = getCurrentDir();\r
2116         _open_filechooser_for_species_tree.setSelectedFile( new File( "" ) );\r
2117         if ( my_dir != null ) {\r
2118             _open_filechooser_for_species_tree.setCurrentDirectory( my_dir );\r
2119         }\r
2120         final int result = _open_filechooser_for_species_tree.showOpenDialog( _contentpane );\r
2121         final File file = _open_filechooser_for_species_tree.getSelectedFile();\r
2122         if ( ( file != null ) && ( result == JFileChooser.APPROVE_OPTION ) ) {\r
2123             if ( _open_filechooser_for_species_tree.getFileFilter() == MainFrame.xmlfilter ) {\r
2124                 try {\r
2125                     final Phylogeny[] trees = PhylogenyMethods.readPhylogenies( PhyloXmlParser\r
2126                             .createPhyloXmlParserXsdValidating(), file );\r
2127                     t = trees[ 0 ];\r
2128                 }\r
2129                 catch ( final Exception e ) {\r
2130                     exception = true;\r
2131                     exceptionOccuredDuringOpenFile( e );\r
2132                 }\r
2133             }\r
2134             else if ( _open_filechooser_for_species_tree.getFileFilter() == MainFrame.tolfilter ) {\r
2135                 try {\r
2136                     final Phylogeny[] trees = PhylogenyMethods.readPhylogenies( new TolParser(), file );\r
2137                     t = trees[ 0 ];\r
2138                 }\r
2139                 catch ( final Exception e ) {\r
2140                     exception = true;\r
2141                     exceptionOccuredDuringOpenFile( e );\r
2142                 }\r
2143             }\r
2144             // "*.*":\r
2145             else {\r
2146                 try {\r
2147                     final Phylogeny[] trees = PhylogenyMethods.readPhylogenies( PhyloXmlParser\r
2148                             .createPhyloXmlParserXsdValidating(), file );\r
2149                     t = trees[ 0 ];\r
2150                 }\r
2151                 catch ( final Exception e ) {\r
2152                     exception = true;\r
2153                     exceptionOccuredDuringOpenFile( e );\r
2154                 }\r
2155             }\r
2156             if ( !exception && ( t != null ) && !t.isRooted() ) {\r
2157                 exception = true;\r
2158                 t = null;\r
2159                 JOptionPane.showMessageDialog( this,\r
2160                                                "Species tree is not rooted",\r
2161                                                "Species tree not loaded",\r
2162                                                JOptionPane.ERROR_MESSAGE );\r
2163             }\r
2164             if ( !exception && ( t != null ) ) {\r
2165                 final Set<Taxonomy> tax_set = new HashSet<Taxonomy>();\r
2166                 for( final PhylogenyNodeIterator it = t.iteratorExternalForward(); it.hasNext(); ) {\r
2167                     final PhylogenyNode node = it.next();\r
2168                     if ( !node.getNodeData().isHasTaxonomy() ) {\r
2169                         exception = true;\r
2170                         t = null;\r
2171                         JOptionPane\r
2172                                 .showMessageDialog( this,\r
2173                                                     "Species tree contains external node(s) without taxonomy information",\r
2174                                                     "Species tree not loaded",\r
2175                                                     JOptionPane.ERROR_MESSAGE );\r
2176                         break;\r
2177                     }\r
2178                     else {\r
2179                         if ( tax_set.contains( node.getNodeData().getTaxonomy() ) ) {\r
2180                             exception = true;\r
2181                             t = null;\r
2182                             JOptionPane.showMessageDialog( this,\r
2183                                                            "Taxonomy ["\r
2184                                                                    + node.getNodeData().getTaxonomy().asSimpleText()\r
2185                                                                    + "] is not unique in species tree",\r
2186                                                            "Species tree not loaded",\r
2187                                                            JOptionPane.ERROR_MESSAGE );\r
2188                             break;\r
2189                         }\r
2190                         else {\r
2191                             tax_set.add( node.getNodeData().getTaxonomy() );\r
2192                         }\r
2193                     }\r
2194                 }\r
2195             }\r
2196             if ( !exception && ( t != null ) ) {\r
2197                 setSpeciesTree( t );\r
2198                 JOptionPane.showMessageDialog( this,\r
2199                                                "Species tree successfully loaded",\r
2200                                                "Species tree loaded",\r
2201                                                JOptionPane.INFORMATION_MESSAGE );\r
2202             }\r
2203             _contentpane.repaint();\r
2204             System.gc();\r
2205         }\r
2206     }\r
2207 \r
2208     private void setArrowCursor() {\r
2209         try {\r
2210             _mainpanel.getCurrentTreePanel().setArrowCursor();\r
2211         }\r
2212         catch ( final Exception ex ) {\r
2213             // Do nothing.\r
2214         }\r
2215     }\r
2216 \r
2217     private void setMinNotCollapseBlValue( final double min_not_collapse_bl ) {\r
2218         _min_not_collapse_bl = min_not_collapse_bl;\r
2219     }\r
2220 \r
2221     private void setMinNotCollapseConfidenceValue( final double min_not_collapse ) {\r
2222         _min_not_collapse = min_not_collapse;\r
2223     }\r
2224 \r
2225     void setMsa( final Msa msa ) {\r
2226         _msa = msa;\r
2227     }\r
2228 \r
2229     void setMsaFile( final File msa_file ) {\r
2230         _msa_file = msa_file;\r
2231     }\r
2232 \r
2233     private void setPhylogeneticInferenceOptions( final PhylogeneticInferenceOptions phylogenetic_inference_options ) {\r
2234         _phylogenetic_inference_options = phylogenetic_inference_options;\r
2235     }\r
2236 \r
2237     void setSeqs( final List<MolecularSequence> seqs ) {\r
2238         _seqs = seqs;\r
2239     }\r
2240 \r
2241     void setSeqsFile( final File seqs_file ) {\r
2242         _seqs_file = seqs_file;\r
2243     }\r
2244 \r
2245     private void setSpecialOptionsForNexParser( final NexusPhylogeniesParser nex ) {\r
2246         nex.setReplaceUnderscores( getOptions().isReplaceUnderscoresInNhParsing() );\r
2247         nex.setTaxonomyExtraction( getOptions().getTaxonomyExtraction() );\r
2248     }\r
2249 \r
2250     private void setSpecialOptionsForNhxParser( final NHXParser nhx ) {\r
2251         nhx.setReplaceUnderscores( getOptions().isReplaceUnderscoresInNhParsing() );\r
2252         nhx.setTaxonomyExtraction( getOptions().getTaxonomyExtraction() );\r
2253         nhx.setAllowErrorsInDistanceToParent( getOptions().isAllowErrorsInDistanceToParent() );\r
2254     }\r
2255 \r
2256    \r
2257 } // MainFrameApplication.\r