2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
5 // Copyright (C) 2008-2009 Christian M. Zmasek
6 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
7 // Copyright (C) 2003-2007 Ethalinda K.S. Cannon
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 // Contact: phylosoft @ gmail . com
25 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
27 package org.forester.archaeopteryx;
29 import java.awt.BorderLayout;
31 import java.awt.event.ActionEvent;
32 import java.awt.event.ComponentAdapter;
33 import java.awt.event.ComponentEvent;
34 import java.awt.event.WindowAdapter;
35 import java.awt.event.WindowEvent;
37 import java.io.FileInputStream;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.net.MalformedURLException;
42 import java.util.ArrayList;
43 import java.util.HashSet;
44 import java.util.List;
47 import javax.swing.ButtonGroup;
48 import javax.swing.JCheckBoxMenuItem;
49 import javax.swing.JFileChooser;
50 import javax.swing.JMenu;
51 import javax.swing.JMenuBar;
52 import javax.swing.JMenuItem;
53 import javax.swing.JOptionPane;
54 import javax.swing.JRadioButtonMenuItem;
55 import javax.swing.UIManager;
56 import javax.swing.UnsupportedLookAndFeelException;
57 import javax.swing.WindowConstants;
58 import javax.swing.event.ChangeEvent;
59 import javax.swing.event.ChangeListener;
61 import org.forester.analysis.TaxonomyDataManager;
62 import org.forester.archaeopteryx.Options.CLADOGRAM_TYPE;
63 import org.forester.archaeopteryx.Options.NODE_LABEL_DIRECTION;
64 import org.forester.archaeopteryx.Options.PHYLOGENY_GRAPHICS_TYPE;
65 import org.forester.archaeopteryx.tools.InferenceManager;
66 import org.forester.archaeopteryx.tools.PhyloInferenceDialog;
67 import org.forester.archaeopteryx.tools.PhylogeneticInferenceOptions;
68 import org.forester.archaeopteryx.tools.PhylogeneticInferrer;
69 import org.forester.archaeopteryx.tools.SequenceDataRetriver;
70 import org.forester.archaeopteryx.webservices.PhylogeniesWebserviceClient;
71 import org.forester.archaeopteryx.webservices.WebservicesManager;
72 import org.forester.io.parsers.FastaParser;
73 import org.forester.io.parsers.GeneralMsaParser;
74 import org.forester.io.parsers.PhylogenyParser;
75 import org.forester.io.parsers.nexus.NexusPhylogeniesParser;
76 import org.forester.io.parsers.nhx.NHXParser;
77 import org.forester.io.parsers.nhx.NHXParser.TAXONOMY_EXTRACTION;
78 import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException;
79 import org.forester.io.parsers.phyloxml.PhyloXmlParser;
80 import org.forester.io.parsers.phyloxml.PhyloXmlUtil;
81 import org.forester.io.parsers.tol.TolParser;
82 import org.forester.io.parsers.util.ParserUtils;
83 import org.forester.io.writers.SequenceWriter;
84 import org.forester.msa.Msa;
85 import org.forester.msa.MsaFormatException;
86 import org.forester.phylogeny.Phylogeny;
87 import org.forester.phylogeny.PhylogenyMethods;
88 import org.forester.phylogeny.PhylogenyNode;
89 import org.forester.phylogeny.PhylogenyNode.NH_CONVERSION_SUPPORT_VALUE_STYLE;
90 import org.forester.phylogeny.data.Confidence;
91 import org.forester.phylogeny.data.PhylogenyDataUtil;
92 import org.forester.phylogeny.data.Sequence;
93 import org.forester.phylogeny.data.Taxonomy;
94 import org.forester.phylogeny.factories.ParserBasedPhylogenyFactory;
95 import org.forester.phylogeny.factories.PhylogenyFactory;
96 import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
97 import org.forester.sequence.MolecularSequence;
98 import org.forester.util.BasicDescriptiveStatistics;
99 import org.forester.util.BasicTable;
100 import org.forester.util.BasicTableParser;
101 import org.forester.util.DescriptiveStatistics;
102 import org.forester.util.ForesterUtil;
104 public final class MainFrameApplication extends MainFrame {
106 private final static int FRAME_X_SIZE = 900;
107 private final static int FRAME_Y_SIZE = 900;
108 // Filters for the file-open dialog (classes defined in this file)
109 private static final long serialVersionUID = -799735726778865234L;
110 private static final boolean PREPROCESS_TREES = false;
111 private final JFileChooser _values_filechooser;
112 private final JFileChooser _sequences_filechooser;
113 private final JFileChooser _open_filechooser;
114 private final JFileChooser _msa_filechooser;
115 private final JFileChooser _seqs_pi_filechooser;
116 private final JFileChooser _open_filechooser_for_species_tree;
117 // Application-only print menu items
118 private JMenuItem _collapse_below_threshold;
119 private JMenuItem _collapse_below_branch_length;
120 private ButtonGroup _radio_group_1;
121 private ButtonGroup _radio_group_2;
123 double _min_not_collapse = AptxConstants.MIN_NOT_COLLAPSE_DEFAULT;
124 double _min_not_collapse_bl = 0.001;
125 // Phylogeny Inference menu
126 private JMenu _inference_menu;
127 private JMenuItem _inference_from_msa_item;
128 private JMenuItem _inference_from_seqs_item;
129 // Phylogeny Inference
130 private PhylogeneticInferenceOptions _phylogenetic_inference_options = null;
131 private Msa _msa = null;
132 private File _msa_file = null;
133 private List<MolecularSequence> _seqs = null;
134 private File _seqs_file = null;
135 JMenuItem _read_values_jmi;
136 JMenuItem _read_seqs_jmi;
138 private MainFrameApplication( final Phylogeny[] phys, final Configuration config ) {
139 _configuration = config;
140 if ( _configuration == null ) {
141 throw new IllegalArgumentException( "configuration is null" );
144 setOptions( Options.createInstance( _configuration ) );
145 _mainpanel = new MainPanel( _configuration, this );
146 _open_filechooser = null;
147 _open_filechooser_for_species_tree = null;
148 _save_filechooser = null;
149 _writetopdf_filechooser = null;
150 _writetographics_filechooser = null;
151 _msa_filechooser = null;
152 _seqs_pi_filechooser = null;
153 _values_filechooser = null;
154 _sequences_filechooser = null;
155 _jmenubar = new JMenuBar();
158 _contentpane = getContentPane();
159 _contentpane.setLayout( new BorderLayout() );
160 _contentpane.add( _mainpanel, BorderLayout.CENTER );
162 setSize( MainFrameApplication.FRAME_X_SIZE, MainFrameApplication.FRAME_Y_SIZE );
163 // The window listener
164 setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );
165 addWindowListener( new WindowAdapter() {
168 public void windowClosing( final WindowEvent e ) {
172 // setVisible( true );
173 if ( ( phys != null ) && ( phys.length > 0 ) ) {
174 AptxUtil.addPhylogeniesToTabs( phys, "", null, _configuration, _mainpanel );
176 getMainPanel().getControlPanel().showWholeAll();
177 getMainPanel().getControlPanel().showWhole();
179 //activateSaveAllIfNeeded();
180 // ...and its children
181 _contentpane.repaint();
184 private MainFrameApplication( final Phylogeny[] phys, final Configuration config, final String title ) {
185 this( phys, config, title, null );
188 private MainFrameApplication( final Phylogeny[] phys,
189 final Configuration config,
191 final File current_dir ) {
193 _configuration = config;
194 if ( _configuration == null ) {
195 throw new IllegalArgumentException( "configuration is null" );
198 if ( _configuration.isUseNativeUI() ) {
199 UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
202 UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName() );
205 catch ( final UnsupportedLookAndFeelException e ) {
206 AptxUtil.dieWithSystemError( "unsupported look and feel: " + e.toString() );
208 catch ( final ClassNotFoundException e ) {
209 AptxUtil.dieWithSystemError( "class not found exception: " + e.toString() );
211 catch ( final InstantiationException e ) {
212 AptxUtil.dieWithSystemError( "instantiation exception: " + e.toString() );
214 catch ( final IllegalAccessException e ) {
215 AptxUtil.dieWithSystemError( "illegal access exception: " + e.toString() );
217 if ( ( current_dir != null ) && current_dir.canRead() && current_dir.isDirectory() ) {
218 setCurrentDir( current_dir );
220 // hide until everything is ready
222 setOptions( Options.createInstance( _configuration ) );
223 setInferenceManager( InferenceManager.createInstance( _configuration ) );
224 setPhylogeneticInferenceOptions( PhylogeneticInferenceOptions.createInstance( _configuration ) );
226 setTitle( AptxConstants.PRG_NAME + " " + AptxConstants.VERSION + " (" + AptxConstants.PRG_DATE + ")" );
227 _mainpanel = new MainPanel( _configuration, this );
229 _open_filechooser = new JFileChooser();
230 _open_filechooser.setMultiSelectionEnabled( true );
231 _open_filechooser.addChoosableFileFilter( MainFrame.xmlfilter );
232 _open_filechooser.addChoosableFileFilter( MainFrame.nhxfilter );
233 _open_filechooser.addChoosableFileFilter( MainFrame.nhfilter );
234 _open_filechooser.addChoosableFileFilter( MainFrame.nexusfilter );
235 _open_filechooser.addChoosableFileFilter( MainFrame.tolfilter );
236 _open_filechooser.addChoosableFileFilter( _open_filechooser.getAcceptAllFileFilter() );
237 _open_filechooser.setFileFilter( MainFrame.defaultfilter );
238 _open_filechooser_for_species_tree = new JFileChooser();
239 _open_filechooser_for_species_tree.setMultiSelectionEnabled( false );
240 _open_filechooser_for_species_tree.addChoosableFileFilter( MainFrame.xmlfilter );
241 _open_filechooser_for_species_tree.addChoosableFileFilter( MainFrame.tolfilter );
242 _open_filechooser_for_species_tree.setFileFilter( MainFrame.xmlfilter );
244 _msa_filechooser = new JFileChooser();
245 _msa_filechooser.setName( "Read Multiple Sequence Alignment File" );
246 _msa_filechooser.setMultiSelectionEnabled( false );
247 _msa_filechooser.addChoosableFileFilter( _msa_filechooser.getAcceptAllFileFilter() );
248 _msa_filechooser.addChoosableFileFilter( MainFrame.msafilter );
250 _seqs_pi_filechooser = new JFileChooser();
251 _seqs_pi_filechooser.setName( "Read Sequences File" );
252 _seqs_pi_filechooser.setMultiSelectionEnabled( false );
253 _seqs_pi_filechooser.addChoosableFileFilter( _seqs_pi_filechooser.getAcceptAllFileFilter() );
254 _seqs_pi_filechooser.addChoosableFileFilter( MainFrame.seqsfilter );
256 _values_filechooser = new JFileChooser();
257 _values_filechooser.setMultiSelectionEnabled( false );
259 _sequences_filechooser = new JFileChooser();
260 _sequences_filechooser.setMultiSelectionEnabled( false );
262 final String home_dir = System.getProperty( "user.home" );
263 _open_filechooser.setCurrentDirectory( new File( home_dir ) );
264 _open_filechooser_for_species_tree.setCurrentDirectory( new File( home_dir ) );
265 _msa_filechooser.setCurrentDirectory( new File( home_dir ) );
266 _seqs_pi_filechooser.setCurrentDirectory( new File( home_dir ) );
267 _values_filechooser.setCurrentDirectory( new File( home_dir ) );
268 _sequences_filechooser.setCurrentDirectory( new File( home_dir ) );
270 catch ( final Exception e ) {
272 // Do nothing. Not important.
274 // build the menu bar
275 _jmenubar = new JMenuBar();
276 if ( !_configuration.isUseNativeUI() ) {
277 _jmenubar.setBackground( getConfiguration().getGuiMenuBackgroundColor() );
280 if ( AptxConstants.__ALLOW_PHYLOGENETIC_INFERENCE ) {
281 buildPhylogeneticInferenceMenu();
290 setJMenuBar( _jmenubar );
291 _jmenubar.add( _help_jmenu );
292 _contentpane = getContentPane();
293 _contentpane.setLayout( new BorderLayout() );
294 _contentpane.add( _mainpanel, BorderLayout.CENTER );
296 setSize( MainFrameApplication.FRAME_X_SIZE, MainFrameApplication.FRAME_Y_SIZE );
297 // addWindowFocusListener( new WindowAdapter() {
300 // public void windowGainedFocus( WindowEvent e ) {
301 // requestFocusInWindow();
304 // The window listener
305 setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );
306 addWindowListener( new WindowAdapter() {
309 public void windowClosing( final WindowEvent e ) {
310 if ( isUnsavedDataPresent() ) {
311 final int r = JOptionPane.showConfirmDialog( null,
312 "Exit despite potentially unsaved changes?",
314 JOptionPane.YES_NO_OPTION );
315 if ( r != JOptionPane.YES_OPTION ) {
320 final int r = JOptionPane
321 .showConfirmDialog( null, "Exit Archaeopteryx?", "Exit?", JOptionPane.YES_NO_OPTION );
322 if ( r != JOptionPane.YES_OPTION ) {
329 // The component listener
330 addComponentListener( new ComponentAdapter() {
333 public void componentResized( final ComponentEvent e ) {
334 if ( _mainpanel.getCurrentTreePanel() != null ) {
335 _mainpanel.getCurrentTreePanel()
336 .calcParametersForPainting( _mainpanel.getCurrentTreePanel().getWidth(),
337 _mainpanel.getCurrentTreePanel().getHeight() );
341 requestFocusInWindow();
342 // addKeyListener( this );
344 if ( ( phys != null ) && ( phys.length > 0 ) ) {
345 AptxUtil.addPhylogeniesToTabs( phys, title, null, _configuration, _mainpanel );
347 getMainPanel().getControlPanel().showWholeAll();
348 getMainPanel().getControlPanel().showWhole();
350 activateSaveAllIfNeeded();
351 // ...and its children
352 _contentpane.repaint();
356 private MainFrameApplication( final Phylogeny[] phys, final String config_file, final String title ) {
357 // Reads the config file (false, false => not url, not applet):
358 this( phys, new Configuration( config_file, false, false, true ), title );
362 public void actionPerformed( final ActionEvent e ) {
364 super.actionPerformed( e );
365 final Object o = e.getSource();
366 // Handle app-specific actions here:
367 if ( o == _open_item ) {
368 readPhylogeniesFromFile();
370 if ( o == _open_url_item ) {
371 readPhylogeniesFromURL();
373 else if ( o == _new_item ) {
376 else if ( o == _close_item ) {
379 else if ( o == _load_species_tree_item ) {
380 readSpeciesTreeFromFile();
382 else if ( o == _obtain_detailed_taxonomic_information_jmi ) {
383 if ( isSubtreeDisplayed() ) {
386 obtainDetailedTaxonomicInformation();
388 else if ( o == _obtain_detailed_taxonomic_information_deleting_jmi ) {
389 if ( isSubtreeDisplayed() ) {
392 obtainDetailedTaxonomicInformationDelete();
394 else if ( o == _obtain_seq_information_jmi ) {
395 obtainSequenceInformation();
397 else if ( o == _read_values_jmi ) {
398 if ( isSubtreeDisplayed() ) {
401 addExpressionValuesFromFile();
403 else if ( o == _read_seqs_jmi ) {
404 if ( isSubtreeDisplayed() ) {
407 addSequencesFromFile();
409 else if ( o == _move_node_names_to_tax_sn_jmi ) {
410 moveNodeNamesToTaxSn();
412 else if ( o == _move_node_names_to_seq_names_jmi ) {
413 moveNodeNamesToSeqNames();
415 else if ( o == _extract_tax_code_from_node_names_jmi ) {
416 extractTaxDataFromNodeNames();
418 else if ( o == _internal_number_are_confidence_for_nh_parsing_cbmi ) {
419 updateOptions( getOptions() );
421 else if ( o == _replace_underscores_cbmi ) {
422 if ( ( _extract_taxonomy_no_rbmi != null ) && !_extract_taxonomy_no_rbmi.isSelected() ) {
423 _extract_taxonomy_no_rbmi.setSelected( true );
425 updateOptions( getOptions() );
427 else if ( o == _allow_errors_in_distance_to_parent_cbmi ) {
428 updateOptions( getOptions() );
430 else if ( o == _collapse_below_threshold ) {
431 if ( isSubtreeDisplayed() ) {
434 collapseBelowThreshold();
437 else if ( o == _collapse_below_branch_length ) {
438 if ( isSubtreeDisplayed() ) {
441 collapseBelowBranchLengthThreshold();
443 else if ( ( o == _extract_taxonomy_pfam_strict_rbmi ) || ( o == _extract_taxonomy_pfam_relaxed_rbmi )
444 || ( o == _extract_taxonomy_agressive_rbmi ) ) {
445 if ( _replace_underscores_cbmi != null ) {
446 _replace_underscores_cbmi.setSelected( false );
448 updateOptions( getOptions() );
450 else if ( o == _extract_taxonomy_no_rbmi ) {
451 updateOptions( getOptions() );
453 else if ( o == _inference_from_msa_item ) {
454 executePhyleneticInference( false );
456 else if ( o == _inference_from_seqs_item ) {
457 executePhyleneticInference( true );
459 _contentpane.repaint();
461 catch ( final Exception ex ) {
462 AptxUtil.unexpectedException( ex );
464 catch ( final Error err ) {
465 AptxUtil.unexpectedError( err );
470 _mainpanel.terminate();
471 _contentpane.removeAll();
477 public MainPanel getMainPanel() {
481 public Msa getMsa() {
485 public File getMsaFile() {
489 public List<MolecularSequence> getSeqs() {
493 public File getSeqsFile() {
497 public void readMsaFromFile() {
498 // Set an initial directory if none set yet
499 final File my_dir = getCurrentDir();
500 _msa_filechooser.setMultiSelectionEnabled( false );
501 // Open file-open dialog and set current directory
502 if ( my_dir != null ) {
503 _msa_filechooser.setCurrentDirectory( my_dir );
505 final int result = _msa_filechooser.showOpenDialog( _contentpane );
506 // All done: get the msa
507 final File file = _msa_filechooser.getSelectedFile();
508 setCurrentDir( _msa_filechooser.getCurrentDirectory() );
509 if ( ( file != null ) && !file.isDirectory() && ( result == JFileChooser.APPROVE_OPTION ) ) {
514 final InputStream is = new FileInputStream( file );
515 if ( FastaParser.isLikelyFasta( file ) ) {
516 msa = FastaParser.parseMsa( is );
519 msa = GeneralMsaParser.parse( is );
522 catch ( final MsaFormatException e ) {
524 JOptionPane.showMessageDialog( this,
525 e.getLocalizedMessage(),
526 "Multiple sequence alignment format error",
527 JOptionPane.ERROR_MESSAGE );
530 catch ( final IOException e ) {
532 JOptionPane.showMessageDialog( this,
533 e.getLocalizedMessage(),
534 "Failed to read multiple sequence alignment",
535 JOptionPane.ERROR_MESSAGE );
538 catch ( final IllegalArgumentException e ) {
540 JOptionPane.showMessageDialog( this,
541 e.getLocalizedMessage(),
542 "Unexpected error during reading of multiple sequence alignment",
543 JOptionPane.ERROR_MESSAGE );
546 catch ( final Exception e ) {
549 JOptionPane.showMessageDialog( this,
550 e.getLocalizedMessage(),
551 "Unexpected error during reading of multiple sequence alignment",
552 JOptionPane.ERROR_MESSAGE );
555 if ( ( msa == null ) || ( msa.getNumberOfSequences() < 1 ) ) {
556 JOptionPane.showMessageDialog( this,
557 "Multiple sequence alignment is empty",
558 "Illegal Multiple Sequence Alignment",
559 JOptionPane.ERROR_MESSAGE );
562 if ( msa.getNumberOfSequences() < 4 ) {
563 JOptionPane.showMessageDialog( this,
564 "Multiple sequence alignment needs to contain at least 3 sequences",
565 "Illegal multiple sequence alignment",
566 JOptionPane.ERROR_MESSAGE );
569 if ( msa.getLength() < 2 ) {
570 JOptionPane.showMessageDialog( this,
571 "Multiple sequence alignment needs to contain at least 2 residues",
572 "Illegal multiple sequence alignment",
573 JOptionPane.ERROR_MESSAGE );
577 setMsaFile( _msa_filechooser.getSelectedFile() );
582 public void readSeqsFromFileforPI() {
583 // Set an initial directory if none set yet
584 final File my_dir = getCurrentDir();
585 _seqs_pi_filechooser.setMultiSelectionEnabled( false );
586 // Open file-open dialog and set current directory
587 if ( my_dir != null ) {
588 _seqs_pi_filechooser.setCurrentDirectory( my_dir );
590 final int result = _seqs_pi_filechooser.showOpenDialog( _contentpane );
591 // All done: get the seqs
592 final File file = _seqs_pi_filechooser.getSelectedFile();
593 setCurrentDir( _seqs_pi_filechooser.getCurrentDirectory() );
594 if ( ( file != null ) && !file.isDirectory() && ( result == JFileChooser.APPROVE_OPTION ) ) {
597 List<MolecularSequence> seqs = null;
599 if ( FastaParser.isLikelyFasta( new FileInputStream( file ) ) ) {
600 seqs = FastaParser.parse( new FileInputStream( file ) );
601 for( final MolecularSequence seq : seqs ) {
602 System.out.println( SequenceWriter.toFasta( seq, 60 ) );
609 catch ( final MsaFormatException e ) {
611 JOptionPane.showMessageDialog( this,
612 e.getLocalizedMessage(),
613 "Multiple sequence file format error",
614 JOptionPane.ERROR_MESSAGE );
617 catch ( final IOException e ) {
619 JOptionPane.showMessageDialog( this,
620 e.getLocalizedMessage(),
621 "Failed to read multiple sequence file",
622 JOptionPane.ERROR_MESSAGE );
625 catch ( final IllegalArgumentException e ) {
627 JOptionPane.showMessageDialog( this,
628 e.getLocalizedMessage(),
629 "Unexpected error during reading of multiple sequence file",
630 JOptionPane.ERROR_MESSAGE );
633 catch ( final Exception e ) {
636 JOptionPane.showMessageDialog( this,
637 e.getLocalizedMessage(),
638 "Unexpected error during reading of multiple sequence file",
639 JOptionPane.ERROR_MESSAGE );
642 if ( ( seqs == null ) || ( seqs.size() < 1 ) ) {
643 JOptionPane.showMessageDialog( this,
644 "Multiple sequence file is empty",
645 "Illegal multiple sequence file",
646 JOptionPane.ERROR_MESSAGE );
649 if ( seqs.size() < 4 ) {
650 JOptionPane.showMessageDialog( this,
651 "Multiple sequence file needs to contain at least 3 sequences",
652 "Illegal multiple sequence file",
653 JOptionPane.ERROR_MESSAGE );
656 // if ( msa.getLength() < 2 ) {
657 // JOptionPane.showMessageDialog( this,
658 // "Multiple sequence alignment needs to contain at least 2 residues",
659 // "Illegal multiple sequence file",
660 // JOptionPane.ERROR_MESSAGE );
664 setSeqsFile( _seqs_pi_filechooser.getSelectedFile() );
669 private void addExpressionValuesFromFile() {
670 if ( ( getCurrentTreePanel() == null ) || ( getCurrentTreePanel().getPhylogeny() == null ) ) {
671 JOptionPane.showMessageDialog( this,
672 "Need to load evolutionary tree first",
673 "Can Not Read Expression Values",
674 JOptionPane.WARNING_MESSAGE );
677 final File my_dir = getCurrentDir();
678 if ( my_dir != null ) {
679 _values_filechooser.setCurrentDirectory( my_dir );
681 final int result = _values_filechooser.showOpenDialog( _contentpane );
682 final File file = _values_filechooser.getSelectedFile();
683 if ( ( file != null ) && ( file.length() > 0 ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
684 BasicTable<String> t = null;
686 t = BasicTableParser.parse( file, '\t' );
687 if ( t.getNumberOfColumns() < 2 ) {
688 t = BasicTableParser.parse( file, ',' );
690 if ( t.getNumberOfColumns() < 2 ) {
691 t = BasicTableParser.parse( file, ' ' );
694 catch ( final IOException e ) {
695 JOptionPane.showMessageDialog( this,
697 "Could Not Read Expression Value Table",
698 JOptionPane.ERROR_MESSAGE );
701 if ( t.getNumberOfColumns() < 2 ) {
702 JOptionPane.showMessageDialog( this,
703 "Table contains " + t.getNumberOfColumns() + " column(s)",
704 "Problem with Expression Value Table",
705 JOptionPane.ERROR_MESSAGE );
708 if ( t.getNumberOfRows() < 1 ) {
709 JOptionPane.showMessageDialog( this,
710 "Table contains zero rows",
711 "Problem with Expression Value Table",
712 JOptionPane.ERROR_MESSAGE );
715 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
716 if ( t.getNumberOfRows() != phy.getNumberOfExternalNodes() ) {
717 JOptionPane.showMessageDialog( this,
718 "Table contains " + t.getNumberOfRows() + " rows, but tree contains "
719 + phy.getNumberOfExternalNodes() + " external nodes",
721 JOptionPane.WARNING_MESSAGE );
723 final DescriptiveStatistics stats = new BasicDescriptiveStatistics();
725 for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) {
726 final PhylogenyNode node = iter.next();
727 final String node_name = node.getName();
728 if ( !ForesterUtil.isEmpty( node_name ) ) {
731 row = t.findRow( node_name );
733 catch ( final IllegalArgumentException e ) {
734 JOptionPane.showMessageDialog( this,
736 "Error Mapping Node Identifiers to Expression Value Identifiers",
737 JOptionPane.ERROR_MESSAGE );
741 if ( node.isExternal() ) {
746 final List<Double> l = new ArrayList<Double>();
747 for( int col = 1; col < t.getNumberOfColumns(); ++col ) {
750 d = Double.parseDouble( t.getValueAsString( col, row ) );
752 catch ( final NumberFormatException e ) {
753 JOptionPane.showMessageDialog( this,
754 "Could not parse \"" + t.getValueAsString( col, row )
755 + "\" into a decimal value",
756 "Issue with Expression Value Table",
757 JOptionPane.ERROR_MESSAGE );
763 if ( !l.isEmpty() ) {
765 node.getNodeData().setVector( l );
769 if ( not_found > 0 ) {
771 .showMessageDialog( this,
772 "Could not fine expression values for " + not_found + " external node(s)",
774 JOptionPane.WARNING_MESSAGE );
776 getCurrentTreePanel().setStatisticsForExpressionValues( stats );
780 private void addSequencesFromFile() {
781 if ( ( getCurrentTreePanel() == null ) || ( getCurrentTreePanel().getPhylogeny() == null ) ) {
782 JOptionPane.showMessageDialog( this,
783 "Need to load evolutionary tree first",
784 "Can Not Read Sequences",
785 JOptionPane.WARNING_MESSAGE );
788 final File my_dir = getCurrentDir();
789 if ( my_dir != null ) {
790 _sequences_filechooser.setCurrentDirectory( my_dir );
792 final int result = _sequences_filechooser.showOpenDialog( _contentpane );
793 final File file = _sequences_filechooser.getSelectedFile();
794 List<MolecularSequence> seqs = null;
795 if ( ( file != null ) && !file.isDirectory() && ( result == JFileChooser.APPROVE_OPTION ) ) {
797 final FileInputStream fis1 = new FileInputStream( file );
798 if ( FastaParser.isLikelyFasta( fis1 ) ) {
799 final FileInputStream fis2 = new FileInputStream( file );
800 seqs = FastaParser.parse( fis2 );
804 catch ( final Exception e ) {
809 JOptionPane.showMessageDialog( this,
810 "Format does not appear to be Fasta",
811 "Multiple sequence file format error",
812 JOptionPane.ERROR_MESSAGE );
818 catch ( final Exception e ) {
822 catch ( final MsaFormatException e ) {
824 JOptionPane.showMessageDialog( this,
825 e.getLocalizedMessage(),
826 "Multiple sequence file format error",
827 JOptionPane.ERROR_MESSAGE );
830 catch ( final IOException e ) {
832 JOptionPane.showMessageDialog( this,
833 e.getLocalizedMessage(),
834 "Failed to read multiple sequence file",
835 JOptionPane.ERROR_MESSAGE );
838 catch ( final Exception e ) {
841 JOptionPane.showMessageDialog( this,
842 e.getLocalizedMessage(),
843 "Unexpected error during reading of multiple sequence file",
844 JOptionPane.ERROR_MESSAGE );
847 if ( ( seqs == null ) || ( seqs.size() < 1 ) ) {
848 JOptionPane.showMessageDialog( this,
849 "Multiple sequence file is empty",
850 "Empty multiple sequence file",
851 JOptionPane.ERROR_MESSAGE );
856 if ( seqs != null ) {
857 for( final MolecularSequence seq : seqs ) {
858 System.out.println( seq.getIdentifier() );
860 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
861 int total_counter = 0;
862 int attached_counter = 0;
863 for( final MolecularSequence seq : seqs ) {
865 final String seq_name = seq.getIdentifier();
866 if ( !ForesterUtil.isEmpty( seq_name ) ) {
867 List<PhylogenyNode> nodes = phy.getNodesViaSequenceName( seq_name );
868 if ( nodes.isEmpty() ) {
869 nodes = phy.getNodesViaSequenceSymbol( seq_name );
871 if ( nodes.isEmpty() ) {
872 nodes = phy.getNodesViaGeneName( seq_name );
874 if ( nodes.isEmpty() ) {
875 nodes = phy.getNodes( seq_name );
877 if ( nodes.size() > 1 ) {
878 JOptionPane.showMessageDialog( this,
879 "Sequence name \"" + seq_name + "\" is not unique",
880 "Sequence name not unique",
881 JOptionPane.ERROR_MESSAGE );
885 final String[] a = seq_name.split( "\\s" );
886 if ( nodes.isEmpty() && ( a.length > 1 ) ) {
887 final String seq_name_split = a[ 0 ];
888 nodes = phy.getNodesViaSequenceName( seq_name_split );
889 if ( nodes.isEmpty() ) {
890 nodes = phy.getNodesViaSequenceSymbol( seq_name_split );
892 if ( nodes.isEmpty() ) {
893 nodes = phy.getNodes( seq_name_split );
895 if ( nodes.size() > 1 ) {
896 JOptionPane.showMessageDialog( this,
897 "Split sequence name \"" + seq_name_split
898 + "\" is not unique",
899 "Sequence name not unique",
900 JOptionPane.ERROR_MESSAGE );
905 if ( nodes.size() == 1 ) {
907 final PhylogenyNode n = nodes.get( 0 );
908 if ( !n.getNodeData().isHasSequence() ) {
909 n.getNodeData().addSequence( new org.forester.phylogeny.data.Sequence() );
911 n.getNodeData().getSequence().setMolecularSequence( seq.getMolecularSequenceAsString() );
912 if ( ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) {
913 n.getNodeData().getSequence().setName( seq_name );
918 if ( attached_counter > 0 ) {
920 int ext_nodes_with_seq = 0;
921 for( final PhylogenyNodeIterator iter = phy.iteratorExternalForward(); iter.hasNext(); ) {
923 final PhylogenyNode n = iter.next();
924 if ( n.getNodeData().isHasSequence()
925 && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) {
926 ++ext_nodes_with_seq;
930 if ( ext_nodes == ext_nodes_with_seq ) {
931 s = "All " + ext_nodes_with_seq + " external nodes now have a molecular sequence attached to them.";
934 s = ext_nodes_with_seq + " out of " + ext_nodes
935 + " external nodes now have a molecular sequence attached to them.";
937 if ( ( attached_counter == total_counter ) && ( ext_nodes == ext_nodes_with_seq ) ) {
938 JOptionPane.showMessageDialog( this,
939 "Attached all " + total_counter + " sequences to tree nodes.\n" + s,
940 "All sequences attached",
941 JOptionPane.INFORMATION_MESSAGE );
944 JOptionPane.showMessageDialog( this,
945 "Attached " + attached_counter + " sequences out of a total of "
946 + total_counter + " sequences.\n" + s,
947 attached_counter + " sequences attached",
948 JOptionPane.WARNING_MESSAGE );
952 JOptionPane.showMessageDialog( this,
953 "No maching tree node for any of the " + total_counter + " sequences",
954 "Could not attach any sequences",
955 JOptionPane.ERROR_MESSAGE );
960 private void closeCurrentPane() {
961 if ( getMainPanel().getCurrentTreePanel() != null ) {
962 if ( getMainPanel().getCurrentTreePanel().isEdited() ) {
963 final int r = JOptionPane.showConfirmDialog( this,
964 "Close tab despite potentially unsaved changes?",
966 JOptionPane.YES_NO_OPTION );
967 if ( r != JOptionPane.YES_OPTION ) {
971 getMainPanel().closeCurrentPane();
972 activateSaveAllIfNeeded();
976 private void collapseBelowThreshold( final Phylogeny phy ) {
977 final PhylogenyNodeIterator it = phy.iteratorPostorder();
978 final List<PhylogenyNode> to_be_removed = new ArrayList<PhylogenyNode>();
979 double min_support = Double.MAX_VALUE;
980 boolean conf_present = false;
981 while ( it.hasNext() ) {
982 final PhylogenyNode n = it.next();
983 if ( !n.isExternal() && !n.isRoot() ) {
984 final List<Confidence> c = n.getBranchData().getConfidences();
985 if ( ( c != null ) && ( c.size() > 0 ) ) {
988 for( final Confidence confidence : c ) {
989 if ( confidence.getValue() > max ) {
990 max = confidence.getValue();
993 if ( max < getMinNotCollapseConfidenceValue() ) {
994 to_be_removed.add( n );
996 if ( max < min_support ) {
1002 if ( conf_present ) {
1003 for( final PhylogenyNode node : to_be_removed ) {
1004 PhylogenyMethods.removeNode( node, phy );
1006 if ( to_be_removed.size() > 0 ) {
1007 phy.externalNodesHaveChanged();
1008 phy.clearHashIdToNodeMap();
1009 phy.recalculateNumberOfExternalDescendants( true );
1010 getCurrentTreePanel().resetNodeIdToDistToLeafMap();
1011 getCurrentTreePanel().updateSetOfCollapsedExternalNodes();
1012 getCurrentTreePanel().calculateLongestExtNodeInfo();
1013 getCurrentTreePanel().setNodeInPreorderToNull();
1014 getCurrentTreePanel().recalculateMaxDistanceToRoot();
1015 getCurrentTreePanel().resetPreferredSize();
1016 getCurrentTreePanel().setEdited( true );
1017 getCurrentTreePanel().repaint();
1020 if ( to_be_removed.size() > 0 ) {
1021 JOptionPane.showMessageDialog( this,
1022 "Collapsed " + to_be_removed.size()
1023 + " branches with\nconfidence values below "
1024 + getMinNotCollapseConfidenceValue(),
1025 "Collapsed " + to_be_removed.size() + " branches",
1026 JOptionPane.INFORMATION_MESSAGE );
1029 JOptionPane.showMessageDialog( this,
1030 "No branch collapsed,\nminimum confidence value per branch is "
1032 "No branch collapsed",
1033 JOptionPane.INFORMATION_MESSAGE );
1037 JOptionPane.showMessageDialog( this,
1038 "No branch collapsed because no confidence values present",
1039 "No confidence values present",
1040 JOptionPane.INFORMATION_MESSAGE );
1044 private void collapseBelowBranchLengthThreshold() {
1045 if ( getCurrentTreePanel() != null ) {
1046 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1047 if ( ( phy != null ) && !phy.isEmpty() ) {
1048 final String s = ( String ) JOptionPane.showInputDialog( this,
1049 "Please enter the minimum branch length value\n",
1050 "Minimal Branch Length Value",
1051 JOptionPane.QUESTION_MESSAGE,
1054 getMinNotCollapseBlValue() );
1055 if ( !ForesterUtil.isEmpty( s ) ) {
1056 boolean success = true;
1058 final String m_str = s.trim();
1059 if ( !ForesterUtil.isEmpty( m_str ) ) {
1061 m = Double.parseDouble( m_str );
1063 catch ( final Exception ex ) {
1070 if ( success && ( m >= 0.0 ) ) {
1071 setMinNotCollapseBlValue( m );
1079 private void collapseBelowThreshold() {
1080 if ( getCurrentTreePanel() != null ) {
1081 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1082 if ( ( phy != null ) && !phy.isEmpty() ) {
1083 final String s = ( String ) JOptionPane.showInputDialog( this,
1084 "Please enter the minimum confidence value\n",
1085 "Minimal Confidence Value",
1086 JOptionPane.QUESTION_MESSAGE,
1089 getMinNotCollapseConfidenceValue() );
1090 if ( !ForesterUtil.isEmpty( s ) ) {
1091 boolean success = true;
1093 final String m_str = s.trim();
1094 if ( !ForesterUtil.isEmpty( m_str ) ) {
1096 m = Double.parseDouble( m_str );
1098 catch ( final Exception ex ) {
1105 if ( success && ( m >= 0.0 ) ) {
1106 setMinNotCollapseConfidenceValue( m );
1107 collapseBelowThreshold( phy );
1114 private void collapseBl( final Phylogeny phy ) {
1115 final PhylogenyNodeIterator it = phy.iteratorPostorder();
1116 final List<PhylogenyNode> to_be_removed = new ArrayList<PhylogenyNode>();
1117 double min_bl = Double.MAX_VALUE;
1118 boolean bl_present = false;
1119 while ( it.hasNext() ) {
1120 final PhylogenyNode n = it.next();
1121 if ( !n.isExternal() && !n.isRoot() ) {
1122 final double bl = n.getDistanceToParent();
1123 if ( bl != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) {
1125 if ( bl < getMinNotCollapseBlValue() ) {
1126 to_be_removed.add( n );
1128 if ( bl < min_bl ) {
1135 for( final PhylogenyNode node : to_be_removed ) {
1136 PhylogenyMethods.removeNode( node, phy );
1138 if ( to_be_removed.size() > 0 ) {
1139 phy.externalNodesHaveChanged();
1140 phy.clearHashIdToNodeMap();
1141 phy.recalculateNumberOfExternalDescendants( true );
1142 getCurrentTreePanel().resetNodeIdToDistToLeafMap();
1143 getCurrentTreePanel().updateSetOfCollapsedExternalNodes();
1144 getCurrentTreePanel().calculateLongestExtNodeInfo();
1145 getCurrentTreePanel().setNodeInPreorderToNull();
1146 getCurrentTreePanel().recalculateMaxDistanceToRoot();
1147 getCurrentTreePanel().resetPreferredSize();
1148 getCurrentTreePanel().setEdited( true );
1149 getCurrentTreePanel().repaint();
1152 if ( to_be_removed.size() > 0 ) {
1153 JOptionPane.showMessageDialog( this,
1154 "Collapsed " + to_be_removed.size()
1155 + " branches with\nbranch length values below "
1156 + getMinNotCollapseBlValue(),
1157 "Collapsed " + to_be_removed.size() + " branches",
1158 JOptionPane.INFORMATION_MESSAGE );
1161 JOptionPane.showMessageDialog( this,
1162 "No branch collapsed,\nminimum branch length is " + min_bl,
1163 "No branch collapsed",
1164 JOptionPane.INFORMATION_MESSAGE );
1168 JOptionPane.showMessageDialog( this,
1169 "No branch collapsed because no branch length values present",
1170 "No branch length values present",
1171 JOptionPane.INFORMATION_MESSAGE );
1175 private PhyloXmlParser createPhyloXmlParser() {
1176 PhyloXmlParser xml_parser = null;
1177 if ( getConfiguration().isValidatePhyloXmlAgainstSchema() ) {
1179 xml_parser = PhyloXmlParser.createPhyloXmlParserXsdValidating();
1181 catch ( final Exception e ) {
1182 JOptionPane.showMessageDialog( this,
1183 e.getLocalizedMessage(),
1184 "failed to create validating XML parser",
1185 JOptionPane.WARNING_MESSAGE );
1188 if ( xml_parser == null ) {
1189 xml_parser = PhyloXmlParser.createPhyloXmlParser();
1194 private void executePhyleneticInference( final boolean from_unaligned_seqs ) {
1195 final PhyloInferenceDialog dialog = new PhyloInferenceDialog( this,
1196 getPhylogeneticInferenceOptions(),
1197 from_unaligned_seqs );
1199 if ( dialog.getValue() == JOptionPane.OK_OPTION ) {
1200 if ( !from_unaligned_seqs ) {
1201 if ( getMsa() != null ) {
1202 final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getMsa(),
1203 getPhylogeneticInferenceOptions()
1206 new Thread( inferrer ).start();
1209 JOptionPane.showMessageDialog( this,
1210 "No multiple sequence alignment selected",
1211 "Phylogenetic Inference Not Launched",
1212 JOptionPane.WARNING_MESSAGE );
1216 if ( getSeqs() != null ) {
1217 final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getSeqs(),
1218 getPhylogeneticInferenceOptions()
1221 new Thread( inferrer ).start();
1224 JOptionPane.showMessageDialog( this,
1225 "No input sequences selected",
1226 "Phylogenetic Inference Not Launched",
1227 JOptionPane.WARNING_MESSAGE );
1233 private void extractTaxDataFromNodeNames() throws PhyloXmlDataFormatException {
1234 final StringBuilder sb = new StringBuilder();
1235 final StringBuilder sb_failed = new StringBuilder();
1237 int counter_failed = 0;
1238 if ( getCurrentTreePanel() != null ) {
1239 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1240 if ( ( phy != null ) && !phy.isEmpty() ) {
1241 final PhylogenyNodeIterator it = phy.iteratorExternalForward();
1242 while ( it.hasNext() ) {
1243 final PhylogenyNode n = it.next();
1244 final String name = n.getName().trim();
1245 if ( !ForesterUtil.isEmpty( name ) ) {
1246 final String nt = ParserUtils.extractTaxonomyDataFromNodeName( n,
1247 TAXONOMY_EXTRACTION.AGGRESSIVE );
1248 if ( !ForesterUtil.isEmpty( nt ) ) {
1249 if ( counter < 15 ) {
1250 sb.append( name + ": " + nt + "\n" );
1252 else if ( counter == 15 ) {
1253 sb.append( "...\n" );
1258 if ( counter_failed < 15 ) {
1259 sb_failed.append( name + "\n" );
1261 else if ( counter_failed == 15 ) {
1262 sb_failed.append( "...\n" );
1268 if ( counter > 0 ) {
1270 String all = "all ";
1271 if ( counter_failed > 0 ) {
1273 failed = "\nCould not extract taxonomic data for " + counter_failed + " named external nodes:\n"
1276 JOptionPane.showMessageDialog( this,
1277 "Extracted taxonomic data from " + all + counter
1278 + " named external nodes:\n" + sb.toString() + failed,
1279 "Taxonomic Data Extraction Completed",
1280 counter_failed > 0 ? JOptionPane.WARNING_MESSAGE
1281 : JOptionPane.INFORMATION_MESSAGE );
1284 JOptionPane.showMessageDialog( this,
1285 "Could not extract any taxonomic data.\nMaybe node names are empty\n"
1286 + "or not in the forms \"XYZ_CAEEL\", \"XYZ_6239\", or \"XYZ_Caenorhabditis_elegans\"\n"
1287 + "or nodes already have taxonomic data?\n",
1288 "No Taxonomic Data Extracted",
1289 JOptionPane.ERROR_MESSAGE );
1295 private double getMinNotCollapseBlValue() {
1296 return _min_not_collapse_bl;
1299 private double getMinNotCollapseConfidenceValue() {
1300 return _min_not_collapse;
1303 private PhylogeneticInferenceOptions getPhylogeneticInferenceOptions() {
1304 if ( _phylogenetic_inference_options == null ) {
1305 _phylogenetic_inference_options = new PhylogeneticInferenceOptions();
1307 return _phylogenetic_inference_options;
1310 private boolean isUnsavedDataPresent() {
1311 final List<TreePanel> tps = getMainPanel().getTreePanels();
1312 for( final TreePanel tp : tps ) {
1313 if ( tp.isEdited() ) {
1320 private void moveNodeNamesToSeqNames() throws PhyloXmlDataFormatException {
1321 if ( getCurrentTreePanel() != null ) {
1322 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1323 if ( ( phy != null ) && !phy.isEmpty() ) {
1324 PhylogenyMethods.transferNodeNameToField( phy,
1325 PhylogenyMethods.PhylogenyNodeField.SEQUENCE_NAME,
1331 private void moveNodeNamesToTaxSn() throws PhyloXmlDataFormatException {
1332 if ( getCurrentTreePanel() != null ) {
1333 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1334 if ( ( phy != null ) && !phy.isEmpty() ) {
1335 PhylogenyMethods.transferNodeNameToField( phy,
1336 PhylogenyMethods.PhylogenyNodeField.TAXONOMY_SCIENTIFIC_NAME,
1342 private void newTree() {
1343 final Phylogeny[] phys = new Phylogeny[ 1 ];
1344 final Phylogeny phy = new Phylogeny();
1345 final PhylogenyNode node = new PhylogenyNode();
1346 phy.setRoot( node );
1347 phy.setRooted( true );
1349 AptxUtil.addPhylogeniesToTabs( phys, "", "", getConfiguration(), getMainPanel() );
1350 _mainpanel.getControlPanel().showWhole();
1351 _mainpanel.getCurrentTreePanel().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
1352 _mainpanel.getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
1354 getMainPanel().getMainFrame().setSelectedTypeInTypeMenu( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
1356 activateSaveAllIfNeeded();
1360 private void obtainDetailedTaxonomicInformation() {
1361 if ( getCurrentTreePanel() != null ) {
1362 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1363 if ( ( phy != null ) && !phy.isEmpty() ) {
1364 final TaxonomyDataManager t = new TaxonomyDataManager( this,
1365 _mainpanel.getCurrentTreePanel(),
1369 new Thread( t ).start();
1374 private void obtainDetailedTaxonomicInformationDelete() {
1375 if ( getCurrentTreePanel() != null ) {
1376 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1377 if ( ( phy != null ) && !phy.isEmpty() ) {
1378 final TaxonomyDataManager t = new TaxonomyDataManager( this,
1379 _mainpanel.getCurrentTreePanel(),
1383 new Thread( t ).start();
1388 private void obtainSequenceInformation() {
1389 if ( getCurrentTreePanel() != null ) {
1390 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1391 if ( ( phy != null ) && !phy.isEmpty() ) {
1392 final SequenceDataRetriver u = new SequenceDataRetriver( this,
1393 _mainpanel.getCurrentTreePanel(),
1395 new Thread( u ).start();
1400 private void preProcessTreesUponReading( final Phylogeny[] phys ) {
1401 for( final Phylogeny phy : phys ) {
1402 if ( ( phy != null ) && !phy.isEmpty() ) {
1403 for( final PhylogenyNodeIterator it = phy.iteratorPreorder(); it.hasNext(); ) {
1404 final PhylogenyNode n = it.next();
1405 if ( n.isExternal() ) {
1406 if ( n.getNodeData().isHasSequence() ) {
1407 final Sequence s = n.getNodeData().getSequence();
1408 if ( ForesterUtil.isEmpty( s.getGeneName() ) || s.getGeneName().startsWith( "LOC" ) ) {
1409 if ( ( s.getAccession() != null )
1410 && !ForesterUtil.isEmpty( s.getAccession().getValue() ) ) {
1411 s.setGeneName( s.getAccession().getValue() );
1413 else if ( !ForesterUtil.isEmpty( n.getName() ) ) {
1414 s.setGeneName( n.getName() );
1424 private void readPhylogeniesFromFile() {
1425 boolean exception = false;
1426 Phylogeny[] phys = null;
1427 // Set an initial directory if none set yet
1428 final File my_dir = getCurrentDir();
1429 // Open file-open dialog and set current directory
1430 if ( my_dir != null ) {
1431 _open_filechooser.setCurrentDirectory( my_dir );
1433 final int result = _open_filechooser.showOpenDialog( _contentpane );
1434 // All done: get the file
1435 final File[] files = _open_filechooser.getSelectedFiles();
1436 setCurrentDir( _open_filechooser.getCurrentDirectory() );
1437 boolean nhx_or_nexus = false;
1438 if ( ( files != null ) && ( files.length > 0 ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
1439 for( final File file : files ) {
1440 if ( ( file != null ) && !file.isDirectory() ) {
1441 if ( _mainpanel.getCurrentTreePanel() != null ) {
1442 _mainpanel.getCurrentTreePanel().setWaitCursor();
1445 _mainpanel.setWaitCursor();
1447 if ( ( _open_filechooser.getFileFilter() == MainFrame.nhfilter )
1448 || ( _open_filechooser.getFileFilter() == MainFrame.nhxfilter ) ) {
1450 final NHXParser nhx = new NHXParser();
1451 setSpecialOptionsForNhxParser( nhx );
1452 phys = PhylogenyMethods.readPhylogenies( nhx, file );
1453 nhx_or_nexus = true;
1455 catch ( final Exception e ) {
1457 exceptionOccuredDuringOpenFile( e );
1460 else if ( _open_filechooser.getFileFilter() == MainFrame.xmlfilter ) {
1461 warnIfNotPhyloXmlValidation( getConfiguration() );
1463 final PhyloXmlParser xml_parser = createPhyloXmlParser();
1464 phys = PhylogenyMethods.readPhylogenies( xml_parser, file );
1466 catch ( final Exception e ) {
1468 exceptionOccuredDuringOpenFile( e );
1471 else if ( _open_filechooser.getFileFilter() == MainFrame.tolfilter ) {
1473 phys = PhylogenyMethods.readPhylogenies( new TolParser(), file );
1475 catch ( final Exception e ) {
1477 exceptionOccuredDuringOpenFile( e );
1480 else if ( _open_filechooser.getFileFilter() == MainFrame.nexusfilter ) {
1482 final NexusPhylogeniesParser nex = new NexusPhylogeniesParser();
1483 setSpecialOptionsForNexParser( nex );
1484 phys = PhylogenyMethods.readPhylogenies( nex, file );
1485 nhx_or_nexus = true;
1487 catch ( final Exception e ) {
1489 exceptionOccuredDuringOpenFile( e );
1495 final PhylogenyParser parser = ParserUtils
1496 .createParserDependingOnFileType( file,
1498 .isValidatePhyloXmlAgainstSchema() );
1499 if ( parser instanceof NexusPhylogeniesParser ) {
1500 final NexusPhylogeniesParser nex = ( NexusPhylogeniesParser ) parser;
1501 setSpecialOptionsForNexParser( nex );
1502 nhx_or_nexus = true;
1504 else if ( parser instanceof NHXParser ) {
1505 final NHXParser nhx = ( NHXParser ) parser;
1506 setSpecialOptionsForNhxParser( nhx );
1507 nhx_or_nexus = true;
1509 else if ( parser instanceof PhyloXmlParser ) {
1510 warnIfNotPhyloXmlValidation( getConfiguration() );
1512 phys = PhylogenyMethods.readPhylogenies( parser, file );
1514 catch ( final Exception e ) {
1516 exceptionOccuredDuringOpenFile( e );
1519 if ( _mainpanel.getCurrentTreePanel() != null ) {
1520 _mainpanel.getCurrentTreePanel().setArrowCursor();
1523 _mainpanel.setArrowCursor();
1525 if ( !exception && ( phys != null ) && ( phys.length > 0 ) ) {
1526 boolean one_desc = false;
1527 if ( nhx_or_nexus ) {
1528 for( final Phylogeny phy : phys ) {
1529 if ( getOptions().isInternalNumberAreConfidenceForNhParsing() ) {
1530 PhylogenyMethods.transferInternalNodeNamesToConfidence( phy, "" );
1532 if ( PhylogenyMethods.getMinimumDescendentsPerInternalNodes( phy ) == 1 ) {
1538 if ( PREPROCESS_TREES ) {
1539 preProcessTreesUponReading( phys );
1541 AptxUtil.addPhylogeniesToTabs( phys,
1543 file.getAbsolutePath(),
1546 _mainpanel.getControlPanel().showWhole();
1547 if ( nhx_or_nexus && one_desc ) {
1548 JOptionPane.showMessageDialog( this,
1549 "One or more trees contain (a) node(s) with one descendant, "
1550 + ForesterUtil.LINE_SEPARATOR
1551 + "possibly indicating illegal parentheses within node names.",
1552 "Warning: Possible Error in New Hampshire Formatted Data",
1553 JOptionPane.WARNING_MESSAGE );
1559 activateSaveAllIfNeeded();
1563 private void readSpeciesTreeFromFile() {
1565 boolean exception = false;
1566 final File my_dir = getCurrentDir();
1567 _open_filechooser_for_species_tree.setSelectedFile( new File( "" ) );
1568 if ( my_dir != null ) {
1569 _open_filechooser_for_species_tree.setCurrentDirectory( my_dir );
1571 final int result = _open_filechooser_for_species_tree.showOpenDialog( _contentpane );
1572 final File file = _open_filechooser_for_species_tree.getSelectedFile();
1573 if ( ( file != null ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
1574 if ( _open_filechooser_for_species_tree.getFileFilter() == MainFrame.xmlfilter ) {
1576 final Phylogeny[] trees = PhylogenyMethods
1577 .readPhylogenies( PhyloXmlParser.createPhyloXmlParserXsdValidating(), file );
1580 catch ( final Exception e ) {
1582 exceptionOccuredDuringOpenFile( e );
1585 else if ( _open_filechooser_for_species_tree.getFileFilter() == MainFrame.tolfilter ) {
1587 final Phylogeny[] trees = PhylogenyMethods.readPhylogenies( new TolParser(), file );
1590 catch ( final Exception e ) {
1592 exceptionOccuredDuringOpenFile( e );
1598 final Phylogeny[] trees = PhylogenyMethods
1599 .readPhylogenies( PhyloXmlParser.createPhyloXmlParserXsdValidating(), file );
1602 catch ( final Exception e ) {
1604 exceptionOccuredDuringOpenFile( e );
1607 if ( !exception && ( t != null ) && !t.isRooted() ) {
1610 JOptionPane.showMessageDialog( this,
1611 "Species tree is not rooted",
1612 "Species tree not loaded",
1613 JOptionPane.ERROR_MESSAGE );
1615 if ( !exception && ( t != null ) ) {
1616 final Set<Taxonomy> tax_set = new HashSet<Taxonomy>();
1617 for( final PhylogenyNodeIterator it = t.iteratorExternalForward(); it.hasNext(); ) {
1618 final PhylogenyNode node = it.next();
1619 if ( !node.getNodeData().isHasTaxonomy() ) {
1622 JOptionPane.showMessageDialog( this,
1623 "Species tree contains external node(s) without taxonomy information",
1624 "Species tree not loaded",
1625 JOptionPane.ERROR_MESSAGE );
1629 if ( tax_set.contains( node.getNodeData().getTaxonomy() ) ) {
1633 .showMessageDialog( this,
1634 "Taxonomy [" + node.getNodeData().getTaxonomy().asSimpleText()
1635 + "] is not unique in species tree",
1636 "Species tree not loaded",
1637 JOptionPane.ERROR_MESSAGE );
1641 tax_set.add( node.getNodeData().getTaxonomy() );
1646 if ( !exception && ( t != null ) ) {
1647 setSpeciesTree( t );
1648 JOptionPane.showMessageDialog( this,
1649 "Species tree successfully loaded",
1650 "Species tree loaded",
1651 JOptionPane.INFORMATION_MESSAGE );
1653 _contentpane.repaint();
1658 private void setArrowCursor() {
1660 _mainpanel.getCurrentTreePanel().setArrowCursor();
1662 catch ( final Exception ex ) {
1667 private void setMinNotCollapseBlValue( final double min_not_collapse_bl ) {
1668 _min_not_collapse_bl = min_not_collapse_bl;
1671 private void setMinNotCollapseConfidenceValue( final double min_not_collapse ) {
1672 _min_not_collapse = min_not_collapse;
1675 private void setPhylogeneticInferenceOptions( final PhylogeneticInferenceOptions phylogenetic_inference_options ) {
1676 _phylogenetic_inference_options = phylogenetic_inference_options;
1679 private void setSpecialOptionsForNexParser( final NexusPhylogeniesParser nex ) {
1680 nex.setReplaceUnderscores( getOptions().isReplaceUnderscoresInNhParsing() );
1681 nex.setTaxonomyExtraction( getOptions().getTaxonomyExtraction() );
1682 nex.setParseBeastStyleExtendedTags( getOptions().isParseBeastStyleExtendedNexusTags() );
1685 private void setSpecialOptionsForNhxParser( final NHXParser nhx ) {
1686 nhx.setReplaceUnderscores( getOptions().isReplaceUnderscoresInNhParsing() );
1687 nhx.setTaxonomyExtraction( getOptions().getTaxonomyExtraction() );
1688 nhx.setAllowErrorsInDistanceToParent( getOptions().isAllowErrorsInDistanceToParent() );
1689 nhx.setParseBeastStyleExtendedTags( getOptions().isParseBeastStyleExtendedNexusTags() );
1692 void buildAnalysisMenu() {
1693 _analysis_menu = MainFrame.createMenu( "Analysis", getConfiguration() );
1694 _analysis_menu.add( _gsdi_item = new JMenuItem( "GSDI (Generalized Speciation Duplication Inference)" ) );
1695 _analysis_menu.add( _gsdir_item = new JMenuItem( "GSDIR (GSDI with re-rooting)" ) );
1696 _analysis_menu.add( _load_species_tree_item = new JMenuItem( "Load Species Tree..." ) );
1697 customizeJMenuItem( _gsdi_item );
1698 customizeJMenuItem( _gsdir_item );
1699 customizeJMenuItem( _load_species_tree_item );
1700 _analysis_menu.addSeparator();
1701 _analysis_menu.add( _lineage_inference = new JMenuItem( INFER_ANCESTOR_TAXONOMIES ) );
1702 customizeJMenuItem( _lineage_inference );
1703 _lineage_inference.setToolTipText( "Inference of ancestor taxonomies/lineages" );
1704 _jmenubar.add( _analysis_menu );
1708 void buildFileMenu() {
1709 _file_jmenu = MainFrame.createMenu( "File", getConfiguration() );
1710 _file_jmenu.add( _open_item = new JMenuItem( "Read Tree from File..." ) );
1711 _file_jmenu.addSeparator();
1712 _file_jmenu.add( _open_url_item = new JMenuItem( "Read Tree from URL/Webservice..." ) );
1713 _file_jmenu.addSeparator();
1714 final WebservicesManager webservices_manager = WebservicesManager.getInstance();
1715 _load_phylogeny_from_webservice_menu_items = new JMenuItem[ webservices_manager
1716 .getAvailablePhylogeniesWebserviceClients().size() ];
1717 for( int i = 0; i < webservices_manager.getAvailablePhylogeniesWebserviceClients().size(); ++i ) {
1718 final PhylogeniesWebserviceClient client = webservices_manager.getAvailablePhylogeniesWebserviceClient( i );
1719 _load_phylogeny_from_webservice_menu_items[ i ] = new JMenuItem( client.getMenuName() );
1720 _file_jmenu.add( _load_phylogeny_from_webservice_menu_items[ i ] );
1722 if ( getConfiguration().isEditable() ) {
1723 _file_jmenu.addSeparator();
1724 _file_jmenu.add( _new_item = new JMenuItem( "New" ) );
1725 _new_item.setToolTipText( "to create a new tree with one node, as source for manual tree construction" );
1727 _file_jmenu.addSeparator();
1728 _file_jmenu.add( _save_item = new JMenuItem( "Save Tree As..." ) );
1729 _file_jmenu.add( _save_all_item = new JMenuItem( "Save All Trees As..." ) );
1730 _save_all_item.setToolTipText( "Write all phylogenies to one file." );
1731 _save_all_item.setEnabled( false );
1732 _file_jmenu.addSeparator();
1733 _file_jmenu.add( _write_to_pdf_item = new JMenuItem( "Export to PDF file ..." ) );
1734 if ( AptxUtil.canWriteFormat( "tif" ) || AptxUtil.canWriteFormat( "tiff" )
1735 || AptxUtil.canWriteFormat( "TIF" ) ) {
1736 _file_jmenu.add( _write_to_tif_item = new JMenuItem( "Export to TIFF file..." ) );
1738 _file_jmenu.add( _write_to_png_item = new JMenuItem( "Export to PNG file..." ) );
1739 _file_jmenu.add( _write_to_jpg_item = new JMenuItem( "Export to JPG file..." ) );
1740 if ( AptxUtil.canWriteFormat( "gif" ) ) {
1741 _file_jmenu.add( _write_to_gif_item = new JMenuItem( "Export to GIF file..." ) );
1743 if ( AptxUtil.canWriteFormat( "bmp" ) ) {
1744 _file_jmenu.add( _write_to_bmp_item = new JMenuItem( "Export to BMP file..." ) );
1746 _file_jmenu.addSeparator();
1747 _file_jmenu.add( _print_item = new JMenuItem( "Print..." ) );
1748 _file_jmenu.addSeparator();
1749 _file_jmenu.add( _close_item = new JMenuItem( "Close Tab" ) );
1750 _close_item.setToolTipText( "To close the current pane." );
1751 _close_item.setEnabled( true );
1752 _file_jmenu.addSeparator();
1753 _file_jmenu.add( _exit_item = new JMenuItem( "Exit" ) );
1754 customizeJMenuItem( _open_item );
1755 _open_item.setFont( new Font( _open_item.getFont().getFontName(),
1757 _open_item.getFont().getSize() + 4 ) );
1758 customizeJMenuItem( _open_url_item );
1759 for( int i = 0; i < webservices_manager.getAvailablePhylogeniesWebserviceClients().size(); ++i ) {
1760 customizeJMenuItem( _load_phylogeny_from_webservice_menu_items[ i ] );
1762 customizeJMenuItem( _save_item );
1763 if ( getConfiguration().isEditable() ) {
1764 customizeJMenuItem( _new_item );
1766 customizeJMenuItem( _close_item );
1767 customizeJMenuItem( _save_all_item );
1768 customizeJMenuItem( _write_to_pdf_item );
1769 customizeJMenuItem( _write_to_png_item );
1770 customizeJMenuItem( _write_to_jpg_item );
1771 customizeJMenuItem( _write_to_gif_item );
1772 customizeJMenuItem( _write_to_tif_item );
1773 customizeJMenuItem( _write_to_bmp_item );
1774 customizeJMenuItem( _print_item );
1775 customizeJMenuItem( _exit_item );
1776 _jmenubar.add( _file_jmenu );
1779 void buildOptionsMenu() {
1780 _options_jmenu = MainFrame.createMenu( OPTIONS_HEADER, getConfiguration() );
1781 _options_jmenu.addChangeListener( new ChangeListener() {
1784 public void stateChanged( final ChangeEvent e ) {
1785 MainFrame.setOvPlacementColorChooseMenuItem( _overview_placment_mi, getOptions() );
1786 MainFrame.setTextColorChooseMenuItem( _switch_colors_mi, getCurrentTreePanel() );
1787 MainFrame.setTextMinSupportMenuItem( _choose_minimal_confidence_mi,
1789 getCurrentTreePanel() );
1790 MainFrame.setTextForFontChooserMenuItem( _choose_font_mi,
1791 MainFrame.createCurrentFontDesc( getMainPanel()
1792 .getTreeFontSet() ) );
1793 // MainFrame.setTextForGraphicsSizeChooserMenuItem( _print_size_mi, getOptions() );
1794 MainFrame.setTextForPdfLineWidthChooserMenuItem( _choose_pdf_width_mi, getOptions() );
1795 MainFrame.setCycleNodeFillMenuItem( _cycle_node_fill_mi, getOptions() );
1796 MainFrame.setCycleNodeShapeMenuItem( _cycle_node_shape_mi, getOptions() );
1797 MainFrame.setCycleDataReturnMenuItem( _cycle_data_return, getOptions() );
1798 MainFrame.setTextNodeSizeMenuItem( _choose_node_size_mi, getOptions() );
1800 getMainPanel().getControlPanel().setVisibilityOfDomainStrucureCB();
1801 getMainPanel().getControlPanel().setVisibilityOfX();
1803 catch ( final Exception ignore ) {
1804 // do nothing, not important.
1808 _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( DISPLAY_SUBHEADER ), getConfiguration() ) );
1810 .add( _ext_node_dependent_cladogram_rbmi = new JRadioButtonMenuItem( MainFrame.NONUNIFORM_CLADOGRAMS_LABEL ) );
1811 _options_jmenu.add( _non_lined_up_cladograms_rbmi = new JRadioButtonMenuItem( NON_LINED_UP_CLADOGRAMS_LABEL ) );
1812 _radio_group_1 = new ButtonGroup();
1813 _radio_group_1.add( _ext_node_dependent_cladogram_rbmi );
1814 _radio_group_1.add( _non_lined_up_cladograms_rbmi );
1815 _options_jmenu.add( _show_overview_cbmi = new JCheckBoxMenuItem( SHOW_OVERVIEW_LABEL ) );
1816 _options_jmenu.add( _show_scale_cbmi = new JCheckBoxMenuItem( DISPLAY_SCALE_LABEL ) );
1818 .add( _show_default_node_shapes_internal_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_INT ) );
1820 .add( _show_default_node_shapes_external_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_EXT ) );
1822 .add( _show_default_node_shapes_for_marked_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_NODE_BOXES_LABEL_MARKED ) );
1825 .add( _collapsed_with_average_height_cbmi = new JCheckBoxMenuItem( "Proportional Height of Collapsed Subtrees" ) );
1829 .add( _show_abbreviated_labels_for_collapsed_nodes_cbmi = new JCheckBoxMenuItem( "Add Abbreviated Labels to Collapsed Subtrees" ) );
1834 .add( _line_up_renderable_data_cbmi = new JCheckBoxMenuItem( MainFrame.LINE_UP_RENDERABLE_DATA ) );
1838 if ( getConfiguration().doDisplayOption( Configuration.show_domain_architectures ) ) {
1840 .add( _right_line_up_domains_cbmi = new JCheckBoxMenuItem( MainFrame.RIGHT_LINE_UP_DOMAINS ) );
1841 _options_jmenu.add( _show_domain_labels = new JCheckBoxMenuItem( MainFrame.SHOW_DOMAIN_LABELS_LABEL ) );
1843 _options_jmenu.add( _show_annotation_ref_source = new JCheckBoxMenuItem( SHOW_ANN_REF_SOURCE_LABEL ) );
1844 _options_jmenu.add( _show_confidence_stddev_cbmi = new JCheckBoxMenuItem( SHOW_CONF_STDDEV_LABEL ) );
1845 _options_jmenu.add( _color_by_taxonomic_group_cbmi = new JCheckBoxMenuItem( COLOR_BY_TAXONOMIC_GROUP ) );
1846 _options_jmenu.add( _color_labels_same_as_parent_branch = new JCheckBoxMenuItem( COLOR_LABELS_LABEL ) );
1847 _color_labels_same_as_parent_branch.setToolTipText( MainFrame.COLOR_LABELS_TIP );
1848 _options_jmenu.add( _abbreviate_scientific_names = new JCheckBoxMenuItem( ABBREV_SN_LABEL ) );
1849 _options_jmenu.add( _label_direction_cbmi = new JCheckBoxMenuItem( LABEL_DIRECTION_LABEL ) );
1850 _label_direction_cbmi.setToolTipText( LABEL_DIRECTION_TIP );
1851 _options_jmenu.add( _screen_antialias_cbmi = new JCheckBoxMenuItem( SCREEN_ANTIALIAS_LABEL ) );
1852 _options_jmenu.add( _background_gradient_cbmi = new JCheckBoxMenuItem( BG_GRAD_LABEL ) );
1853 _options_jmenu.add( _cycle_node_shape_mi = new JMenuItem( MainFrame.CYCLE_NODE_SHAPE_LABEL ) );
1854 _options_jmenu.add( _cycle_node_fill_mi = new JMenuItem( MainFrame.CYCLE_NODE_FILL_LABEL ) );
1855 _options_jmenu.add( _choose_node_size_mi = new JMenuItem( MainFrame.CHOOSE_NODE_SIZE_LABEL ) );
1856 _options_jmenu.add( _choose_minimal_confidence_mi = new JMenuItem( "" ) );
1857 _options_jmenu.add( _overview_placment_mi = new JMenuItem( "" ) );
1858 _options_jmenu.add( _switch_colors_mi = new JMenuItem( "" ) );
1859 _options_jmenu.add( _choose_font_mi = new JMenuItem( "" ) );
1860 _options_jmenu.addSeparator();
1861 _options_jmenu.add( _cycle_data_return = new JMenuItem( "Cycle Data Return" ) );
1862 _options_jmenu.addSeparator();
1863 _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( SEARCH_SUBHEADER ), getConfiguration() ) );
1864 _options_jmenu.add( _search_case_senstive_cbmi = new JCheckBoxMenuItem( SEARCH_CASE_SENSITIVE_LABEL ) );
1865 _options_jmenu.add( _search_whole_words_only_cbmi = new JCheckBoxMenuItem( SEARCH_TERMS_ONLY_LABEL ) );
1866 _options_jmenu.add( _search_with_regex_cbmi = new JCheckBoxMenuItem( MainFrame.SEARCH_REGEX_LABEL ) );
1867 _search_with_regex_cbmi.setToolTipText( MainFrame.SEARCH_WITH_REGEX_TIP );
1868 _options_jmenu.add( _inverse_search_result_cbmi = new JCheckBoxMenuItem( INVERSE_SEARCH_RESULT_LABEL ) );
1870 .add( _color_all_found_nodes_when_coloring_subtree_cbmi = new JCheckBoxMenuItem( "Colorize All Found Nodes When Colorizing Subtree(s)" ) );
1871 _options_jmenu.addSeparator();
1873 .add( customizeMenuItemAsLabel( new JMenuItem( "Graphics Export & Printing:" ), getConfiguration() ) );
1874 _options_jmenu.add( _antialias_print_cbmi = new JCheckBoxMenuItem( "Antialias" ) );
1875 _options_jmenu.add( _print_black_and_white_cbmi = new JCheckBoxMenuItem( "Export in Black and White" ) );
1877 .add( _graphics_export_visible_only_cbmi = new JCheckBoxMenuItem( "Limit to Visible ('Screenshot') for PNG, JPG, and GIF export" ) );
1878 _options_jmenu.add( _choose_pdf_width_mi = new JMenuItem( "" ) );
1879 _options_jmenu.addSeparator();
1880 _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Newick/NHX/Nexus Read:" ), getConfiguration() ) );
1882 .add( _internal_number_are_confidence_for_nh_parsing_cbmi = new JCheckBoxMenuItem( "Internal Node Names are Confidence Values" ) );
1883 _options_jmenu.add( _replace_underscores_cbmi = new JCheckBoxMenuItem( "Replace Underscores with Spaces" ) );
1885 .add( _parse_beast_style_extended_nexus_tags_cbmi = new JCheckBoxMenuItem( "Parse BEAST-style extended Newick/Nexus tags" ) );
1886 _parse_beast_style_extended_nexus_tags_cbmi
1887 .setToolTipText( "to parse elements in the form of \"[&!color=#800080]\" in Newick/Nexus formatted trees" );
1889 .add( _allow_errors_in_distance_to_parent_cbmi = new JCheckBoxMenuItem( "Ignore Distance Values Format Errors" ) );
1890 _options_jmenu.add( _extract_taxonomy_no_rbmi = new JRadioButtonMenuItem( "No Taxonomy Extraction" ) );
1892 .add( _extract_taxonomy_pfam_strict_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style Node Names" ) );
1894 .add( _extract_taxonomy_pfam_relaxed_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style like Node Names" ) );
1896 .add( _extract_taxonomy_agressive_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids/Scientific Names from Node Names" ) );
1897 _extract_taxonomy_pfam_strict_rbmi
1898 .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"BCL2_MOUSE/123-304\" or \"BCL2_10090/123-304\"" );
1899 _extract_taxonomy_pfam_relaxed_rbmi
1900 .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"bax_MOUSE\" or \"bax_10090\"" );
1901 _extract_taxonomy_agressive_rbmi
1902 .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\"" );
1903 _radio_group_2 = new ButtonGroup();
1904 _radio_group_2.add( _extract_taxonomy_no_rbmi );
1905 _radio_group_2.add( _extract_taxonomy_pfam_strict_rbmi );
1906 _radio_group_2.add( _extract_taxonomy_pfam_relaxed_rbmi );
1907 _radio_group_2.add( _extract_taxonomy_agressive_rbmi );
1908 _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Newick/Nexus Save:" ), getConfiguration() ) );
1910 .add( _use_brackets_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_BRACKETS_FOR_CONF_IN_NH_LABEL ) );
1911 _use_brackets_for_conf_in_nh_export_cbmi
1912 .setToolTipText( "e.g. \"0.1[90]\" for a branch with support 90 and a length of 0.1" );
1914 .add( _use_internal_names_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_INTERNAL_NAMES_FOR_CONF_IN_NH_LABEL ) );
1915 customizeJMenuItem( _choose_font_mi );
1916 customizeJMenuItem( _choose_minimal_confidence_mi );
1917 customizeJMenuItem( _switch_colors_mi );
1918 customizeJMenuItem( _choose_pdf_width_mi );
1919 customizeJMenuItem( _overview_placment_mi );
1920 customizeCheckBoxMenuItem( _show_default_node_shapes_external_cbmi,
1921 getOptions().isShowDefaultNodeShapesExternal() );
1922 customizeCheckBoxMenuItem( _show_default_node_shapes_internal_cbmi,
1923 getOptions().isShowDefaultNodeShapesInternal() );
1924 customizeCheckBoxMenuItem( _show_default_node_shapes_for_marked_cbmi,
1925 getOptions().isShowDefaultNodeShapesForMarkedNodes() );
1926 customizeJMenuItem( _cycle_node_shape_mi );
1927 customizeJMenuItem( _cycle_node_fill_mi );
1928 customizeJMenuItem( _choose_node_size_mi );
1929 customizeJMenuItem( _cycle_data_return );
1930 customizeCheckBoxMenuItem( _color_labels_same_as_parent_branch,
1931 getOptions().isColorLabelsSameAsParentBranch() );
1932 customizeCheckBoxMenuItem( _color_by_taxonomic_group_cbmi, getOptions().isColorByTaxonomicGroup() );
1933 customizeCheckBoxMenuItem( _screen_antialias_cbmi, getOptions().isAntialiasScreen() );
1934 customizeCheckBoxMenuItem( _background_gradient_cbmi, getOptions().isBackgroundColorGradient() );
1935 customizeCheckBoxMenuItem( _show_domain_labels, getOptions().isShowDomainLabels() );
1936 customizeCheckBoxMenuItem( _show_annotation_ref_source, getOptions().isShowAnnotationRefSource() );
1937 customizeCheckBoxMenuItem( _abbreviate_scientific_names, getOptions().isAbbreviateScientificTaxonNames() );
1938 customizeCheckBoxMenuItem( _search_case_senstive_cbmi, getOptions().isSearchCaseSensitive() );
1939 customizeCheckBoxMenuItem( _show_scale_cbmi, getOptions().isShowScale() );
1940 customizeCheckBoxMenuItem( _collapsed_with_average_height_cbmi, getOptions().isCollapsedWithAverageHeigh() );
1941 customizeCheckBoxMenuItem( _show_abbreviated_labels_for_collapsed_nodes_cbmi, getOptions().isShowAbbreviatedLabelsForCollapsedNodes() );
1943 customizeRadioButtonMenuItem( _non_lined_up_cladograms_rbmi,
1944 getOptions().getCladogramType() == CLADOGRAM_TYPE.NON_LINED_UP );
1945 customizeRadioButtonMenuItem( _ext_node_dependent_cladogram_rbmi,
1946 getOptions().getCladogramType() == CLADOGRAM_TYPE.LINED_UP );
1947 customizeCheckBoxMenuItem( _show_overview_cbmi, getOptions().isShowOverview() );
1948 customizeCheckBoxMenuItem( _label_direction_cbmi,
1949 getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL );
1950 customizeCheckBoxMenuItem( _antialias_print_cbmi, getOptions().isAntialiasPrint() );
1951 customizeCheckBoxMenuItem( _print_black_and_white_cbmi, getOptions().isPrintBlackAndWhite() );
1952 customizeCheckBoxMenuItem( _internal_number_are_confidence_for_nh_parsing_cbmi,
1953 getOptions().isInternalNumberAreConfidenceForNhParsing() );
1954 customizeRadioButtonMenuItem( _extract_taxonomy_no_rbmi,
1955 getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.NO );
1956 customizeRadioButtonMenuItem( _extract_taxonomy_pfam_strict_rbmi,
1957 getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT );
1958 customizeRadioButtonMenuItem( _extract_taxonomy_pfam_relaxed_rbmi,
1959 getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.PFAM_STYLE_RELAXED );
1960 customizeRadioButtonMenuItem( _extract_taxonomy_agressive_rbmi,
1961 getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.AGGRESSIVE );
1962 customizeCheckBoxMenuItem( _replace_underscores_cbmi, getOptions().isReplaceUnderscoresInNhParsing() );
1963 customizeCheckBoxMenuItem( _allow_errors_in_distance_to_parent_cbmi,
1964 getOptions().isReplaceUnderscoresInNhParsing() );
1965 customizeCheckBoxMenuItem( _search_with_regex_cbmi, getOptions().isSearchWithRegex() );
1966 customizeCheckBoxMenuItem( _search_whole_words_only_cbmi, getOptions().isMatchWholeTermsOnly() );
1967 customizeCheckBoxMenuItem( _inverse_search_result_cbmi, getOptions().isInverseSearchResult() );
1968 customizeCheckBoxMenuItem( _color_all_found_nodes_when_coloring_subtree_cbmi,
1969 getOptions().isColorAllFoundNodesWhenColoringSubtree() );
1970 customizeCheckBoxMenuItem( _parse_beast_style_extended_nexus_tags_cbmi,
1971 getOptions().isParseBeastStyleExtendedNexusTags() );
1972 customizeCheckBoxMenuItem( _graphics_export_visible_only_cbmi, getOptions().isGraphicsExportVisibleOnly() );
1973 customizeCheckBoxMenuItem( _show_confidence_stddev_cbmi, getOptions().isShowConfidenceStddev() );
1974 customizeCheckBoxMenuItem( _use_brackets_for_conf_in_nh_export_cbmi,
1976 .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.IN_SQUARE_BRACKETS );
1977 customizeCheckBoxMenuItem( _use_internal_names_for_conf_in_nh_export_cbmi,
1979 .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.AS_INTERNAL_NODE_NAMES );
1980 customizeCheckBoxMenuItem( _line_up_renderable_data_cbmi, getOptions().isLineUpRendarableNodeData() );
1981 customizeCheckBoxMenuItem( _right_line_up_domains_cbmi, getOptions().isRightLineUpDomains() );
1982 _jmenubar.add( _options_jmenu );
1985 void buildPhylogeneticInferenceMenu() {
1986 final InferenceManager im = getInferenceManager();
1987 _inference_menu = MainFrame.createMenu( "Inference", getConfiguration() );
1988 _inference_menu.add( _inference_from_msa_item = new JMenuItem( "From Multiple Sequence Alignment..." ) );
1989 customizeJMenuItem( _inference_from_msa_item );
1990 _inference_from_msa_item.setToolTipText( "Basic phylogenetic inference from MSA" );
1991 if ( im.canDoMsa() ) {
1992 _inference_menu.add( _inference_from_seqs_item = new JMenuItem( "From Unaligned Sequences..." ) );
1993 customizeJMenuItem( _inference_from_seqs_item );
1994 _inference_from_seqs_item
1995 .setToolTipText( "Basic phylogenetic inference including multiple sequence alignment" );
1999 .add( _inference_from_seqs_item = new JMenuItem( "From Unaligned Sequences (no program found)" ) );
2000 customizeJMenuItem( _inference_from_seqs_item );
2001 _inference_from_seqs_item.setEnabled( false );
2003 _jmenubar.add( _inference_menu );
2006 void buildToolsMenu() {
2007 _tools_menu = createMenu( "Tools", getConfiguration() );
2008 _tools_menu.add( _confcolor_item = new JMenuItem( "Colorize Branches Depending on Confidence" ) );
2009 customizeJMenuItem( _confcolor_item );
2010 _tools_menu.add( _color_rank_jmi = new JMenuItem( "Colorize Subtrees via Taxonomic Rank" ) );
2011 customizeJMenuItem( _color_rank_jmi );
2012 _color_rank_jmi.setToolTipText( "for example, at \"Class\" level, colorize mammal specific subtree red" );
2013 _tools_menu.add( _taxcolor_item = new JMenuItem( "Taxonomy Colorize Branches" ) );
2014 customizeJMenuItem( _taxcolor_item );
2015 _tools_menu.addSeparator();
2016 _tools_menu.add( _remove_visual_styles_item = new JMenuItem( "Delete All Visual Styles From Nodes" ) );
2017 _remove_visual_styles_item
2018 .setToolTipText( "To remove all node visual styles (fonts, colors) from the current phylogeny" );
2019 customizeJMenuItem( _remove_visual_styles_item );
2020 _tools_menu.add( _remove_branch_color_item = new JMenuItem( "Delete All Colors From Branches" ) );
2021 _remove_branch_color_item.setToolTipText( "To remove all branch color values from the current phylogeny" );
2022 customizeJMenuItem( _remove_branch_color_item );
2023 _tools_menu.addSeparator();
2024 _tools_menu.add( _annotate_item = new JMenuItem( "Annotate Sequences of Selected Nodes" ) );
2025 customizeJMenuItem( _annotate_item );
2026 _tools_menu.addSeparator();
2027 _tools_menu.add( _midpoint_root_item = new JMenuItem( "Midpoint-Root" ) );
2028 customizeJMenuItem( _midpoint_root_item );
2029 _tools_menu.addSeparator();
2030 _tools_menu.add( _delete_selected_nodes_item = new JMenuItem( "Delete Selected Nodes" ) );
2031 _delete_selected_nodes_item.setToolTipText( "To delete all selected external nodes" );
2032 customizeJMenuItem( _delete_selected_nodes_item );
2033 _tools_menu.add( _delete_not_selected_nodes_item = new JMenuItem( "Retain Selected Nodes" ) );
2034 _delete_not_selected_nodes_item.setToolTipText( "To delete all not selected external nodes" );
2035 customizeJMenuItem( _delete_not_selected_nodes_item );
2036 _tools_menu.addSeparator();
2037 _tools_menu.add( _collapse_species_specific_subtrees = new JMenuItem( "Collapse Single Taxonomy-Subtrees" ) );
2038 customizeJMenuItem( _collapse_species_specific_subtrees );
2039 _collapse_species_specific_subtrees.setToolTipText( "To (reversibly) collapse subtrees associated with only one taxonomy (such as species specific subtrees)" );
2041 .add( _collapse_below_threshold = new JMenuItem( "Collapse Branches with Confidence Below Threshold into Multifurcations" ) );
2042 customizeJMenuItem( _collapse_below_threshold );
2043 _collapse_below_threshold
2044 .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)" );
2047 .add( _collapse_below_branch_length = new JMenuItem( "Collapse Branches with Branch Lengths Below Threshold into Multifurcations" ) );
2048 customizeJMenuItem( _collapse_below_branch_length );
2049 _collapse_below_branch_length
2050 .setToolTipText( "To (permanently) collapse branches with branches with branch lengths below a threshold into multifurcations" );
2052 _tools_menu.addSeparator();
2054 .add( _extract_tax_code_from_node_names_jmi = new JMenuItem( "Extract Taxonomic Data from Node Names" ) );
2055 customizeJMenuItem( _extract_tax_code_from_node_names_jmi );
2056 _extract_tax_code_from_node_names_jmi
2057 .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'" );
2059 .add( _move_node_names_to_tax_sn_jmi = new JMenuItem( "Transfer Node Names to Taxonomic Scientific Names" ) );
2060 customizeJMenuItem( _move_node_names_to_tax_sn_jmi );
2061 _move_node_names_to_tax_sn_jmi.setToolTipText( "To interpret node names as taxonomic scientific names" );
2062 _tools_menu.add( _move_node_names_to_seq_names_jmi = new JMenuItem( "Transfer Node Names to Sequence Names" ) );
2063 customizeJMenuItem( _move_node_names_to_seq_names_jmi );
2064 _move_node_names_to_seq_names_jmi.setToolTipText( "To interpret node names as sequence (protein, gene) names" );
2065 _tools_menu.addSeparator();
2066 _tools_menu.add( _obtain_seq_information_jmi = new JMenuItem( "Obtain Sequence Information" ) );
2067 customizeJMenuItem( _obtain_seq_information_jmi );
2068 _obtain_seq_information_jmi.setToolTipText( "To add additional sequence information" );
2070 .add( _obtain_detailed_taxonomic_information_jmi = new JMenuItem( OBTAIN_DETAILED_TAXONOMIC_INFORMATION ) );
2071 customizeJMenuItem( _obtain_detailed_taxonomic_information_jmi );
2072 _obtain_detailed_taxonomic_information_jmi
2073 .setToolTipText( "To add additional taxonomic information (from UniProt Taxonomy)" );
2075 .add( _obtain_detailed_taxonomic_information_deleting_jmi = new JMenuItem( "Obtain Detailed Taxonomic Information (deletes nodes!)" ) );
2076 customizeJMenuItem( _obtain_detailed_taxonomic_information_deleting_jmi );
2077 _obtain_detailed_taxonomic_information_deleting_jmi
2078 .setToolTipText( "To add additional taxonomic information, deletes nodes for which taxonomy cannot found (from UniProt Taxonomy)" );
2079 _tools_menu.addSeparator();
2080 _tools_menu.add( _read_values_jmi = new JMenuItem( "Attach Vector/Expression Values" ) );
2081 customizeJMenuItem( _read_values_jmi );
2082 _read_values_jmi.setToolTipText( "To attach vector (e.g. gene expression) values to tree nodes (beta)" );
2083 _jmenubar.add( _tools_menu );
2084 _tools_menu.add( _read_seqs_jmi = new JMenuItem( "Attach Molecular Sequences" ) );
2085 customizeJMenuItem( _read_seqs_jmi );
2087 .setToolTipText( "To attach molecular sequences to tree nodes (from Fasta-formatted file) (beta)" );
2088 _jmenubar.add( _tools_menu );
2093 if ( isUnsavedDataPresent() ) {
2094 final int r = JOptionPane.showConfirmDialog( this,
2095 "Exit despite potentially unsaved changes?",
2097 JOptionPane.YES_NO_OPTION );
2098 if ( r != JOptionPane.YES_OPTION ) {
2106 removeAllTextFrames();
2107 _mainpanel.terminate();
2108 _contentpane.removeAll();
2109 setVisible( false );
2111 // System.exit( 0 ); //TODO reconfirm that this is OK, then remove.
2114 void readPhylogeniesFromURL() {
2116 Phylogeny[] phys = null;
2117 final String message = "Please enter a complete URL, for example \"http://purl.org/phylo/treebase/phylows/study/TB2:S15480?format=nexus\"";
2118 final String url_string = JOptionPane
2119 .showInputDialog( this,
2121 "Use URL/webservice to obtain a phylogeny",
2122 JOptionPane.QUESTION_MESSAGE );
2123 boolean nhx_or_nexus = false;
2124 if ( ( url_string != null ) && ( url_string.length() > 0 ) ) {
2126 url = new URL( url_string );
2127 PhylogenyParser parser = null;
2128 if ( url.getHost().toLowerCase().indexOf( "tolweb" ) >= 0 ) {
2129 parser = new TolParser();
2132 parser = ParserUtils
2133 .createParserDependingOnUrlContents( url,
2134 getConfiguration().isValidatePhyloXmlAgainstSchema() );
2136 if ( parser instanceof NexusPhylogeniesParser ) {
2137 nhx_or_nexus = true;
2139 else if ( parser instanceof NHXParser ) {
2140 nhx_or_nexus = true;
2142 if ( _mainpanel.getCurrentTreePanel() != null ) {
2143 _mainpanel.getCurrentTreePanel().setWaitCursor();
2146 _mainpanel.setWaitCursor();
2148 final PhylogenyFactory factory = ParserBasedPhylogenyFactory.getInstance();
2149 phys = factory.create( url.openStream(), parser );
2151 catch ( final MalformedURLException e ) {
2152 JOptionPane.showMessageDialog( this,
2153 "Malformed URL: " + url + "\n" + e.getLocalizedMessage(),
2155 JOptionPane.ERROR_MESSAGE );
2157 catch ( final IOException e ) {
2158 JOptionPane.showMessageDialog( this,
2159 "Could not read from " + url + "\n"
2160 + ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ),
2161 "Failed to read URL",
2162 JOptionPane.ERROR_MESSAGE );
2164 catch ( final Exception e ) {
2165 JOptionPane.showMessageDialog( this,
2166 ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ),
2167 "Unexpected Exception",
2168 JOptionPane.ERROR_MESSAGE );
2171 if ( _mainpanel.getCurrentTreePanel() != null ) {
2172 _mainpanel.getCurrentTreePanel().setArrowCursor();
2175 _mainpanel.setArrowCursor();
2178 if ( ( phys != null ) && ( phys.length > 0 ) ) {
2179 if ( nhx_or_nexus && getOptions().isInternalNumberAreConfidenceForNhParsing() ) {
2180 for( final Phylogeny phy : phys ) {
2181 PhylogenyMethods.transferInternalNodeNamesToConfidence( phy, "" );
2184 AptxUtil.addPhylogeniesToTabs( phys,
2185 new File( url.getFile() ).getName(),
2186 new File( url.getFile() ).toString(),
2189 _mainpanel.getControlPanel().showWhole();
2192 activateSaveAllIfNeeded();
2196 void setMsa( final Msa msa ) {
2200 void setMsaFile( final File msa_file ) {
2201 _msa_file = msa_file;
2204 void setSeqs( final List<MolecularSequence> seqs ) {
2208 void setSeqsFile( final File seqs_file ) {
2209 _seqs_file = seqs_file;
2212 public static MainFrameApplication createInstance( final Phylogeny[] phys, final Configuration config ) {
2213 return new MainFrameApplication( phys, config );
2216 public static MainFrame createInstance( final Phylogeny[] phys,
2217 final Configuration config,
2219 final File current_dir ) {
2220 return new MainFrameApplication( phys, config, title, current_dir );
2223 static MainFrame createInstance( final Phylogeny[] phys, final Configuration config, final String title ) {
2224 return new MainFrameApplication( phys, config, title );
2227 static MainFrame createInstance( final Phylogeny[] phys, final String config_file_name, final String title ) {
2228 return new MainFrameApplication( phys, config_file_name, title );
2231 static void warnIfNotPhyloXmlValidation( final Configuration c ) {
2232 if ( !c.isValidatePhyloXmlAgainstSchema() ) {
2233 JOptionPane.showMessageDialog( null,
2234 ForesterUtil.wordWrap(
2235 "phyloXML XSD-based validation is turned off [enable with line 'validate_against_phyloxml_xsd_schem: true' in configuration file]",
2238 JOptionPane.WARNING_MESSAGE );
2241 } // MainFrameApplication.