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 = 800;
107 private final static int FRAME_Y_SIZE = 800;
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() ) {
764 if ( node.getNodeData().getProperties() != null ) {
765 node.getNodeData().getProperties()
766 .removePropertiesWithGivenReferencePrefix( PhyloXmlUtil.VECTOR_PROPERTY_REF );
768 node.getNodeData().setVector( l );
772 if ( not_found > 0 ) {
774 .showMessageDialog( this,
775 "Could not fine expression values for " + not_found + " external node(s)",
777 JOptionPane.WARNING_MESSAGE );
779 getCurrentTreePanel().setStatisticsForExpressionValues( stats );
783 private void addSequencesFromFile() {
784 if ( ( getCurrentTreePanel() == null ) || ( getCurrentTreePanel().getPhylogeny() == null ) ) {
785 JOptionPane.showMessageDialog( this,
786 "Need to load evolutionary tree first",
787 "Can Not Read Sequences",
788 JOptionPane.WARNING_MESSAGE );
791 final File my_dir = getCurrentDir();
792 if ( my_dir != null ) {
793 _sequences_filechooser.setCurrentDirectory( my_dir );
795 final int result = _sequences_filechooser.showOpenDialog( _contentpane );
796 final File file = _sequences_filechooser.getSelectedFile();
797 List<MolecularSequence> seqs = null;
798 if ( ( file != null ) && !file.isDirectory() && ( result == JFileChooser.APPROVE_OPTION ) ) {
800 final FileInputStream fis1 = new FileInputStream( file );
801 if ( FastaParser.isLikelyFasta( fis1 ) ) {
802 final FileInputStream fis2 = new FileInputStream( file );
803 seqs = FastaParser.parse( fis2 );
807 catch ( final Exception e ) {
812 JOptionPane.showMessageDialog( this,
813 "Format does not appear to be Fasta",
814 "Multiple sequence file format error",
815 JOptionPane.ERROR_MESSAGE );
821 catch ( final Exception e ) {
825 catch ( final MsaFormatException e ) {
827 JOptionPane.showMessageDialog( this,
828 e.getLocalizedMessage(),
829 "Multiple sequence file format error",
830 JOptionPane.ERROR_MESSAGE );
833 catch ( final IOException e ) {
835 JOptionPane.showMessageDialog( this,
836 e.getLocalizedMessage(),
837 "Failed to read multiple sequence file",
838 JOptionPane.ERROR_MESSAGE );
841 catch ( final Exception e ) {
844 JOptionPane.showMessageDialog( this,
845 e.getLocalizedMessage(),
846 "Unexpected error during reading of multiple sequence file",
847 JOptionPane.ERROR_MESSAGE );
850 if ( ( seqs == null ) || ( seqs.size() < 1 ) ) {
851 JOptionPane.showMessageDialog( this,
852 "Multiple sequence file is empty",
853 "Empty multiple sequence file",
854 JOptionPane.ERROR_MESSAGE );
859 if ( seqs != null ) {
860 for( final MolecularSequence seq : seqs ) {
861 System.out.println( seq.getIdentifier() );
863 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
864 int total_counter = 0;
865 int attached_counter = 0;
866 for( final MolecularSequence seq : seqs ) {
868 final String seq_name = seq.getIdentifier();
869 if ( !ForesterUtil.isEmpty( seq_name ) ) {
870 List<PhylogenyNode> nodes = phy.getNodesViaSequenceName( seq_name );
871 if ( nodes.isEmpty() ) {
872 nodes = phy.getNodesViaSequenceSymbol( seq_name );
874 if ( nodes.isEmpty() ) {
875 nodes = phy.getNodesViaGeneName( seq_name );
877 if ( nodes.isEmpty() ) {
878 nodes = phy.getNodes( seq_name );
880 if ( nodes.size() > 1 ) {
881 JOptionPane.showMessageDialog( this,
882 "Sequence name \"" + seq_name + "\" is not unique",
883 "Sequence name not unique",
884 JOptionPane.ERROR_MESSAGE );
888 final String[] a = seq_name.split( "\\s" );
889 if ( nodes.isEmpty() && ( a.length > 1 ) ) {
890 final String seq_name_split = a[ 0 ];
891 nodes = phy.getNodesViaSequenceName( seq_name_split );
892 if ( nodes.isEmpty() ) {
893 nodes = phy.getNodesViaSequenceSymbol( seq_name_split );
895 if ( nodes.isEmpty() ) {
896 nodes = phy.getNodes( seq_name_split );
898 if ( nodes.size() > 1 ) {
899 JOptionPane.showMessageDialog( this,
900 "Split sequence name \"" + seq_name_split
901 + "\" is not unique",
902 "Sequence name not unique",
903 JOptionPane.ERROR_MESSAGE );
908 if ( nodes.size() == 1 ) {
910 final PhylogenyNode n = nodes.get( 0 );
911 if ( !n.getNodeData().isHasSequence() ) {
912 n.getNodeData().addSequence( new org.forester.phylogeny.data.Sequence() );
914 n.getNodeData().getSequence().setMolecularSequence( seq.getMolecularSequenceAsString() );
915 if ( ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) {
916 n.getNodeData().getSequence().setName( seq_name );
921 if ( attached_counter > 0 ) {
923 int ext_nodes_with_seq = 0;
924 for( final PhylogenyNodeIterator iter = phy.iteratorExternalForward(); iter.hasNext(); ) {
926 final PhylogenyNode n = iter.next();
927 if ( n.getNodeData().isHasSequence()
928 && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) {
929 ++ext_nodes_with_seq;
933 if ( ext_nodes == ext_nodes_with_seq ) {
934 s = "All " + ext_nodes_with_seq + " external nodes now have a molecular sequence attached to them.";
937 s = ext_nodes_with_seq + " out of " + ext_nodes
938 + " external nodes now have a molecular sequence attached to them.";
940 if ( ( attached_counter == total_counter ) && ( ext_nodes == ext_nodes_with_seq ) ) {
941 JOptionPane.showMessageDialog( this,
942 "Attached all " + total_counter + " sequences to tree nodes.\n" + s,
943 "All sequences attached",
944 JOptionPane.INFORMATION_MESSAGE );
947 JOptionPane.showMessageDialog( this,
948 "Attached " + attached_counter + " sequences out of a total of "
949 + total_counter + " sequences.\n" + s,
950 attached_counter + " sequences attached",
951 JOptionPane.WARNING_MESSAGE );
955 JOptionPane.showMessageDialog( this,
956 "No maching tree node for any of the " + total_counter + " sequences",
957 "Could not attach any sequences",
958 JOptionPane.ERROR_MESSAGE );
963 private void closeCurrentPane() {
964 if ( getMainPanel().getCurrentTreePanel() != null ) {
965 if ( getMainPanel().getCurrentTreePanel().isEdited() ) {
966 final int r = JOptionPane.showConfirmDialog( this,
967 "Close tab despite potentially unsaved changes?",
969 JOptionPane.YES_NO_OPTION );
970 if ( r != JOptionPane.YES_OPTION ) {
974 getMainPanel().closeCurrentPane();
975 activateSaveAllIfNeeded();
979 private void collapseBelowThreshold( final Phylogeny phy ) {
980 final PhylogenyNodeIterator it = phy.iteratorPostorder();
981 final List<PhylogenyNode> to_be_removed = new ArrayList<PhylogenyNode>();
982 double min_support = Double.MAX_VALUE;
983 boolean conf_present = false;
984 while ( it.hasNext() ) {
985 final PhylogenyNode n = it.next();
986 if ( !n.isExternal() && !n.isRoot() ) {
987 final List<Confidence> c = n.getBranchData().getConfidences();
988 if ( ( c != null ) && ( c.size() > 0 ) ) {
991 for( final Confidence confidence : c ) {
992 if ( confidence.getValue() > max ) {
993 max = confidence.getValue();
996 if ( max < getMinNotCollapseConfidenceValue() ) {
997 to_be_removed.add( n );
999 if ( max < min_support ) {
1005 if ( conf_present ) {
1006 for( final PhylogenyNode node : to_be_removed ) {
1007 PhylogenyMethods.removeNode( node, phy );
1009 if ( to_be_removed.size() > 0 ) {
1010 phy.externalNodesHaveChanged();
1011 phy.clearHashIdToNodeMap();
1012 phy.recalculateNumberOfExternalDescendants( true );
1013 getCurrentTreePanel().resetNodeIdToDistToLeafMap();
1014 getCurrentTreePanel().updateSetOfCollapsedExternalNodes();
1015 getCurrentTreePanel().calculateLongestExtNodeInfo();
1016 getCurrentTreePanel().setNodeInPreorderToNull();
1017 getCurrentTreePanel().recalculateMaxDistanceToRoot();
1018 getCurrentTreePanel().resetPreferredSize();
1019 getCurrentTreePanel().setEdited( true );
1020 getCurrentTreePanel().repaint();
1023 if ( to_be_removed.size() > 0 ) {
1024 JOptionPane.showMessageDialog( this,
1025 "Collapsed " + to_be_removed.size()
1026 + " branches with\nconfidence values below "
1027 + getMinNotCollapseConfidenceValue(),
1028 "Collapsed " + to_be_removed.size() + " branches",
1029 JOptionPane.INFORMATION_MESSAGE );
1032 JOptionPane.showMessageDialog( this,
1033 "No branch collapsed,\nminimum confidence value per branch is "
1035 "No branch collapsed",
1036 JOptionPane.INFORMATION_MESSAGE );
1040 JOptionPane.showMessageDialog( this,
1041 "No branch collapsed because no confidence values present",
1042 "No confidence values present",
1043 JOptionPane.INFORMATION_MESSAGE );
1047 private void collapseBelowBranchLengthThreshold() {
1048 if ( getCurrentTreePanel() != null ) {
1049 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1050 if ( ( phy != null ) && !phy.isEmpty() ) {
1051 final String s = ( String ) JOptionPane.showInputDialog( this,
1052 "Please enter the minimum branch length value\n",
1053 "Minimal Branch Length Value",
1054 JOptionPane.QUESTION_MESSAGE,
1057 getMinNotCollapseBlValue() );
1058 if ( !ForesterUtil.isEmpty( s ) ) {
1059 boolean success = true;
1061 final String m_str = s.trim();
1062 if ( !ForesterUtil.isEmpty( m_str ) ) {
1064 m = Double.parseDouble( m_str );
1066 catch ( final Exception ex ) {
1073 if ( success && ( m >= 0.0 ) ) {
1074 setMinNotCollapseBlValue( m );
1082 private void collapseBelowThreshold() {
1083 if ( getCurrentTreePanel() != null ) {
1084 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1085 if ( ( phy != null ) && !phy.isEmpty() ) {
1086 final String s = ( String ) JOptionPane.showInputDialog( this,
1087 "Please enter the minimum confidence value\n",
1088 "Minimal Confidence Value",
1089 JOptionPane.QUESTION_MESSAGE,
1092 getMinNotCollapseConfidenceValue() );
1093 if ( !ForesterUtil.isEmpty( s ) ) {
1094 boolean success = true;
1096 final String m_str = s.trim();
1097 if ( !ForesterUtil.isEmpty( m_str ) ) {
1099 m = Double.parseDouble( m_str );
1101 catch ( final Exception ex ) {
1108 if ( success && ( m >= 0.0 ) ) {
1109 setMinNotCollapseConfidenceValue( m );
1110 collapseBelowThreshold( phy );
1117 private void collapseBl( final Phylogeny phy ) {
1118 final PhylogenyNodeIterator it = phy.iteratorPostorder();
1119 final List<PhylogenyNode> to_be_removed = new ArrayList<PhylogenyNode>();
1120 double min_bl = Double.MAX_VALUE;
1121 boolean bl_present = false;
1122 while ( it.hasNext() ) {
1123 final PhylogenyNode n = it.next();
1124 if ( !n.isExternal() && !n.isRoot() ) {
1125 final double bl = n.getDistanceToParent();
1126 if ( bl != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) {
1128 if ( bl < getMinNotCollapseBlValue() ) {
1129 to_be_removed.add( n );
1131 if ( bl < min_bl ) {
1138 for( final PhylogenyNode node : to_be_removed ) {
1139 PhylogenyMethods.removeNode( node, phy );
1141 if ( to_be_removed.size() > 0 ) {
1142 phy.externalNodesHaveChanged();
1143 phy.clearHashIdToNodeMap();
1144 phy.recalculateNumberOfExternalDescendants( true );
1145 getCurrentTreePanel().resetNodeIdToDistToLeafMap();
1146 getCurrentTreePanel().updateSetOfCollapsedExternalNodes();
1147 getCurrentTreePanel().calculateLongestExtNodeInfo();
1148 getCurrentTreePanel().setNodeInPreorderToNull();
1149 getCurrentTreePanel().recalculateMaxDistanceToRoot();
1150 getCurrentTreePanel().resetPreferredSize();
1151 getCurrentTreePanel().setEdited( true );
1152 getCurrentTreePanel().repaint();
1155 if ( to_be_removed.size() > 0 ) {
1156 JOptionPane.showMessageDialog( this,
1157 "Collapsed " + to_be_removed.size()
1158 + " branches with\nbranch length values below "
1159 + getMinNotCollapseBlValue(),
1160 "Collapsed " + to_be_removed.size() + " branches",
1161 JOptionPane.INFORMATION_MESSAGE );
1164 JOptionPane.showMessageDialog( this,
1165 "No branch collapsed,\nminimum branch length is " + min_bl,
1166 "No branch collapsed",
1167 JOptionPane.INFORMATION_MESSAGE );
1171 JOptionPane.showMessageDialog( this,
1172 "No branch collapsed because no branch length values present",
1173 "No branch length values present",
1174 JOptionPane.INFORMATION_MESSAGE );
1178 private PhyloXmlParser createPhyloXmlParser() {
1179 PhyloXmlParser xml_parser = null;
1180 if ( getConfiguration().isValidatePhyloXmlAgainstSchema() ) {
1182 xml_parser = PhyloXmlParser.createPhyloXmlParserXsdValidating();
1184 catch ( final Exception e ) {
1185 JOptionPane.showMessageDialog( this,
1186 e.getLocalizedMessage(),
1187 "failed to create validating XML parser",
1188 JOptionPane.WARNING_MESSAGE );
1191 if ( xml_parser == null ) {
1192 xml_parser = PhyloXmlParser.createPhyloXmlParser();
1197 private void executePhyleneticInference( final boolean from_unaligned_seqs ) {
1198 final PhyloInferenceDialog dialog = new PhyloInferenceDialog( this,
1199 getPhylogeneticInferenceOptions(),
1200 from_unaligned_seqs );
1202 if ( dialog.getValue() == JOptionPane.OK_OPTION ) {
1203 if ( !from_unaligned_seqs ) {
1204 if ( getMsa() != null ) {
1205 final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getMsa(),
1206 getPhylogeneticInferenceOptions()
1209 new Thread( inferrer ).start();
1212 JOptionPane.showMessageDialog( this,
1213 "No multiple sequence alignment selected",
1214 "Phylogenetic Inference Not Launched",
1215 JOptionPane.WARNING_MESSAGE );
1219 if ( getSeqs() != null ) {
1220 final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getSeqs(),
1221 getPhylogeneticInferenceOptions()
1224 new Thread( inferrer ).start();
1227 JOptionPane.showMessageDialog( this,
1228 "No input sequences selected",
1229 "Phylogenetic Inference Not Launched",
1230 JOptionPane.WARNING_MESSAGE );
1236 private void extractTaxDataFromNodeNames() throws PhyloXmlDataFormatException {
1237 final StringBuilder sb = new StringBuilder();
1238 final StringBuilder sb_failed = new StringBuilder();
1240 int counter_failed = 0;
1241 if ( getCurrentTreePanel() != null ) {
1242 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1243 if ( ( phy != null ) && !phy.isEmpty() ) {
1244 final PhylogenyNodeIterator it = phy.iteratorExternalForward();
1245 while ( it.hasNext() ) {
1246 final PhylogenyNode n = it.next();
1247 final String name = n.getName().trim();
1248 if ( !ForesterUtil.isEmpty( name ) ) {
1249 final String nt = ParserUtils.extractTaxonomyDataFromNodeName( n,
1250 TAXONOMY_EXTRACTION.AGGRESSIVE );
1251 if ( !ForesterUtil.isEmpty( nt ) ) {
1252 if ( counter < 15 ) {
1253 sb.append( name + ": " + nt + "\n" );
1255 else if ( counter == 15 ) {
1256 sb.append( "...\n" );
1261 if ( counter_failed < 15 ) {
1262 sb_failed.append( name + "\n" );
1264 else if ( counter_failed == 15 ) {
1265 sb_failed.append( "...\n" );
1271 if ( counter > 0 ) {
1273 String all = "all ";
1274 if ( counter_failed > 0 ) {
1276 failed = "\nCould not extract taxonomic data for " + counter_failed + " named external nodes:\n"
1279 JOptionPane.showMessageDialog( this,
1280 "Extracted taxonomic data from " + all + counter
1281 + " named external nodes:\n" + sb.toString() + failed,
1282 "Taxonomic Data Extraction Completed",
1283 counter_failed > 0 ? JOptionPane.WARNING_MESSAGE
1284 : JOptionPane.INFORMATION_MESSAGE );
1287 JOptionPane.showMessageDialog( this,
1288 "Could not extract any taxonomic data.\nMaybe node names are empty\n"
1289 + "or not in the forms \"XYZ_CAEEL\", \"XYZ_6239\", or \"XYZ_Caenorhabditis_elegans\"\n"
1290 + "or nodes already have taxonomic data?\n",
1291 "No Taxonomic Data Extracted",
1292 JOptionPane.ERROR_MESSAGE );
1298 private double getMinNotCollapseBlValue() {
1299 return _min_not_collapse_bl;
1302 private double getMinNotCollapseConfidenceValue() {
1303 return _min_not_collapse;
1306 private PhylogeneticInferenceOptions getPhylogeneticInferenceOptions() {
1307 if ( _phylogenetic_inference_options == null ) {
1308 _phylogenetic_inference_options = new PhylogeneticInferenceOptions();
1310 return _phylogenetic_inference_options;
1313 private boolean isUnsavedDataPresent() {
1314 final List<TreePanel> tps = getMainPanel().getTreePanels();
1315 for( final TreePanel tp : tps ) {
1316 if ( tp.isEdited() ) {
1323 private void moveNodeNamesToSeqNames() throws PhyloXmlDataFormatException {
1324 if ( getCurrentTreePanel() != null ) {
1325 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1326 if ( ( phy != null ) && !phy.isEmpty() ) {
1327 PhylogenyMethods.transferNodeNameToField( phy,
1328 PhylogenyMethods.PhylogenyNodeField.SEQUENCE_NAME,
1334 private void moveNodeNamesToTaxSn() throws PhyloXmlDataFormatException {
1335 if ( getCurrentTreePanel() != null ) {
1336 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1337 if ( ( phy != null ) && !phy.isEmpty() ) {
1338 PhylogenyMethods.transferNodeNameToField( phy,
1339 PhylogenyMethods.PhylogenyNodeField.TAXONOMY_SCIENTIFIC_NAME,
1345 private void newTree() {
1346 final Phylogeny[] phys = new Phylogeny[ 1 ];
1347 final Phylogeny phy = new Phylogeny();
1348 final PhylogenyNode node = new PhylogenyNode();
1349 phy.setRoot( node );
1350 phy.setRooted( true );
1352 AptxUtil.addPhylogeniesToTabs( phys, "", "", getConfiguration(), getMainPanel() );
1353 _mainpanel.getControlPanel().showWhole();
1354 _mainpanel.getCurrentTreePanel().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
1355 _mainpanel.getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
1356 if ( getMainPanel().getMainFrame() == null ) {
1357 // Must be "E" applet version.
1358 ( ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet() )
1359 .setSelectedTypeInTypeMenu( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
1362 getMainPanel().getMainFrame().setSelectedTypeInTypeMenu( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
1364 activateSaveAllIfNeeded();
1368 private void obtainDetailedTaxonomicInformation() {
1369 if ( getCurrentTreePanel() != null ) {
1370 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1371 if ( ( phy != null ) && !phy.isEmpty() ) {
1372 final TaxonomyDataManager t = new TaxonomyDataManager( this,
1373 _mainpanel.getCurrentTreePanel(),
1377 new Thread( t ).start();
1382 private void obtainDetailedTaxonomicInformationDelete() {
1383 if ( getCurrentTreePanel() != null ) {
1384 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1385 if ( ( phy != null ) && !phy.isEmpty() ) {
1386 final TaxonomyDataManager t = new TaxonomyDataManager( this,
1387 _mainpanel.getCurrentTreePanel(),
1391 new Thread( t ).start();
1396 private void obtainSequenceInformation() {
1397 if ( getCurrentTreePanel() != null ) {
1398 final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
1399 if ( ( phy != null ) && !phy.isEmpty() ) {
1400 final SequenceDataRetriver u = new SequenceDataRetriver( this,
1401 _mainpanel.getCurrentTreePanel(),
1403 new Thread( u ).start();
1408 private void preProcessTreesUponReading( final Phylogeny[] phys ) {
1409 for( final Phylogeny phy : phys ) {
1410 if ( ( phy != null ) && !phy.isEmpty() ) {
1411 for( final PhylogenyNodeIterator it = phy.iteratorPreorder(); it.hasNext(); ) {
1412 final PhylogenyNode n = it.next();
1413 if ( n.isExternal() ) {
1414 if ( n.getNodeData().isHasSequence() ) {
1415 final Sequence s = n.getNodeData().getSequence();
1416 if ( ForesterUtil.isEmpty( s.getGeneName() ) || s.getGeneName().startsWith( "LOC" ) ) {
1417 if ( ( s.getAccession() != null )
1418 && !ForesterUtil.isEmpty( s.getAccession().getValue() ) ) {
1419 s.setGeneName( s.getAccession().getValue() );
1421 else if ( !ForesterUtil.isEmpty( n.getName() ) ) {
1422 s.setGeneName( n.getName() );
1432 private void readPhylogeniesFromFile() {
1433 boolean exception = false;
1434 Phylogeny[] phys = null;
1435 // Set an initial directory if none set yet
1436 final File my_dir = getCurrentDir();
1437 // Open file-open dialog and set current directory
1438 if ( my_dir != null ) {
1439 _open_filechooser.setCurrentDirectory( my_dir );
1441 final int result = _open_filechooser.showOpenDialog( _contentpane );
1442 // All done: get the file
1443 final File[] files = _open_filechooser.getSelectedFiles();
1444 setCurrentDir( _open_filechooser.getCurrentDirectory() );
1445 boolean nhx_or_nexus = false;
1446 if ( ( files != null ) && ( files.length > 0 ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
1447 for( final File file : files ) {
1448 if ( ( file != null ) && !file.isDirectory() ) {
1449 if ( _mainpanel.getCurrentTreePanel() != null ) {
1450 _mainpanel.getCurrentTreePanel().setWaitCursor();
1453 _mainpanel.setWaitCursor();
1455 if ( ( _open_filechooser.getFileFilter() == MainFrame.nhfilter )
1456 || ( _open_filechooser.getFileFilter() == MainFrame.nhxfilter ) ) {
1458 final NHXParser nhx = new NHXParser();
1459 setSpecialOptionsForNhxParser( nhx );
1460 phys = PhylogenyMethods.readPhylogenies( nhx, file );
1461 nhx_or_nexus = true;
1463 catch ( final Exception e ) {
1465 exceptionOccuredDuringOpenFile( e );
1468 else if ( _open_filechooser.getFileFilter() == MainFrame.xmlfilter ) {
1469 warnIfNotPhyloXmlValidation( getConfiguration() );
1471 final PhyloXmlParser xml_parser = createPhyloXmlParser();
1472 phys = PhylogenyMethods.readPhylogenies( xml_parser, file );
1474 catch ( final Exception e ) {
1476 exceptionOccuredDuringOpenFile( e );
1479 else if ( _open_filechooser.getFileFilter() == MainFrame.tolfilter ) {
1481 phys = PhylogenyMethods.readPhylogenies( new TolParser(), file );
1483 catch ( final Exception e ) {
1485 exceptionOccuredDuringOpenFile( e );
1488 else if ( _open_filechooser.getFileFilter() == MainFrame.nexusfilter ) {
1490 final NexusPhylogeniesParser nex = new NexusPhylogeniesParser();
1491 setSpecialOptionsForNexParser( nex );
1492 phys = PhylogenyMethods.readPhylogenies( nex, file );
1493 nhx_or_nexus = true;
1495 catch ( final Exception e ) {
1497 exceptionOccuredDuringOpenFile( e );
1503 final PhylogenyParser parser = ParserUtils
1504 .createParserDependingOnFileType( file,
1506 .isValidatePhyloXmlAgainstSchema() );
1507 if ( parser instanceof NexusPhylogeniesParser ) {
1508 final NexusPhylogeniesParser nex = ( NexusPhylogeniesParser ) parser;
1509 setSpecialOptionsForNexParser( nex );
1510 nhx_or_nexus = true;
1512 else if ( parser instanceof NHXParser ) {
1513 final NHXParser nhx = ( NHXParser ) parser;
1514 setSpecialOptionsForNhxParser( nhx );
1515 nhx_or_nexus = true;
1517 else if ( parser instanceof PhyloXmlParser ) {
1518 warnIfNotPhyloXmlValidation( getConfiguration() );
1520 phys = PhylogenyMethods.readPhylogenies( parser, file );
1522 catch ( final Exception e ) {
1524 exceptionOccuredDuringOpenFile( e );
1527 if ( _mainpanel.getCurrentTreePanel() != null ) {
1528 _mainpanel.getCurrentTreePanel().setArrowCursor();
1531 _mainpanel.setArrowCursor();
1533 if ( !exception && ( phys != null ) && ( phys.length > 0 ) ) {
1534 boolean one_desc = false;
1535 if ( nhx_or_nexus ) {
1536 for( final Phylogeny phy : phys ) {
1537 if ( getOptions().isInternalNumberAreConfidenceForNhParsing() ) {
1538 PhylogenyMethods.transferInternalNodeNamesToConfidence( phy, "" );
1540 if ( PhylogenyMethods.getMinimumDescendentsPerInternalNodes( phy ) == 1 ) {
1546 if ( PREPROCESS_TREES ) {
1547 preProcessTreesUponReading( phys );
1549 AptxUtil.addPhylogeniesToTabs( phys,
1551 file.getAbsolutePath(),
1554 _mainpanel.getControlPanel().showWhole();
1555 if ( nhx_or_nexus && one_desc ) {
1556 JOptionPane.showMessageDialog( this,
1557 "One or more trees contain (a) node(s) with one descendant, "
1558 + ForesterUtil.LINE_SEPARATOR
1559 + "possibly indicating illegal parentheses within node names.",
1560 "Warning: Possible Error in New Hampshire Formatted Data",
1561 JOptionPane.WARNING_MESSAGE );
1567 activateSaveAllIfNeeded();
1571 private void readSpeciesTreeFromFile() {
1573 boolean exception = false;
1574 final File my_dir = getCurrentDir();
1575 _open_filechooser_for_species_tree.setSelectedFile( new File( "" ) );
1576 if ( my_dir != null ) {
1577 _open_filechooser_for_species_tree.setCurrentDirectory( my_dir );
1579 final int result = _open_filechooser_for_species_tree.showOpenDialog( _contentpane );
1580 final File file = _open_filechooser_for_species_tree.getSelectedFile();
1581 if ( ( file != null ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
1582 if ( _open_filechooser_for_species_tree.getFileFilter() == MainFrame.xmlfilter ) {
1584 final Phylogeny[] trees = PhylogenyMethods
1585 .readPhylogenies( PhyloXmlParser.createPhyloXmlParserXsdValidating(), file );
1588 catch ( final Exception e ) {
1590 exceptionOccuredDuringOpenFile( e );
1593 else if ( _open_filechooser_for_species_tree.getFileFilter() == MainFrame.tolfilter ) {
1595 final Phylogeny[] trees = PhylogenyMethods.readPhylogenies( new TolParser(), file );
1598 catch ( final Exception e ) {
1600 exceptionOccuredDuringOpenFile( e );
1606 final Phylogeny[] trees = PhylogenyMethods
1607 .readPhylogenies( PhyloXmlParser.createPhyloXmlParserXsdValidating(), file );
1610 catch ( final Exception e ) {
1612 exceptionOccuredDuringOpenFile( e );
1615 if ( !exception && ( t != null ) && !t.isRooted() ) {
1618 JOptionPane.showMessageDialog( this,
1619 "Species tree is not rooted",
1620 "Species tree not loaded",
1621 JOptionPane.ERROR_MESSAGE );
1623 if ( !exception && ( t != null ) ) {
1624 final Set<Taxonomy> tax_set = new HashSet<Taxonomy>();
1625 for( final PhylogenyNodeIterator it = t.iteratorExternalForward(); it.hasNext(); ) {
1626 final PhylogenyNode node = it.next();
1627 if ( !node.getNodeData().isHasTaxonomy() ) {
1630 JOptionPane.showMessageDialog( this,
1631 "Species tree contains external node(s) without taxonomy information",
1632 "Species tree not loaded",
1633 JOptionPane.ERROR_MESSAGE );
1637 if ( tax_set.contains( node.getNodeData().getTaxonomy() ) ) {
1641 .showMessageDialog( this,
1642 "Taxonomy [" + node.getNodeData().getTaxonomy().asSimpleText()
1643 + "] is not unique in species tree",
1644 "Species tree not loaded",
1645 JOptionPane.ERROR_MESSAGE );
1649 tax_set.add( node.getNodeData().getTaxonomy() );
1654 if ( !exception && ( t != null ) ) {
1655 setSpeciesTree( t );
1656 JOptionPane.showMessageDialog( this,
1657 "Species tree successfully loaded",
1658 "Species tree loaded",
1659 JOptionPane.INFORMATION_MESSAGE );
1661 _contentpane.repaint();
1666 private void setArrowCursor() {
1668 _mainpanel.getCurrentTreePanel().setArrowCursor();
1670 catch ( final Exception ex ) {
1675 private void setMinNotCollapseBlValue( final double min_not_collapse_bl ) {
1676 _min_not_collapse_bl = min_not_collapse_bl;
1679 private void setMinNotCollapseConfidenceValue( final double min_not_collapse ) {
1680 _min_not_collapse = min_not_collapse;
1683 private void setPhylogeneticInferenceOptions( final PhylogeneticInferenceOptions phylogenetic_inference_options ) {
1684 _phylogenetic_inference_options = phylogenetic_inference_options;
1687 private void setSpecialOptionsForNexParser( final NexusPhylogeniesParser nex ) {
1688 nex.setReplaceUnderscores( getOptions().isReplaceUnderscoresInNhParsing() );
1689 nex.setTaxonomyExtraction( getOptions().getTaxonomyExtraction() );
1690 nex.setParseBeastStyleExtendedTags( getOptions().isParseBeastStyleExtendedNexusTags() );
1693 private void setSpecialOptionsForNhxParser( final NHXParser nhx ) {
1694 nhx.setReplaceUnderscores( getOptions().isReplaceUnderscoresInNhParsing() );
1695 nhx.setTaxonomyExtraction( getOptions().getTaxonomyExtraction() );
1696 nhx.setAllowErrorsInDistanceToParent( getOptions().isAllowErrorsInDistanceToParent() );
1697 nhx.setParseBeastStyleExtendedTags( getOptions().isParseBeastStyleExtendedNexusTags() );
1700 void buildAnalysisMenu() {
1701 _analysis_menu = MainFrame.createMenu( "Analysis", getConfiguration() );
1702 _analysis_menu.add( _gsdi_item = new JMenuItem( "GSDI (Generalized Speciation Duplication Inference)" ) );
1703 _analysis_menu.add( _gsdir_item = new JMenuItem( "GSDIR (GSDI with re-rooting)" ) );
1704 _analysis_menu.add( _load_species_tree_item = new JMenuItem( "Load Species Tree..." ) );
1705 customizeJMenuItem( _gsdi_item );
1706 customizeJMenuItem( _gsdir_item );
1707 customizeJMenuItem( _load_species_tree_item );
1708 _analysis_menu.addSeparator();
1709 _analysis_menu.add( _lineage_inference = new JMenuItem( INFER_ANCESTOR_TAXONOMIES ) );
1710 customizeJMenuItem( _lineage_inference );
1711 _lineage_inference.setToolTipText( "Inference of ancestor taxonomies/lineages" );
1712 _jmenubar.add( _analysis_menu );
1716 void buildFileMenu() {
1717 _file_jmenu = MainFrame.createMenu( "File", getConfiguration() );
1718 _file_jmenu.add( _open_item = new JMenuItem( "Read Tree from File..." ) );
1719 _file_jmenu.addSeparator();
1720 _file_jmenu.add( _open_url_item = new JMenuItem( "Read Tree from URL/Webservice..." ) );
1721 _file_jmenu.addSeparator();
1722 final WebservicesManager webservices_manager = WebservicesManager.getInstance();
1723 _load_phylogeny_from_webservice_menu_items = new JMenuItem[ webservices_manager
1724 .getAvailablePhylogeniesWebserviceClients().size() ];
1725 for( int i = 0; i < webservices_manager.getAvailablePhylogeniesWebserviceClients().size(); ++i ) {
1726 final PhylogeniesWebserviceClient client = webservices_manager.getAvailablePhylogeniesWebserviceClient( i );
1727 _load_phylogeny_from_webservice_menu_items[ i ] = new JMenuItem( client.getMenuName() );
1728 _file_jmenu.add( _load_phylogeny_from_webservice_menu_items[ i ] );
1730 if ( getConfiguration().isEditable() ) {
1731 _file_jmenu.addSeparator();
1732 _file_jmenu.add( _new_item = new JMenuItem( "New" ) );
1733 _new_item.setToolTipText( "to create a new tree with one node, as source for manual tree construction" );
1735 _file_jmenu.addSeparator();
1736 _file_jmenu.add( _save_item = new JMenuItem( "Save Tree As..." ) );
1737 _file_jmenu.add( _save_all_item = new JMenuItem( "Save All Trees As..." ) );
1738 _save_all_item.setToolTipText( "Write all phylogenies to one file." );
1739 _save_all_item.setEnabled( false );
1740 _file_jmenu.addSeparator();
1741 _file_jmenu.add( _write_to_pdf_item = new JMenuItem( "Export to PDF file ..." ) );
1742 if ( AptxUtil.canWriteFormat( "tif" ) || AptxUtil.canWriteFormat( "tiff" )
1743 || AptxUtil.canWriteFormat( "TIF" ) ) {
1744 _file_jmenu.add( _write_to_tif_item = new JMenuItem( "Export to TIFF file..." ) );
1746 _file_jmenu.add( _write_to_png_item = new JMenuItem( "Export to PNG file..." ) );
1747 _file_jmenu.add( _write_to_jpg_item = new JMenuItem( "Export to JPG file..." ) );
1748 if ( AptxUtil.canWriteFormat( "gif" ) ) {
1749 _file_jmenu.add( _write_to_gif_item = new JMenuItem( "Export to GIF file..." ) );
1751 if ( AptxUtil.canWriteFormat( "bmp" ) ) {
1752 _file_jmenu.add( _write_to_bmp_item = new JMenuItem( "Export to BMP file..." ) );
1754 _file_jmenu.addSeparator();
1755 _file_jmenu.add( _print_item = new JMenuItem( "Print..." ) );
1756 _file_jmenu.addSeparator();
1757 _file_jmenu.add( _close_item = new JMenuItem( "Close Tab" ) );
1758 _close_item.setToolTipText( "To close the current pane." );
1759 _close_item.setEnabled( true );
1760 _file_jmenu.addSeparator();
1761 _file_jmenu.add( _exit_item = new JMenuItem( "Exit" ) );
1762 customizeJMenuItem( _open_item );
1763 _open_item.setFont( new Font( _open_item.getFont().getFontName(),
1765 _open_item.getFont().getSize() + 4 ) );
1766 customizeJMenuItem( _open_url_item );
1767 for( int i = 0; i < webservices_manager.getAvailablePhylogeniesWebserviceClients().size(); ++i ) {
1768 customizeJMenuItem( _load_phylogeny_from_webservice_menu_items[ i ] );
1770 customizeJMenuItem( _save_item );
1771 if ( getConfiguration().isEditable() ) {
1772 customizeJMenuItem( _new_item );
1774 customizeJMenuItem( _close_item );
1775 customizeJMenuItem( _save_all_item );
1776 customizeJMenuItem( _write_to_pdf_item );
1777 customizeJMenuItem( _write_to_png_item );
1778 customizeJMenuItem( _write_to_jpg_item );
1779 customizeJMenuItem( _write_to_gif_item );
1780 customizeJMenuItem( _write_to_tif_item );
1781 customizeJMenuItem( _write_to_bmp_item );
1782 customizeJMenuItem( _print_item );
1783 customizeJMenuItem( _exit_item );
1784 _jmenubar.add( _file_jmenu );
1787 void buildOptionsMenu() {
1788 _options_jmenu = MainFrame.createMenu( OPTIONS_HEADER, getConfiguration() );
1789 _options_jmenu.addChangeListener( new ChangeListener() {
1792 public void stateChanged( final ChangeEvent e ) {
1793 MainFrame.setOvPlacementColorChooseMenuItem( _overview_placment_mi, getOptions() );
1794 MainFrame.setTextColorChooseMenuItem( _switch_colors_mi, getCurrentTreePanel() );
1795 MainFrame.setTextMinSupportMenuItem( _choose_minimal_confidence_mi,
1797 getCurrentTreePanel() );
1798 MainFrame.setTextForFontChooserMenuItem( _choose_font_mi,
1799 MainFrame.createCurrentFontDesc( getMainPanel()
1800 .getTreeFontSet() ) );
1801 // MainFrame.setTextForGraphicsSizeChooserMenuItem( _print_size_mi, getOptions() );
1802 MainFrame.setTextForPdfLineWidthChooserMenuItem( _choose_pdf_width_mi, getOptions() );
1803 MainFrame.setCycleNodeFillMenuItem( _cycle_node_fill_mi, getOptions() );
1804 MainFrame.setCycleNodeShapeMenuItem( _cycle_node_shape_mi, getOptions() );
1805 MainFrame.setCycleDataReturnMenuItem( _cycle_data_return, getOptions() );
1806 MainFrame.setTextNodeSizeMenuItem( _choose_node_size_mi, getOptions() );
1808 getMainPanel().getControlPanel().setVisibilityOfDomainStrucureCB();
1809 getMainPanel().getControlPanel().setVisibilityOfX();
1811 catch ( final Exception ignore ) {
1812 // do nothing, not important.
1816 _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( DISPLAY_SUBHEADER ), getConfiguration() ) );
1818 .add( _ext_node_dependent_cladogram_rbmi = new JRadioButtonMenuItem( MainFrame.NONUNIFORM_CLADOGRAMS_LABEL ) );
1819 _options_jmenu.add( _non_lined_up_cladograms_rbmi = new JRadioButtonMenuItem( NON_LINED_UP_CLADOGRAMS_LABEL ) );
1820 _radio_group_1 = new ButtonGroup();
1821 _radio_group_1.add( _ext_node_dependent_cladogram_rbmi );
1822 _radio_group_1.add( _non_lined_up_cladograms_rbmi );
1823 _options_jmenu.add( _show_overview_cbmi = new JCheckBoxMenuItem( SHOW_OVERVIEW_LABEL ) );
1824 _options_jmenu.add( _show_scale_cbmi = new JCheckBoxMenuItem( DISPLAY_SCALE_LABEL ) );
1826 .add( _show_default_node_shapes_internal_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_INT ) );
1828 .add( _show_default_node_shapes_external_cbmi = new JCheckBoxMenuItem( DISPLAY_NODE_BOXES_LABEL_EXT ) );
1830 .add( _show_default_node_shapes_for_marked_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_NODE_BOXES_LABEL_MARKED ) );
1833 .add( _collapsed_with_average_height_cbmi = new JCheckBoxMenuItem( "Proportional Height of Collapsed Subtrees" ) );
1837 .add( _show_abbreviated_labels_for_collapsed_nodes_cbmi = new JCheckBoxMenuItem( "Add Abbreviated Labels to Collapsed Subtrees" ) );
1842 .add( _line_up_renderable_data_cbmi = new JCheckBoxMenuItem( MainFrame.LINE_UP_RENDERABLE_DATA ) );
1846 if ( getConfiguration().doDisplayOption( Configuration.show_domain_architectures ) ) {
1848 .add( _right_line_up_domains_cbmi = new JCheckBoxMenuItem( MainFrame.RIGHT_LINE_UP_DOMAINS ) );
1849 _options_jmenu.add( _show_domain_labels = new JCheckBoxMenuItem( MainFrame.SHOW_DOMAIN_LABELS_LABEL ) );
1851 _options_jmenu.add( _show_annotation_ref_source = new JCheckBoxMenuItem( SHOW_ANN_REF_SOURCE_LABEL ) );
1852 _options_jmenu.add( _show_confidence_stddev_cbmi = new JCheckBoxMenuItem( SHOW_CONF_STDDEV_LABEL ) );
1853 _options_jmenu.add( _color_by_taxonomic_group_cbmi = new JCheckBoxMenuItem( COLOR_BY_TAXONOMIC_GROUP ) );
1854 _options_jmenu.add( _color_labels_same_as_parent_branch = new JCheckBoxMenuItem( COLOR_LABELS_LABEL ) );
1855 _color_labels_same_as_parent_branch.setToolTipText( MainFrame.COLOR_LABELS_TIP );
1856 _options_jmenu.add( _abbreviate_scientific_names = new JCheckBoxMenuItem( ABBREV_SN_LABEL ) );
1857 _options_jmenu.add( _label_direction_cbmi = new JCheckBoxMenuItem( LABEL_DIRECTION_LABEL ) );
1858 _label_direction_cbmi.setToolTipText( LABEL_DIRECTION_TIP );
1859 _options_jmenu.add( _screen_antialias_cbmi = new JCheckBoxMenuItem( SCREEN_ANTIALIAS_LABEL ) );
1860 _options_jmenu.add( _background_gradient_cbmi = new JCheckBoxMenuItem( BG_GRAD_LABEL ) );
1861 _options_jmenu.add( _cycle_node_shape_mi = new JMenuItem( MainFrame.CYCLE_NODE_SHAPE_LABEL ) );
1862 _options_jmenu.add( _cycle_node_fill_mi = new JMenuItem( MainFrame.CYCLE_NODE_FILL_LABEL ) );
1863 _options_jmenu.add( _choose_node_size_mi = new JMenuItem( MainFrame.CHOOSE_NODE_SIZE_LABEL ) );
1864 _options_jmenu.add( _choose_minimal_confidence_mi = new JMenuItem( "" ) );
1865 _options_jmenu.add( _overview_placment_mi = new JMenuItem( "" ) );
1866 _options_jmenu.add( _switch_colors_mi = new JMenuItem( "" ) );
1867 _options_jmenu.add( _choose_font_mi = new JMenuItem( "" ) );
1868 _options_jmenu.addSeparator();
1869 _options_jmenu.add( _cycle_data_return = new JMenuItem( "Cycle Data Return" ) );
1870 _options_jmenu.addSeparator();
1871 _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( SEARCH_SUBHEADER ), getConfiguration() ) );
1872 _options_jmenu.add( _search_case_senstive_cbmi = new JCheckBoxMenuItem( SEARCH_CASE_SENSITIVE_LABEL ) );
1873 _options_jmenu.add( _search_whole_words_only_cbmi = new JCheckBoxMenuItem( SEARCH_TERMS_ONLY_LABEL ) );
1874 _options_jmenu.add( _search_with_regex_cbmi = new JCheckBoxMenuItem( MainFrame.SEARCH_REGEX_LABEL ) );
1875 _search_with_regex_cbmi.setToolTipText( MainFrame.SEARCH_WITH_REGEX_TIP );
1876 _options_jmenu.add( _inverse_search_result_cbmi = new JCheckBoxMenuItem( INVERSE_SEARCH_RESULT_LABEL ) );
1878 .add( _color_all_found_nodes_when_coloring_subtree_cbmi = new JCheckBoxMenuItem( "Colorize All Found Nodes When Colorizing Subtree(s)" ) );
1879 _options_jmenu.addSeparator();
1881 .add( customizeMenuItemAsLabel( new JMenuItem( "Graphics Export & Printing:" ), getConfiguration() ) );
1882 _options_jmenu.add( _antialias_print_cbmi = new JCheckBoxMenuItem( "Antialias" ) );
1883 _options_jmenu.add( _print_black_and_white_cbmi = new JCheckBoxMenuItem( "Export in Black and White" ) );
1885 .add( _graphics_export_visible_only_cbmi = new JCheckBoxMenuItem( "Limit to Visible ('Screenshot') for PNG, JPG, and GIF export" ) );
1886 _options_jmenu.add( _choose_pdf_width_mi = new JMenuItem( "" ) );
1887 _options_jmenu.addSeparator();
1888 _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Newick/NHX/Nexus Read:" ), getConfiguration() ) );
1890 .add( _internal_number_are_confidence_for_nh_parsing_cbmi = new JCheckBoxMenuItem( "Internal Node Names are Confidence Values" ) );
1891 _options_jmenu.add( _replace_underscores_cbmi = new JCheckBoxMenuItem( "Replace Underscores with Spaces" ) );
1893 .add( _parse_beast_style_extended_nexus_tags_cbmi = new JCheckBoxMenuItem( "Parse BEAST-style extended Newick/Nexus tags" ) );
1894 _parse_beast_style_extended_nexus_tags_cbmi
1895 .setToolTipText( "to parse elements in the form of \"[&!color=#800080]\" in Newick/Nexus formatted trees" );
1897 .add( _allow_errors_in_distance_to_parent_cbmi = new JCheckBoxMenuItem( "Ignore Distance Values Format Errors" ) );
1898 _options_jmenu.add( _extract_taxonomy_no_rbmi = new JRadioButtonMenuItem( "No Taxonomy Extraction" ) );
1900 .add( _extract_taxonomy_pfam_strict_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style Node Names" ) );
1902 .add( _extract_taxonomy_pfam_relaxed_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids from Pfam-style like Node Names" ) );
1904 .add( _extract_taxonomy_agressive_rbmi = new JRadioButtonMenuItem( "Extract Taxonomy Codes/Ids/Scientific Names from Node Names" ) );
1905 _extract_taxonomy_pfam_strict_rbmi
1906 .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"BCL2_MOUSE/123-304\" or \"BCL2_10090/123-304\"" );
1907 _extract_taxonomy_pfam_relaxed_rbmi
1908 .setToolTipText( "To extract taxonomy codes/ids from node names in the form of e.g. \"bax_MOUSE\" or \"bax_10090\"" );
1909 _extract_taxonomy_agressive_rbmi
1910 .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\"" );
1911 _radio_group_2 = new ButtonGroup();
1912 _radio_group_2.add( _extract_taxonomy_no_rbmi );
1913 _radio_group_2.add( _extract_taxonomy_pfam_strict_rbmi );
1914 _radio_group_2.add( _extract_taxonomy_pfam_relaxed_rbmi );
1915 _radio_group_2.add( _extract_taxonomy_agressive_rbmi );
1916 _options_jmenu.add( customizeMenuItemAsLabel( new JMenuItem( "Newick/Nexus Save:" ), getConfiguration() ) );
1918 .add( _use_brackets_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_BRACKETS_FOR_CONF_IN_NH_LABEL ) );
1919 _use_brackets_for_conf_in_nh_export_cbmi
1920 .setToolTipText( "e.g. \"0.1[90]\" for a branch with support 90 and a length of 0.1" );
1922 .add( _use_internal_names_for_conf_in_nh_export_cbmi = new JCheckBoxMenuItem( USE_INTERNAL_NAMES_FOR_CONF_IN_NH_LABEL ) );
1923 customizeJMenuItem( _choose_font_mi );
1924 customizeJMenuItem( _choose_minimal_confidence_mi );
1925 customizeJMenuItem( _switch_colors_mi );
1926 customizeJMenuItem( _choose_pdf_width_mi );
1927 customizeJMenuItem( _overview_placment_mi );
1928 customizeCheckBoxMenuItem( _show_default_node_shapes_external_cbmi,
1929 getOptions().isShowDefaultNodeShapesExternal() );
1930 customizeCheckBoxMenuItem( _show_default_node_shapes_internal_cbmi,
1931 getOptions().isShowDefaultNodeShapesInternal() );
1932 customizeCheckBoxMenuItem( _show_default_node_shapes_for_marked_cbmi,
1933 getOptions().isShowDefaultNodeShapesForMarkedNodes() );
1934 customizeJMenuItem( _cycle_node_shape_mi );
1935 customizeJMenuItem( _cycle_node_fill_mi );
1936 customizeJMenuItem( _choose_node_size_mi );
1937 customizeJMenuItem( _cycle_data_return );
1938 customizeCheckBoxMenuItem( _color_labels_same_as_parent_branch,
1939 getOptions().isColorLabelsSameAsParentBranch() );
1940 customizeCheckBoxMenuItem( _color_by_taxonomic_group_cbmi, getOptions().isColorByTaxonomicGroup() );
1941 customizeCheckBoxMenuItem( _screen_antialias_cbmi, getOptions().isAntialiasScreen() );
1942 customizeCheckBoxMenuItem( _background_gradient_cbmi, getOptions().isBackgroundColorGradient() );
1943 customizeCheckBoxMenuItem( _show_domain_labels, getOptions().isShowDomainLabels() );
1944 customizeCheckBoxMenuItem( _show_annotation_ref_source, getOptions().isShowAnnotationRefSource() );
1945 customizeCheckBoxMenuItem( _abbreviate_scientific_names, getOptions().isAbbreviateScientificTaxonNames() );
1946 customizeCheckBoxMenuItem( _search_case_senstive_cbmi, getOptions().isSearchCaseSensitive() );
1947 customizeCheckBoxMenuItem( _show_scale_cbmi, getOptions().isShowScale() );
1948 customizeCheckBoxMenuItem( _collapsed_with_average_height_cbmi, getOptions().isCollapsedWithAverageHeigh() );
1949 customizeCheckBoxMenuItem( _show_abbreviated_labels_for_collapsed_nodes_cbmi, getOptions().isShowAbbreviatedLabelsForCollapsedNodes() );
1951 customizeRadioButtonMenuItem( _non_lined_up_cladograms_rbmi,
1952 getOptions().getCladogramType() == CLADOGRAM_TYPE.NON_LINED_UP );
1953 customizeRadioButtonMenuItem( _ext_node_dependent_cladogram_rbmi,
1954 getOptions().getCladogramType() == CLADOGRAM_TYPE.LINED_UP );
1955 customizeCheckBoxMenuItem( _show_overview_cbmi, getOptions().isShowOverview() );
1956 customizeCheckBoxMenuItem( _label_direction_cbmi,
1957 getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL );
1958 customizeCheckBoxMenuItem( _antialias_print_cbmi, getOptions().isAntialiasPrint() );
1959 customizeCheckBoxMenuItem( _print_black_and_white_cbmi, getOptions().isPrintBlackAndWhite() );
1960 customizeCheckBoxMenuItem( _internal_number_are_confidence_for_nh_parsing_cbmi,
1961 getOptions().isInternalNumberAreConfidenceForNhParsing() );
1962 customizeRadioButtonMenuItem( _extract_taxonomy_no_rbmi,
1963 getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.NO );
1964 customizeRadioButtonMenuItem( _extract_taxonomy_pfam_strict_rbmi,
1965 getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT );
1966 customizeRadioButtonMenuItem( _extract_taxonomy_pfam_relaxed_rbmi,
1967 getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.PFAM_STYLE_RELAXED );
1968 customizeRadioButtonMenuItem( _extract_taxonomy_agressive_rbmi,
1969 getOptions().getTaxonomyExtraction() == TAXONOMY_EXTRACTION.AGGRESSIVE );
1970 customizeCheckBoxMenuItem( _replace_underscores_cbmi, getOptions().isReplaceUnderscoresInNhParsing() );
1971 customizeCheckBoxMenuItem( _allow_errors_in_distance_to_parent_cbmi,
1972 getOptions().isReplaceUnderscoresInNhParsing() );
1973 customizeCheckBoxMenuItem( _search_with_regex_cbmi, getOptions().isSearchWithRegex() );
1974 customizeCheckBoxMenuItem( _search_whole_words_only_cbmi, getOptions().isMatchWholeTermsOnly() );
1975 customizeCheckBoxMenuItem( _inverse_search_result_cbmi, getOptions().isInverseSearchResult() );
1976 customizeCheckBoxMenuItem( _color_all_found_nodes_when_coloring_subtree_cbmi,
1977 getOptions().isColorAllFoundNodesWhenColoringSubtree() );
1978 customizeCheckBoxMenuItem( _parse_beast_style_extended_nexus_tags_cbmi,
1979 getOptions().isParseBeastStyleExtendedNexusTags() );
1980 customizeCheckBoxMenuItem( _graphics_export_visible_only_cbmi, getOptions().isGraphicsExportVisibleOnly() );
1981 customizeCheckBoxMenuItem( _show_confidence_stddev_cbmi, getOptions().isShowConfidenceStddev() );
1982 customizeCheckBoxMenuItem( _use_brackets_for_conf_in_nh_export_cbmi,
1984 .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.IN_SQUARE_BRACKETS );
1985 customizeCheckBoxMenuItem( _use_internal_names_for_conf_in_nh_export_cbmi,
1987 .getNhConversionSupportValueStyle() == NH_CONVERSION_SUPPORT_VALUE_STYLE.AS_INTERNAL_NODE_NAMES );
1988 customizeCheckBoxMenuItem( _line_up_renderable_data_cbmi, getOptions().isLineUpRendarableNodeData() );
1989 customizeCheckBoxMenuItem( _right_line_up_domains_cbmi, getOptions().isRightLineUpDomains() );
1990 _jmenubar.add( _options_jmenu );
1993 void buildPhylogeneticInferenceMenu() {
1994 final InferenceManager im = getInferenceManager();
1995 _inference_menu = MainFrame.createMenu( "Inference", getConfiguration() );
1996 _inference_menu.add( _inference_from_msa_item = new JMenuItem( "From Multiple Sequence Alignment..." ) );
1997 customizeJMenuItem( _inference_from_msa_item );
1998 _inference_from_msa_item.setToolTipText( "Basic phylogenetic inference from MSA" );
1999 if ( im.canDoMsa() ) {
2000 _inference_menu.add( _inference_from_seqs_item = new JMenuItem( "From Unaligned Sequences..." ) );
2001 customizeJMenuItem( _inference_from_seqs_item );
2002 _inference_from_seqs_item
2003 .setToolTipText( "Basic phylogenetic inference including multiple sequence alignment" );
2007 .add( _inference_from_seqs_item = new JMenuItem( "From Unaligned Sequences (no program found)" ) );
2008 customizeJMenuItem( _inference_from_seqs_item );
2009 _inference_from_seqs_item.setEnabled( false );
2011 _jmenubar.add( _inference_menu );
2014 void buildToolsMenu() {
2015 _tools_menu = createMenu( "Tools", getConfiguration() );
2016 _tools_menu.add( _confcolor_item = new JMenuItem( "Colorize Branches Depending on Confidence" ) );
2017 customizeJMenuItem( _confcolor_item );
2018 _tools_menu.add( _color_rank_jmi = new JMenuItem( "Colorize Subtrees via Taxonomic Rank" ) );
2019 customizeJMenuItem( _color_rank_jmi );
2020 _color_rank_jmi.setToolTipText( "for example, at \"Class\" level, colorize mammal specific subtree red" );
2021 _tools_menu.add( _taxcolor_item = new JMenuItem( "Taxonomy Colorize Branches" ) );
2022 customizeJMenuItem( _taxcolor_item );
2023 _tools_menu.addSeparator();
2024 _tools_menu.add( _remove_visual_styles_item = new JMenuItem( "Delete All Visual Styles From Nodes" ) );
2025 _remove_visual_styles_item
2026 .setToolTipText( "To remove all node visual styles (fonts, colors) from the current phylogeny" );
2027 customizeJMenuItem( _remove_visual_styles_item );
2028 _tools_menu.add( _remove_branch_color_item = new JMenuItem( "Delete All Colors From Branches" ) );
2029 _remove_branch_color_item.setToolTipText( "To remove all branch color values from the current phylogeny" );
2030 customizeJMenuItem( _remove_branch_color_item );
2031 _tools_menu.addSeparator();
2032 _tools_menu.add( _annotate_item = new JMenuItem( "Annotate Sequences of Selected Nodes" ) );
2033 customizeJMenuItem( _annotate_item );
2034 _tools_menu.addSeparator();
2035 _tools_menu.add( _midpoint_root_item = new JMenuItem( "Midpoint-Root" ) );
2036 customizeJMenuItem( _midpoint_root_item );
2037 _tools_menu.addSeparator();
2038 _tools_menu.add( _delete_selected_nodes_item = new JMenuItem( "Delete Selected Nodes" ) );
2039 _delete_selected_nodes_item.setToolTipText( "To delete all selected external nodes" );
2040 customizeJMenuItem( _delete_selected_nodes_item );
2041 _tools_menu.add( _delete_not_selected_nodes_item = new JMenuItem( "Retain Selected Nodes" ) );
2042 _delete_not_selected_nodes_item.setToolTipText( "To delete all not selected external nodes" );
2043 customizeJMenuItem( _delete_not_selected_nodes_item );
2044 _tools_menu.addSeparator();
2045 _tools_menu.add( _collapse_species_specific_subtrees = new JMenuItem( "Collapse Single Taxonomy-Subtrees" ) );
2046 customizeJMenuItem( _collapse_species_specific_subtrees );
2047 _collapse_species_specific_subtrees.setToolTipText( "To (reversibly) collapse subtrees associated with only one taxonomy (such as species specific subtrees)" );
2049 .add( _collapse_below_threshold = new JMenuItem( "Collapse Branches with Confidence Below Threshold into Multifurcations" ) );
2050 customizeJMenuItem( _collapse_below_threshold );
2051 _collapse_below_threshold
2052 .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)" );
2055 .add( _collapse_below_branch_length = new JMenuItem( "Collapse Branches with Branch Lengths Below Threshold into Multifurcations" ) );
2056 customizeJMenuItem( _collapse_below_branch_length );
2057 _collapse_below_branch_length
2058 .setToolTipText( "To (permanently) collapse branches with branches with branch lengths below a threshold into multifurcations" );
2060 _tools_menu.addSeparator();
2062 .add( _extract_tax_code_from_node_names_jmi = new JMenuItem( "Extract Taxonomic Data from Node Names" ) );
2063 customizeJMenuItem( _extract_tax_code_from_node_names_jmi );
2064 _extract_tax_code_from_node_names_jmi
2065 .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'" );
2067 .add( _move_node_names_to_tax_sn_jmi = new JMenuItem( "Transfer Node Names to Taxonomic Scientific Names" ) );
2068 customizeJMenuItem( _move_node_names_to_tax_sn_jmi );
2069 _move_node_names_to_tax_sn_jmi.setToolTipText( "To interpret node names as taxonomic scientific names" );
2070 _tools_menu.add( _move_node_names_to_seq_names_jmi = new JMenuItem( "Transfer Node Names to Sequence Names" ) );
2071 customizeJMenuItem( _move_node_names_to_seq_names_jmi );
2072 _move_node_names_to_seq_names_jmi.setToolTipText( "To interpret node names as sequence (protein, gene) names" );
2073 _tools_menu.addSeparator();
2074 _tools_menu.add( _obtain_seq_information_jmi = new JMenuItem( "Obtain Sequence Information" ) );
2075 customizeJMenuItem( _obtain_seq_information_jmi );
2076 _obtain_seq_information_jmi.setToolTipText( "To add additional sequence information" );
2078 .add( _obtain_detailed_taxonomic_information_jmi = new JMenuItem( OBTAIN_DETAILED_TAXONOMIC_INFORMATION ) );
2079 customizeJMenuItem( _obtain_detailed_taxonomic_information_jmi );
2080 _obtain_detailed_taxonomic_information_jmi
2081 .setToolTipText( "To add additional taxonomic information (from UniProt Taxonomy)" );
2083 .add( _obtain_detailed_taxonomic_information_deleting_jmi = new JMenuItem( "Obtain Detailed Taxonomic Information (deletes nodes!)" ) );
2084 customizeJMenuItem( _obtain_detailed_taxonomic_information_deleting_jmi );
2085 _obtain_detailed_taxonomic_information_deleting_jmi
2086 .setToolTipText( "To add additional taxonomic information, deletes nodes for which taxonomy cannot found (from UniProt Taxonomy)" );
2087 _tools_menu.addSeparator();
2088 _tools_menu.add( _read_values_jmi = new JMenuItem( "Attach Vector/Expression Values" ) );
2089 customizeJMenuItem( _read_values_jmi );
2090 _read_values_jmi.setToolTipText( "To attach vector (e.g. gene expression) values to tree nodes (beta)" );
2091 _jmenubar.add( _tools_menu );
2092 _tools_menu.add( _read_seqs_jmi = new JMenuItem( "Attach Molecular Sequences" ) );
2093 customizeJMenuItem( _read_seqs_jmi );
2095 .setToolTipText( "To attach molecular sequences to tree nodes (from Fasta-formatted file) (beta)" );
2096 _jmenubar.add( _tools_menu );
2101 if ( isUnsavedDataPresent() ) {
2102 final int r = JOptionPane.showConfirmDialog( this,
2103 "Exit despite potentially unsaved changes?",
2105 JOptionPane.YES_NO_OPTION );
2106 if ( r != JOptionPane.YES_OPTION ) {
2114 removeAllTextFrames();
2115 _mainpanel.terminate();
2116 _contentpane.removeAll();
2117 setVisible( false );
2119 // System.exit( 0 ); //TODO reconfirm that this is OK, then remove.
2122 void readPhylogeniesFromURL() {
2124 Phylogeny[] phys = null;
2125 final String message = "Please enter a complete URL, for example \"http://purl.org/phylo/treebase/phylows/study/TB2:S15480?format=nexus\"";
2126 final String url_string = JOptionPane
2127 .showInputDialog( this,
2129 "Use URL/webservice to obtain a phylogeny",
2130 JOptionPane.QUESTION_MESSAGE );
2131 boolean nhx_or_nexus = false;
2132 if ( ( url_string != null ) && ( url_string.length() > 0 ) ) {
2134 url = new URL( url_string );
2135 PhylogenyParser parser = null;
2136 if ( url.getHost().toLowerCase().indexOf( "tolweb" ) >= 0 ) {
2137 parser = new TolParser();
2140 parser = ParserUtils
2141 .createParserDependingOnUrlContents( url,
2142 getConfiguration().isValidatePhyloXmlAgainstSchema() );
2144 if ( parser instanceof NexusPhylogeniesParser ) {
2145 nhx_or_nexus = true;
2147 else if ( parser instanceof NHXParser ) {
2148 nhx_or_nexus = true;
2150 if ( _mainpanel.getCurrentTreePanel() != null ) {
2151 _mainpanel.getCurrentTreePanel().setWaitCursor();
2154 _mainpanel.setWaitCursor();
2156 final PhylogenyFactory factory = ParserBasedPhylogenyFactory.getInstance();
2157 phys = factory.create( url.openStream(), parser );
2159 catch ( final MalformedURLException e ) {
2160 JOptionPane.showMessageDialog( this,
2161 "Malformed URL: " + url + "\n" + e.getLocalizedMessage(),
2163 JOptionPane.ERROR_MESSAGE );
2165 catch ( final IOException e ) {
2166 JOptionPane.showMessageDialog( this,
2167 "Could not read from " + url + "\n"
2168 + ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ),
2169 "Failed to read URL",
2170 JOptionPane.ERROR_MESSAGE );
2172 catch ( final Exception e ) {
2173 JOptionPane.showMessageDialog( this,
2174 ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ),
2175 "Unexpected Exception",
2176 JOptionPane.ERROR_MESSAGE );
2179 if ( _mainpanel.getCurrentTreePanel() != null ) {
2180 _mainpanel.getCurrentTreePanel().setArrowCursor();
2183 _mainpanel.setArrowCursor();
2186 if ( ( phys != null ) && ( phys.length > 0 ) ) {
2187 if ( nhx_or_nexus && getOptions().isInternalNumberAreConfidenceForNhParsing() ) {
2188 for( final Phylogeny phy : phys ) {
2189 PhylogenyMethods.transferInternalNodeNamesToConfidence( phy, "" );
2192 AptxUtil.addPhylogeniesToTabs( phys,
2193 new File( url.getFile() ).getName(),
2194 new File( url.getFile() ).toString(),
2197 _mainpanel.getControlPanel().showWhole();
2200 activateSaveAllIfNeeded();
2204 void setMsa( final Msa msa ) {
2208 void setMsaFile( final File msa_file ) {
2209 _msa_file = msa_file;
2212 void setSeqs( final List<MolecularSequence> seqs ) {
2216 void setSeqsFile( final File seqs_file ) {
2217 _seqs_file = seqs_file;
2220 public static MainFrameApplication createInstance( final Phylogeny[] phys, final Configuration config ) {
2221 return new MainFrameApplication( phys, config );
2224 public static MainFrame createInstance( final Phylogeny[] phys,
2225 final Configuration config,
2227 final File current_dir ) {
2228 return new MainFrameApplication( phys, config, title, current_dir );
2231 static MainFrame createInstance( final Phylogeny[] phys, final Configuration config, final String title ) {
2232 return new MainFrameApplication( phys, config, title );
2235 static MainFrame createInstance( final Phylogeny[] phys, final String config_file_name, final String title ) {
2236 return new MainFrameApplication( phys, config_file_name, title );
2239 static void warnIfNotPhyloXmlValidation( final Configuration c ) {
2240 if ( !c.isValidatePhyloXmlAgainstSchema() ) {
2241 JOptionPane.showMessageDialog( null,
2242 ForesterUtil.wordWrap(
2243 "phyloXML XSD-based validation is turned off [enable with line 'validate_against_phyloxml_xsd_schem: true' in configuration file]",
2246 JOptionPane.WARNING_MESSAGE );
2249 } // MainFrameApplication.