+ private void collapseBelowThreshold() {
+ if ( getCurrentTreePanel() != null ) {
+ final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
+ if ( ( phy != null ) && !phy.isEmpty() ) {
+ final String s = ( String ) JOptionPane.showInputDialog( this,
+ "Please enter the minimum confidence value\n",
+ "Minimal Confidence Value",
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ null,
+ getMinNotCollapseConfidenceValue() );
+ if ( !ForesterUtil.isEmpty( s ) ) {
+ boolean success = true;
+ double m = 0.0;
+ final String m_str = s.trim();
+ if ( !ForesterUtil.isEmpty( m_str ) ) {
+ try {
+ m = Double.parseDouble( m_str );
+ }
+ catch ( final Exception ex ) {
+ success = false;
+ }
+ }
+ else {
+ success = false;
+ }
+ if ( success && ( m >= 0.0 ) ) {
+ setMinNotCollapseConfidenceValue( m );
+ collapseBelowThreshold( phy );
+ }
+ }
+ }
+ }
+ }
+
+ private void collapseBl( final Phylogeny phy ) {
+ final PhylogenyNodeIterator it = phy.iteratorPostorder();
+ final List<PhylogenyNode> to_be_removed = new ArrayList<PhylogenyNode>();
+ double min_bl = Double.MAX_VALUE;
+ boolean bl_present = false;
+ while ( it.hasNext() ) {
+ final PhylogenyNode n = it.next();
+ if ( !n.isExternal() && !n.isRoot() ) {
+ final double bl = n.getDistanceToParent();
+ if ( bl != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) {
+ bl_present = true;
+ if ( bl < getMinNotCollapseBlValue() ) {
+ to_be_removed.add( n );
+ }
+ if ( bl < min_bl ) {
+ min_bl = bl;
+ }
+ }
+ }
+ }
+ if ( bl_present ) {
+ for( final PhylogenyNode node : to_be_removed ) {
+ PhylogenyMethods.removeNode( node, phy );
+ }
+ if ( to_be_removed.size() > 0 ) {
+ phy.externalNodesHaveChanged();
+ phy.clearHashIdToNodeMap();
+ phy.recalculateNumberOfExternalDescendants( true );
+ getCurrentTreePanel().resetNodeIdToDistToLeafMap();
+ getCurrentTreePanel().updateSetOfCollapsedExternalNodes();
+ getCurrentTreePanel().calculateLongestExtNodeInfo();
+ getCurrentTreePanel().setNodeInPreorderToNull();
+ getCurrentTreePanel().recalculateMaxDistanceToRoot();
+ getCurrentTreePanel().resetPreferredSize();
+ getCurrentTreePanel().setEdited( true );
+ getCurrentTreePanel().repaint();
+ repaint();
+ }
+ if ( to_be_removed.size() > 0 ) {
+ JOptionPane.showMessageDialog( this,
+ "Collapsed " + to_be_removed.size()
+ + " branches with\nbranch length values below "
+ + getMinNotCollapseBlValue(),
+ "Collapsed " + to_be_removed.size() + " branches",
+ JOptionPane.INFORMATION_MESSAGE );
+ }
+ else {
+ JOptionPane.showMessageDialog( this,
+ "No branch collapsed,\nminimum branch length is " + min_bl,
+ "No branch collapsed",
+ JOptionPane.INFORMATION_MESSAGE );
+ }
+ }
+ else {
+ JOptionPane.showMessageDialog( this,
+ "No branch collapsed because no branch length values present",
+ "No branch length values present",
+ JOptionPane.INFORMATION_MESSAGE );
+ }
+ }
+
+ private PhyloXmlParser createPhyloXmlParser() {
+ PhyloXmlParser xml_parser = null;
+ if ( getConfiguration().isValidatePhyloXmlAgainstSchema() ) {
+ try {
+ xml_parser = PhyloXmlParser.createPhyloXmlParserXsdValidating();
+ }
+ catch ( final Exception e ) {
+ JOptionPane.showMessageDialog( this,
+ e.getLocalizedMessage(),
+ "failed to create validating XML parser",
+ JOptionPane.WARNING_MESSAGE );
+ }
+ }
+ if ( xml_parser == null ) {
+ xml_parser = PhyloXmlParser.createPhyloXmlParser();
+ }
+ return xml_parser;
+ }
+
+ private void executePhyleneticInference( final boolean from_unaligned_seqs ) {
+ final PhyloInferenceDialog dialog = new PhyloInferenceDialog( this,
+ getPhylogeneticInferenceOptions(),
+ from_unaligned_seqs );
+ dialog.activate();
+ if ( dialog.getValue() == JOptionPane.OK_OPTION ) {
+ if ( !from_unaligned_seqs ) {
+ if ( getMsa() != null ) {
+ final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getMsa(),
+ getPhylogeneticInferenceOptions()
+ .copy(),
+ this );
+ new Thread( inferrer ).start();
+ }
+ else {
+ JOptionPane.showMessageDialog( this,
+ "No multiple sequence alignment selected",
+ "Phylogenetic Inference Not Launched",
+ JOptionPane.WARNING_MESSAGE );
+ }
+ }
+ else {
+ if ( getSeqs() != null ) {
+ final PhylogeneticInferrer inferrer = new PhylogeneticInferrer( getSeqs(),
+ getPhylogeneticInferenceOptions()
+ .copy(),
+ this );
+ new Thread( inferrer ).start();
+ }
+ else {
+ JOptionPane.showMessageDialog( this,
+ "No input sequences selected",
+ "Phylogenetic Inference Not Launched",
+ JOptionPane.WARNING_MESSAGE );
+ }
+ }
+ }
+ }
+
+ private void extractTaxDataFromNodeNames() throws PhyloXmlDataFormatException {
+ final StringBuilder sb = new StringBuilder();
+ final StringBuilder sb_failed = new StringBuilder();
+ int counter = 0;
+ int counter_failed = 0;
+ if ( getCurrentTreePanel() != null ) {
+ final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
+ if ( ( phy != null ) && !phy.isEmpty() ) {
+ final PhylogenyNodeIterator it = phy.iteratorExternalForward();
+ while ( it.hasNext() ) {
+ final PhylogenyNode n = it.next();
+ final String name = n.getName().trim();
+ if ( !ForesterUtil.isEmpty( name ) ) {
+ final String nt = ParserUtils.extractTaxonomyDataFromNodeName( n,
+ TAXONOMY_EXTRACTION.AGGRESSIVE );
+ if ( !ForesterUtil.isEmpty( nt ) ) {
+ if ( counter < 15 ) {
+ sb.append( name + ": " + nt + "\n" );
+ }
+ else if ( counter == 15 ) {
+ sb.append( "...\n" );
+ }
+ counter++;
+ }
+ else {
+ if ( counter_failed < 15 ) {
+ sb_failed.append( name + "\n" );
+ }
+ else if ( counter_failed == 15 ) {
+ sb_failed.append( "...\n" );
+ }
+ counter_failed++;
+ }
+ }
+ }
+ if ( counter > 0 ) {
+ String failed = "";
+ String all = "all ";
+ if ( counter_failed > 0 ) {
+ all = "";
+ failed = "\nCould not extract taxonomic data for " + counter_failed + " named external nodes:\n"
+ + sb_failed;
+ }
+ JOptionPane.showMessageDialog( this,
+ "Extracted taxonomic data from " + all + counter
+ + " named external nodes:\n" + sb.toString() + failed,
+ "Taxonomic Data Extraction Completed",
+ counter_failed > 0 ? JOptionPane.WARNING_MESSAGE
+ : JOptionPane.INFORMATION_MESSAGE );
+ }
+ else {
+ JOptionPane.showMessageDialog( this,
+ "Could not extract any taxonomic data.\nMaybe node names are empty\n"
+ + "or not in the forms \"XYZ_CAEEL\", \"XYZ_6239\", or \"XYZ_Caenorhabditis_elegans\"\n"
+ + "or nodes already have taxonomic data?\n",
+ "No Taxonomic Data Extracted",
+ JOptionPane.ERROR_MESSAGE );
+ }
+ }
+ }
+ }
+
+ private double getMinNotCollapseBlValue() {
+ return _min_not_collapse_bl;
+ }
+
+ private double getMinNotCollapseConfidenceValue() {
+ return _min_not_collapse;
+ }
+
+ private PhylogeneticInferenceOptions getPhylogeneticInferenceOptions() {
+ if ( _phylogenetic_inference_options == null ) {
+ _phylogenetic_inference_options = new PhylogeneticInferenceOptions();
+ }
+ return _phylogenetic_inference_options;
+ }
+
+ private boolean isUnsavedDataPresent() {
+ final List<TreePanel> tps = getMainPanel().getTreePanels();
+ for( final TreePanel tp : tps ) {
+ if ( tp.isEdited() ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void moveNodeNamesToSeqNames() throws PhyloXmlDataFormatException {
+ if ( getCurrentTreePanel() != null ) {
+ final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
+ if ( ( phy != null ) && !phy.isEmpty() ) {
+ PhylogenyMethods.transferNodeNameToField( phy,
+ PhylogenyMethods.PhylogenyNodeField.SEQUENCE_NAME,
+ false );
+ }
+ }
+ }
+
+ private void moveNodeNamesToTaxSn() throws PhyloXmlDataFormatException {
+ if ( getCurrentTreePanel() != null ) {
+ final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
+ if ( ( phy != null ) && !phy.isEmpty() ) {
+ PhylogenyMethods.transferNodeNameToField( phy,
+ PhylogenyMethods.PhylogenyNodeField.TAXONOMY_SCIENTIFIC_NAME,
+ false );
+ }
+ }
+ }
+
+ private void newTree() {
+ final Phylogeny[] phys = new Phylogeny[ 1 ];
+ final Phylogeny phy = new Phylogeny();
+ final PhylogenyNode node = new PhylogenyNode();
+ phy.setRoot( node );
+ phy.setRooted( true );
+ phys[ 0 ] = phy;
+ AptxUtil.addPhylogeniesToTabs( phys, "", "", getConfiguration(), getMainPanel() );
+ _mainpanel.getControlPanel().showWhole();
+ _mainpanel.getCurrentTreePanel().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
+ _mainpanel.getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
+
+ getMainPanel().getMainFrame().setSelectedTypeInTypeMenu( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
+
+ activateSaveAllIfNeeded();
+ System.gc();
+ }
+
+ private void obtainDetailedTaxonomicInformation() {
+ if ( getCurrentTreePanel() != null ) {
+ final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
+ if ( ( phy != null ) && !phy.isEmpty() ) {
+ final TaxonomyDataManager t = new TaxonomyDataManager( this,
+ _mainpanel.getCurrentTreePanel(),
+ phy.copy(),
+ false,
+ true );
+ new Thread( t ).start();
+ }
+ }
+ }
+
+ private void obtainDetailedTaxonomicInformationDelete() {
+ if ( getCurrentTreePanel() != null ) {
+ final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
+ if ( ( phy != null ) && !phy.isEmpty() ) {
+ final TaxonomyDataManager t = new TaxonomyDataManager( this,
+ _mainpanel.getCurrentTreePanel(),
+ phy.copy(),
+ true,
+ true );
+ new Thread( t ).start();
+ }
+ }
+ }
+
+ private void obtainSequenceInformation() {
+ if ( getCurrentTreePanel() != null ) {
+ final Phylogeny phy = getCurrentTreePanel().getPhylogeny();
+ if ( ( phy != null ) && !phy.isEmpty() ) {
+ final SequenceDataRetriver u = new SequenceDataRetriver( this,
+ _mainpanel.getCurrentTreePanel(),
+ phy.copy() );
+ new Thread( u ).start();
+ }
+ }
+ }
+
+ private void preProcessTreesUponReading( final Phylogeny[] phys ) {
+ for( final Phylogeny phy : phys ) {
+ if ( ( phy != null ) && !phy.isEmpty() ) {
+ for( final PhylogenyNodeIterator it = phy.iteratorPreorder(); it.hasNext(); ) {
+ final PhylogenyNode n = it.next();
+ if ( n.isExternal() ) {
+ if ( n.getNodeData().isHasSequence() ) {
+ final Sequence s = n.getNodeData().getSequence();
+ if ( ForesterUtil.isEmpty( s.getGeneName() ) || s.getGeneName().startsWith( "LOC" ) ) {
+ if ( ( s.getAccession() != null )
+ && !ForesterUtil.isEmpty( s.getAccession().getValue() ) ) {
+ s.setGeneName( s.getAccession().getValue() );
+ }
+ else if ( !ForesterUtil.isEmpty( n.getName() ) ) {
+ s.setGeneName( n.getName() );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void readPhylogeniesFromFile() {
+ boolean exception = false;
+ Phylogeny[] phys = null;
+ // Set an initial directory if none set yet
+ final File my_dir = getCurrentDir();
+ // Open file-open dialog and set current directory
+ if ( my_dir != null ) {
+ _open_filechooser.setCurrentDirectory( my_dir );
+ }
+ final int result = _open_filechooser.showOpenDialog( _contentpane );
+ // All done: get the file
+ final File[] files = _open_filechooser.getSelectedFiles();
+ setCurrentDir( _open_filechooser.getCurrentDirectory() );
+ boolean nhx_or_nexus = false;
+ if ( ( files != null ) && ( files.length > 0 ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
+ for( final File file : files ) {
+ if ( ( file != null ) && !file.isDirectory() ) {
+ if ( _mainpanel.getCurrentTreePanel() != null ) {
+ _mainpanel.getCurrentTreePanel().setWaitCursor();
+ }
+ else {
+ _mainpanel.setWaitCursor();
+ }
+ if ( ( _open_filechooser.getFileFilter() == MainFrame.nhfilter )
+ || ( _open_filechooser.getFileFilter() == MainFrame.nhxfilter ) ) {
+ try {
+ final NHXParser nhx = new NHXParser();
+ setSpecialOptionsForNhxParser( nhx );
+ phys = PhylogenyMethods.readPhylogenies( nhx, file );
+ nhx_or_nexus = true;
+ }
+ catch ( final Exception e ) {
+ exception = true;
+ exceptionOccuredDuringOpenFile( e );
+ }
+ }
+ else if ( _open_filechooser.getFileFilter() == MainFrame.xmlfilter ) {
+ warnIfNotPhyloXmlValidation( getConfiguration() );
+ try {
+ final PhyloXmlParser xml_parser = createPhyloXmlParser();
+ phys = PhylogenyMethods.readPhylogenies( xml_parser, file );
+ }
+ catch ( final Exception e ) {
+ exception = true;
+ exceptionOccuredDuringOpenFile( e );
+ }
+ }
+ else if ( _open_filechooser.getFileFilter() == MainFrame.tolfilter ) {
+ try {
+ phys = PhylogenyMethods.readPhylogenies( new TolParser(), file );
+ }
+ catch ( final Exception e ) {
+ exception = true;
+ exceptionOccuredDuringOpenFile( e );
+ }
+ }
+ else if ( _open_filechooser.getFileFilter() == MainFrame.nexusfilter ) {
+ try {
+ final NexusPhylogeniesParser nex = new NexusPhylogeniesParser();
+ setSpecialOptionsForNexParser( nex );
+ phys = PhylogenyMethods.readPhylogenies( nex, file );
+ nhx_or_nexus = true;
+ }
+ catch ( final Exception e ) {
+ exception = true;
+ exceptionOccuredDuringOpenFile( e );
+ }
+ }
+ // "*.*":
+ else {
+ try {
+ final PhylogenyParser parser = ParserUtils
+ .createParserDependingOnFileType( file,
+ getConfiguration()
+ .isValidatePhyloXmlAgainstSchema() );
+ if ( parser instanceof NexusPhylogeniesParser ) {
+ final NexusPhylogeniesParser nex = ( NexusPhylogeniesParser ) parser;
+ setSpecialOptionsForNexParser( nex );
+ nhx_or_nexus = true;
+ }
+ else if ( parser instanceof NHXParser ) {
+ final NHXParser nhx = ( NHXParser ) parser;
+ setSpecialOptionsForNhxParser( nhx );
+ nhx_or_nexus = true;
+ }
+ else if ( parser instanceof PhyloXmlParser ) {
+ warnIfNotPhyloXmlValidation( getConfiguration() );
+ }
+ phys = PhylogenyMethods.readPhylogenies( parser, file );
+ }
+ catch ( final Exception e ) {
+ exception = true;
+ exceptionOccuredDuringOpenFile( e );
+ }
+ }
+ if ( _mainpanel.getCurrentTreePanel() != null ) {
+ _mainpanel.getCurrentTreePanel().setArrowCursor();
+ }
+ else {
+ _mainpanel.setArrowCursor();
+ }
+ if ( !exception && ( phys != null ) && ( phys.length > 0 ) ) {
+ boolean one_desc = false;
+ if ( nhx_or_nexus ) {
+ for( final Phylogeny phy : phys ) {
+ if ( getOptions().isInternalNumberAreConfidenceForNhParsing() ) {
+ PhylogenyMethods.transferInternalNodeNamesToConfidence( phy, "" );
+ }
+ if ( PhylogenyMethods.getMinimumDescendentsPerInternalNodes( phy ) == 1 ) {
+ one_desc = true;
+ break;
+ }
+ }
+ }
+ if ( PREPROCESS_TREES ) {
+ preProcessTreesUponReading( phys );
+ }
+ AptxUtil.addPhylogeniesToTabs( phys,
+ file.getName(),
+ file.getAbsolutePath(),
+ getConfiguration(),
+ getMainPanel() );
+ _mainpanel.getControlPanel().showWhole();
+ if ( nhx_or_nexus && one_desc ) {
+ JOptionPane.showMessageDialog( this,
+ "One or more trees contain (a) node(s) with one descendant, "
+ + ForesterUtil.LINE_SEPARATOR
+ + "possibly indicating illegal parentheses within node names.",
+ "Warning: Possible Error in New Hampshire Formatted Data",
+ JOptionPane.WARNING_MESSAGE );
+ }
+ }
+ }
+ }
+ }
+ activateSaveAllIfNeeded();
+ System.gc();
+ }
+
+ private void readSpeciesTreeFromFile() {
+ Phylogeny t = null;
+ boolean exception = false;
+ final File my_dir = getCurrentDir();
+ _open_filechooser_for_species_tree.setSelectedFile( new File( "" ) );
+ if ( my_dir != null ) {
+ _open_filechooser_for_species_tree.setCurrentDirectory( my_dir );
+ }
+ final int result = _open_filechooser_for_species_tree.showOpenDialog( _contentpane );
+ final File file = _open_filechooser_for_species_tree.getSelectedFile();
+ if ( ( file != null ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
+ if ( _open_filechooser_for_species_tree.getFileFilter() == MainFrame.xmlfilter ) {
+ try {
+ final Phylogeny[] trees = PhylogenyMethods
+ .readPhylogenies( PhyloXmlParser.createPhyloXmlParserXsdValidating(), file );
+ t = trees[ 0 ];
+ }
+ catch ( final Exception e ) {
+ exception = true;
+ exceptionOccuredDuringOpenFile( e );
+ }
+ }
+ else if ( _open_filechooser_for_species_tree.getFileFilter() == MainFrame.tolfilter ) {
+ try {
+ final Phylogeny[] trees = PhylogenyMethods.readPhylogenies( new TolParser(), file );
+ t = trees[ 0 ];
+ }
+ catch ( final Exception e ) {
+ exception = true;
+ exceptionOccuredDuringOpenFile( e );
+ }
+ }
+ // "*.*":
+ else {
+ try {
+ final Phylogeny[] trees = PhylogenyMethods
+ .readPhylogenies( PhyloXmlParser.createPhyloXmlParserXsdValidating(), file );
+ t = trees[ 0 ];
+ }
+ catch ( final Exception e ) {
+ exception = true;
+ exceptionOccuredDuringOpenFile( e );
+ }
+ }
+ if ( !exception && ( t != null ) && !t.isRooted() ) {
+ exception = true;
+ t = null;
+ JOptionPane.showMessageDialog( this,
+ "Species tree is not rooted",
+ "Species tree not loaded",
+ JOptionPane.ERROR_MESSAGE );
+ }
+ if ( !exception && ( t != null ) ) {
+ final Set<Taxonomy> tax_set = new HashSet<Taxonomy>();
+ for( final PhylogenyNodeIterator it = t.iteratorExternalForward(); it.hasNext(); ) {
+ final PhylogenyNode node = it.next();
+ if ( !node.getNodeData().isHasTaxonomy() ) {
+ exception = true;
+ t = null;
+ JOptionPane.showMessageDialog( this,
+ "Species tree contains external node(s) without taxonomy information",
+ "Species tree not loaded",
+ JOptionPane.ERROR_MESSAGE );
+ break;
+ }
+ else {
+ if ( tax_set.contains( node.getNodeData().getTaxonomy() ) ) {
+ exception = true;
+ t = null;
+ JOptionPane
+ .showMessageDialog( this,
+ "Taxonomy [" + node.getNodeData().getTaxonomy().asSimpleText()
+ + "] is not unique in species tree",
+ "Species tree not loaded",
+ JOptionPane.ERROR_MESSAGE );
+ break;
+ }
+ else {
+ tax_set.add( node.getNodeData().getTaxonomy() );
+ }
+ }
+ }
+ }
+ if ( !exception && ( t != null ) ) {
+ setSpeciesTree( t );
+ JOptionPane.showMessageDialog( this,
+ "Species tree successfully loaded",
+ "Species tree loaded",
+ JOptionPane.INFORMATION_MESSAGE );
+ }
+ _contentpane.repaint();
+ System.gc();
+ }
+ }
+
+ private void setArrowCursor() {