+ if ( n.isRoot() ) {
+ paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file );
+ }
+ }
+
+ final private void paintUnrootedLite( final PhylogenyNode n,
+ final double low_angle,
+ final double high_angle,
+ final Graphics2D g,
+ final float urt_ov_factor ) {
+ if ( n.isRoot() ) {
+ final int x_pos = ( int ) ( getVisibleRect().x + getOvXPosition() + ( getOvMaxWidth() / 2 ) );
+ final int y_pos = ( int ) ( getVisibleRect().y + getOvYPosition() + ( getOvMaxHeight() / 2 ) );
+ n.setXSecondary( x_pos );
+ n.setYSecondary( y_pos );
+ }
+ if ( n.isExternal() ) {
+ return;
+ }
+ final float num_enclosed = n.getNumberOfExternalNodes();
+ final float x = n.getXSecondary();
+ final float y = n.getYSecondary();
+ double current_angle = low_angle;
+ for( int i = 0; i < n.getNumberOfDescendants(); ++i ) {
+ final PhylogenyNode desc = n.getChildNode( i );
+ final int desc_num_enclosed = desc.getNumberOfExternalNodes();
+ final double arc_size = ( desc_num_enclosed / num_enclosed ) * ( high_angle - low_angle );
+ float length;
+ if ( isPhyHasBranchLengths() && getControlPanel().isDrawPhylogram() ) {
+ if ( desc.getDistanceToParent() < 0 ) {
+ length = 0;
+ }
+ else {
+ length = ( float ) ( desc.getDistanceToParent() * urt_ov_factor );
+ }
+ }
+ else {
+ length = urt_ov_factor;
+ }
+ final double mid_angle = current_angle + ( arc_size / 2 );
+ final float new_x = ( float ) ( x + ( Math.cos( mid_angle ) * length ) );
+ final float new_y = ( float ) ( y + ( Math.sin( mid_angle ) * length ) );
+ desc.setXSecondary( new_x );
+ desc.setYSecondary( new_y );
+ if ( isInFoundNodes( desc ) || isInCurrentExternalNodes( desc ) ) {
+ g.setColor( getColorForFoundNode( desc ) );
+ drawRectFilled( desc.getXSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF,
+ desc.getYSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF,
+ OVERVIEW_FOUND_NODE_BOX_SIZE,
+ OVERVIEW_FOUND_NODE_BOX_SIZE,
+ g );
+ g.setColor( getTreeColorSet().getOvColor() );
+ }
+ paintUnrootedLite( desc, current_angle, current_angle + arc_size, g, urt_ov_factor );
+ current_angle += arc_size;
+ drawLine( x, y, new_x, new_y, g );
+ }
+ }
+
+ final private void pasteSubtree( final PhylogenyNode node ) {
+ if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+ errorMessageNoCutCopyPasteInUnrootedDisplay();
+ return;
+ }
+ if ( ( getCutOrCopiedTree() == null ) || getCutOrCopiedTree().isEmpty() ) {
+ JOptionPane.showMessageDialog( this,
+ "No tree in buffer (need to copy or cut a subtree first)",
+ "Attempt to paste with empty buffer",
+ JOptionPane.ERROR_MESSAGE );
+ return;
+ }
+ final String label = createASimpleTextRepresentationOfANode( getCutOrCopiedTree().getRoot() );
+ final Object[] options = { "As sibling", "As descendant", "Cancel" };
+ final int r = JOptionPane.showOptionDialog( this,
+ "How to paste subtree" + label + "?",
+ "Paste Subtree",
+ JOptionPane.CLOSED_OPTION,
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ options,
+ options[ 2 ] );
+ boolean paste_as_sibling = true;
+ if ( r == 1 ) {
+ paste_as_sibling = false;
+ }
+ else if ( r != 0 ) {
+ return;
+ }
+ final Phylogeny buffer_phy = getCutOrCopiedTree().copy();
+ buffer_phy.setAllNodesToNotCollapse();
+ PhylogenyMethods.preOrderReId( buffer_phy );
+ buffer_phy.setRooted( true );
+ boolean need_to_show_whole = false;
+ if ( paste_as_sibling ) {
+ if ( node.isRoot() ) {
+ JOptionPane.showMessageDialog( this,
+ "Cannot paste sibling to root",
+ "Attempt to paste sibling to root",
+ JOptionPane.ERROR_MESSAGE );
+ return;
+ }
+ buffer_phy.addAsSibling( node );
+ }
+ else {
+ if ( ( node.getNumberOfExternalNodes() == 1 ) && node.isRoot() ) {
+ need_to_show_whole = true;
+ _phylogeny = buffer_phy;
+ }
+ else {
+ buffer_phy.addAsChild( node );
+ }
+ }
+ if ( getCopiedAndPastedNodes() == null ) {
+ setCopiedAndPastedNodes( new HashSet<Long>() );
+ }
+ final List<PhylogenyNode> nodes = PhylogenyMethods.obtainAllNodesAsList( buffer_phy );
+ final Set<Long> node_ids = new HashSet<Long>( nodes.size() );
+ for( final PhylogenyNode n : nodes ) {
+ node_ids.add( n.getId() );
+ }
+ node_ids.add( node.getId() );
+ getCopiedAndPastedNodes().addAll( node_ids );
+ setNodeInPreorderToNull();
+ _phylogeny.externalNodesHaveChanged();
+ _phylogeny.clearHashIdToNodeMap();
+ _phylogeny.recalculateNumberOfExternalDescendants( true );
+ resetNodeIdToDistToLeafMap();
+ setEdited( true );
+ if ( need_to_show_whole ) {
+ getControlPanel().showWhole();
+ }
+ repaint();
+ }
+
+ private final StringBuffer propertiesToString( final PhylogenyNode node ) {
+ return node.getNodeData().getProperties().asText();
+ }
+
+ private void setColor( final Graphics2D g,
+ final PhylogenyNode node,
+ final boolean to_graphics_file,
+ final boolean to_pdf,
+ final boolean is_in_found_nodes,
+ final Color default_color ) {
+ if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
+ g.setColor( Color.BLACK );
+ }
+ else if ( is_in_found_nodes ) {
+ g.setColor( getColorForFoundNode( node ) );
+ }
+ else if ( getControlPanel().isUseVisualStyles() && ( node.getNodeData().getNodeVisualData() != null )
+ && ( node.getNodeData().getNodeVisualData().getFontColor() != null ) ) {
+ g.setColor( node.getNodeData().getNodeVisualData().getFontColor() );
+ }
+ else if ( getControlPanel().isColorAccordingToSequence() ) {
+ g.setColor( getSequenceBasedColor( node ) );
+ }
+ else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
+ g.setColor( getTaxonomyBasedColor( node ) );
+ }
+ else if ( getControlPanel().isColorAccordingToAnnotation()
+ && ( node.getNodeData().isHasSequence() && ( node.getNodeData().getSequence().getAnnotations() != null )
+ && ( !node.getNodeData().getSequence().getAnnotations().isEmpty() ) ) ) {
+ g.setColor( calculateColorForAnnotation( node.getNodeData().getSequence().getAnnotations() ) );
+ }
+ else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isUseVisualStyles()
+ && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
+ g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
+ }
+ else if ( to_pdf ) {
+ g.setColor( Color.BLACK );
+ }
+ else {
+ g.setColor( default_color );
+ }
+ }
+
+ final private void setCopiedAndPastedNodes( final Set<Long> nodeIds ) {
+ getMainPanel().setCopiedAndPastedNodes( nodeIds );
+ }
+
+ final private void setCutOrCopiedTree( final Phylogeny cut_or_copied_tree ) {
+ getMainPanel().setCutOrCopiedTree( cut_or_copied_tree );
+ }
+
+ private boolean setFont( final Graphics2D g, final PhylogenyNode node, final boolean is_in_found_nodes ) {
+ Font visual_font = null;
+ if ( getControlPanel().isUseVisualStyles() && ( node.getNodeData().getNodeVisualData() != null ) ) {
+ visual_font = node.getNodeData().getNodeVisualData().getFont();
+ g.setFont( visual_font != null ? visual_font : getTreeFontSet().getLargeFont() );
+ }
+ else {
+ g.setFont( getTreeFontSet().getLargeFont() );
+ }
+ if ( is_in_found_nodes ) {
+ g.setFont( g.getFont().deriveFont( Font.BOLD ) );
+ }
+ return visual_font != null;
+ }
+
+ final private void setInOv( final boolean in_ov ) {
+ _in_ov = in_ov;
+ }
+
+ final private void setOvMaxHeight( final float ov_max_height ) {
+ _ov_max_height = ov_max_height;
+ }
+
+ final private void setOvMaxWidth( final float ov_max_width ) {
+ _ov_max_width = ov_max_width;
+ }
+
+ final private void setOvXcorrectionFactor( final float f ) {
+ _ov_x_correction_factor = f;
+ }
+
+ final private void setOvXDistance( final float ov_x_distance ) {
+ _ov_x_distance = ov_x_distance;
+ }
+
+ final private void setOvXPosition( final int ov_x_position ) {
+ _ov_x_position = ov_x_position;
+ }
+
+ final private void setOvYDistance( final float ov_y_distance ) {
+ _ov_y_distance = ov_y_distance;
+ }
+
+ final private void setOvYPosition( final int ov_y_position ) {
+ _ov_y_position = ov_y_position;
+ }
+
+ final private void setOvYStart( final int ov_y_start ) {
+ _ov_y_start = ov_y_start;
+ }
+
+ final private void setScaleDistance( final double scale_distance ) {
+ _scale_distance = scale_distance;
+ }
+
+ final private void setScaleLabel( final String scale_label ) {
+ _scale_label = scale_label;
+ }
+
+ private final void setupStroke( final Graphics2D g ) {
+ if ( getYdistance() < 0.0001 ) {
+ g.setStroke( STROKE_0025 );
+ }
+ if ( getYdistance() < 0.001 ) {
+ g.setStroke( STROKE_005 );
+ }
+ else if ( getYdistance() < 0.01 ) {
+ g.setStroke( STROKE_01 );
+ }
+ else if ( getYdistance() < 0.5 ) {
+ g.setStroke( STROKE_025 );
+ }
+ else if ( getYdistance() < 1 ) {
+ g.setStroke( STROKE_05 );
+ }
+ else if ( getYdistance() < 2 ) {
+ g.setStroke( STROKE_075 );
+ }
+ else if ( ( getYdistance() < 20 ) || !getConfiguration().isAllowThickStrokes() ) {
+ g.setStroke( STROKE_1 );
+ }
+ else {
+ g.setStroke( STROKE_2 );
+ }
+ }
+
+ final private void setUpUrtFactor() {
+ final int d = getVisibleRect().width < getVisibleRect().height ? getVisibleRect().width
+ : getVisibleRect().height;
+ if ( isPhyHasBranchLengths() && getControlPanel().isDrawPhylogram() ) {
+ setUrtFactor( ( float ) ( d / ( 2 * getMaxDistanceToRoot() ) ) );
+ }
+ else {
+ final int max_depth = _circ_max_depth;
+ if ( max_depth > 0 ) {
+ setUrtFactor( d / ( 2 * max_depth ) );
+ }
+ else {
+ setUrtFactor( d / 2 );
+ }
+ }
+ setUrtFactorOv( getUrtFactor() );
+ }
+
+ final private void setUrtFactor( final float urt_factor ) {
+ _urt_factor = urt_factor;
+ }
+
+ final private void setUrtFactorOv( final float urt_factor_ov ) {
+ _urt_factor_ov = urt_factor_ov;
+ }
+
+ private void showExtDescNodeData( final PhylogenyNode node, final char separator ) {
+ final List<String> data = new ArrayList<String>();
+ final List<PhylogenyNode> nodes = node.getAllExternalDescendants();
+ if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) {
+ for( final PhylogenyNode n : getFoundNodesAsListOfPhylogenyNodes() ) {
+ if ( !nodes.contains( n ) ) {
+ nodes.add( n );
+ }
+ }
+ }
+ for( final PhylogenyNode n : nodes ) {
+ switch ( getOptions().getExtDescNodeDataToReturn() ) {
+ case NODE_NAME:
+ if ( !ForesterUtil.isEmpty( n.getName() ) ) {
+ data.add( n.getName() );
+ }
+ break;
+ case SEQUENCE_NAME:
+ if ( n.getNodeData().isHasSequence()
+ && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) {
+ data.add( n.getNodeData().getSequence().getName() );
+ }
+ break;
+ case GENE_NAME:
+ if ( n.getNodeData().isHasSequence()
+ && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getGeneName() ) ) {
+ data.add( n.getNodeData().getSequence().getGeneName() );
+ }
+ break;
+ case SEQUENCE_SYMBOL:
+ if ( n.getNodeData().isHasSequence()
+ && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) {
+ data.add( n.getNodeData().getSequence().getSymbol() );
+ }
+ break;
+ case SEQUENCE_MOL_SEQ_FASTA:
+ final StringBuilder sb = new StringBuilder();
+ if ( n.getNodeData().isHasSequence()
+ && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) {
+ final StringBuilder ann = new StringBuilder();
+ if ( getControlPanel().isShowNodeNames() && !ForesterUtil.isEmpty( n.getName() ) ) {
+ ann.append( n.getName() );
+ ann.append( separator );
+ }
+ if ( n.getNodeData().isHasTaxonomy() ) {
+ if ( getControlPanel().isShowTaxonomyCode()
+ && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
+ ann.append( n.getNodeData().getTaxonomy().getTaxonomyCode() );
+ ann.append( separator );
+ }
+ if ( getControlPanel().isShowTaxonomyScientificNames()
+ && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
+ ann.append( n.getNodeData().getTaxonomy().getScientificName() );
+ ann.append( separator );
+ }
+ if ( getControlPanel().isShowTaxonomyCommonNames()
+ && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) ) {
+ ann.append( n.getNodeData().getTaxonomy().getCommonName() );
+ ann.append( separator );
+ }
+ }
+ if ( getControlPanel().isShowSeqSymbols()
+ && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) {
+ ann.append( n.getNodeData().getSequence().getSymbol() );
+ ann.append( separator );
+ }
+ if ( getControlPanel().isShowSeqNames()
+ && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) {
+ ann.append( n.getNodeData().getSequence().getName() );
+ ann.append( separator );
+ }
+ if ( getControlPanel().isShowGeneNames()
+ && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getGeneName() ) ) {
+ ann.append( n.getNodeData().getSequence().getGeneName() );
+ ann.append( separator );
+ }
+ if ( getControlPanel().isShowSequenceAcc()
+ && n.getNodeData().getSequence().getAccession() != null ) {
+ ann.append( n.getNodeData().getSequence().getAccession().asText() );
+ ann.append( separator );
+ }
+
+ final String ann_str;
+ if ( ann.length() > 0 && ann.charAt( ann.length() - 1 ) == separator ) {
+ ann_str = ann.substring( 0, ann.length() - 1 );
+ }
+ else {
+ ann_str = ann.toString();
+ }
+ sb.append( SequenceWriter.toFasta( ann_str,
+ n.getNodeData().getSequence().getMolecularSequence(),
+ 60 ) );
+ data.add( sb.toString() );
+ }
+ break;
+ case SEQUENCE_ACC:
+ if ( n.getNodeData().isHasSequence() && ( n.getNodeData().getSequence().getAccession() != null )
+ && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getAccession().toString() ) ) {
+ data.add( n.getNodeData().getSequence().getAccession().toString() );
+ }
+ break;
+ case TAXONOMY_SCIENTIFIC_NAME:
+ if ( n.getNodeData().isHasTaxonomy()
+ && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
+ data.add( n.getNodeData().getTaxonomy().getScientificName() );
+ }
+ break;
+ case TAXONOMY_CODE:
+ if ( n.getNodeData().isHasTaxonomy()
+ && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
+ data.add( n.getNodeData().getTaxonomy().getTaxonomyCode() );
+ }
+ break;
+ case DOMAINS_ALL:
+ case DOMAINS_COLLAPSED_PER_PROTEIN:
+ if ( n.getNodeData().isHasSequence()
+ && ( n.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+ final DomainArchitecture da = n.getNodeData().getSequence().getDomainArchitecture();
+ final Set<String> s = new HashSet<String>();
+ for( int i = 0; i < da.getDomains().size(); ++i ) {
+ final ProteinDomain d = da.getDomain( i );
+ if ( d.getConfidence() <= Math.pow( 10, getDomainStructureEvalueThresholdExp() ) ) {
+ final String name = d.getName();
+ if ( !( s.contains( name ) ) ) {
+ data.add( name );
+ if ( getOptions()
+ .getExtDescNodeDataToReturn() == NodeDataField.DOMAINS_COLLAPSED_PER_PROTEIN ) {
+ s.add( name );
+ }
+ }
+ }
+ }
+ }
+ break;
+ case SEQ_ANNOTATIONS:
+ if ( n.getNodeData().isHasSequence() ) {
+ if ( n.getNodeData().isHasSequence()
+ && ( n.getNodeData().getSequence().getAnnotations() != null ) ) {
+ final SortedSet<Annotation> a = n.getNodeData().getSequence().getAnnotations();
+ for( int i = 0; i < a.size(); ++i ) {
+ data.add( n.getNodeData().getSequence().getAnnotation( i ).toString() );
+ }
+ }
+ }
+ break;
+ case GO_TERM_IDS:
+ if ( n.getNodeData().isHasSequence() ) {
+ if ( n.getNodeData().isHasSequence()
+ && ( n.getNodeData().getSequence().getAnnotations() != null ) ) {
+ final SortedSet<Annotation> a = n.getNodeData().getSequence().getAnnotations();
+ for( int i = 0; i < a.size(); ++i ) {
+ final Annotation ann = n.getNodeData().getSequence().getAnnotation( i );
+ final String ref = ann.getRef();
+ if ( ref.toUpperCase().startsWith( "GO:" ) ) {
+ data.add( ref );
+ }
+ }
+ }
+ }
+ break;
+ case UNKNOWN:
+ TreePanelUtil.showExtDescNodeDataUserSelectedHelper( getControlPanel(), n, data );
+ break;
+ default:
+ throw new IllegalArgumentException( "unknown data element: "
+ + getOptions().getExtDescNodeDataToReturn() );
+ }
+ } // for loop
+ final StringBuilder sb = new StringBuilder();
+ final int size = TreePanelUtil.nodeDataIntoStringBuffer( data, getOptions(), sb );
+ if ( ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE )
+ || ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.BUFFER_ONLY ) ) {
+ if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) {
+ System.out.println( sb );
+ }
+ if ( sb.length() < 1 ) {
+ clearCurrentExternalNodesDataBuffer();
+ }
+ else {
+ setCurrentExternalNodesDataBuffer( sb );
+ }
+ }
+ else if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.WINODW ) {
+ if ( sb.length() < 1 ) {
+ TreePanelUtil.showInformationMessage( this,
+ "No Appropriate Data (" + obtainTitleForExtDescNodeData() + ")",
+ "Descendants of selected node do not contain selected data" );
+ clearCurrentExternalNodesDataBuffer();
+ }
+ else {
+ setCurrentExternalNodesDataBuffer( sb );
+ String title;
+ if ( ( getFoundNodes0() != null ) && !getFoundNodes0().isEmpty() ) {
+ title = ( getOptions().getExtDescNodeDataToReturn() == NodeDataField.UNKNOWN ? "Data"
+ : obtainTitleForExtDescNodeData() ) + " for " + data.size() + " nodes, unique entries: "
+ + size;
+ }
+ else {
+ title = ( getOptions().getExtDescNodeDataToReturn() == NodeDataField.UNKNOWN ? "Data"
+ : obtainTitleForExtDescNodeData() ) + " for " + data.size() + "/"
+ + node.getNumberOfExternalNodes() + " external descendats of node " + node
+ + ", unique entries: " + size;
+ }
+ final String s = sb.toString().trim();
+ getMainPanel().getMainFrame().showTextFrame( s, title );
+ }
+ }
+ }
+
+ final private void showNodeDataPopup( final MouseEvent e, final PhylogenyNode node ) {
+ try {
+ if ( ( node.getName().length() > 0 )
+ || ( node.getNodeData().isHasTaxonomy()
+ && !TreePanelUtil.isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) )
+ || ( node.getNodeData().isHasSequence()
+ && !TreePanelUtil.isSequenceEmpty( node.getNodeData().getSequence() ) )
+ || ( node.getNodeData().isHasDate() ) || ( node.getNodeData().isHasDistribution() )
+ || node.getBranchData().isHasConfidences() ) {
+ _popup_buffer.setLength( 0 );
+ short lines = 0;
+ if ( node.getName().length() > 0 ) {
+ lines++;
+ _popup_buffer.append( node.getName() );
+ }
+ if ( node.getNodeData().isHasTaxonomy()
+ && !TreePanelUtil.isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) ) {
+ lines++;
+ boolean enc_data = false;
+ final Taxonomy tax = node.getNodeData().getTaxonomy();
+ if ( _popup_buffer.length() > 0 ) {
+ _popup_buffer.append( "\n" );
+ }
+ if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) {
+ _popup_buffer.append( "[" );
+ _popup_buffer.append( tax.getTaxonomyCode() );
+ _popup_buffer.append( "]" );
+ enc_data = true;
+ }
+ if ( !ForesterUtil.isEmpty( tax.getScientificName() ) ) {
+ if ( enc_data ) {
+ _popup_buffer.append( " " );
+ }
+ _popup_buffer.append( tax.getScientificName() );
+ enc_data = true;
+ }
+ if ( !ForesterUtil.isEmpty( tax.getCommonName() ) ) {
+ if ( enc_data ) {
+ _popup_buffer.append( " (" );
+ }
+ else {
+ _popup_buffer.append( "(" );
+ }
+ _popup_buffer.append( tax.getCommonName() );
+ _popup_buffer.append( ")" );
+ enc_data = true;
+ }
+ if ( !ForesterUtil.isEmpty( tax.getAuthority() ) ) {
+ if ( enc_data ) {
+ _popup_buffer.append( " (" );
+ }
+ else {
+ _popup_buffer.append( "(" );
+ }
+ _popup_buffer.append( tax.getAuthority() );
+ _popup_buffer.append( ")" );
+ enc_data = true;
+ }
+ if ( !ForesterUtil.isEmpty( tax.getRank() ) ) {
+ if ( enc_data ) {
+ _popup_buffer.append( " [" );
+ }
+ else {
+ _popup_buffer.append( "[" );
+ }
+ _popup_buffer.append( tax.getRank() );
+ _popup_buffer.append( "]" );
+ enc_data = true;
+ }
+ if ( tax.getSynonyms().size() > 0 ) {
+ if ( enc_data ) {
+ _popup_buffer.append( " " );
+ }
+ _popup_buffer.append( "[" );
+ int counter = 1;
+ for( final String syn : tax.getSynonyms() ) {
+ if ( !ForesterUtil.isEmpty( syn ) ) {
+ enc_data = true;
+ _popup_buffer.append( syn );
+ if ( counter < tax.getSynonyms().size() ) {
+ _popup_buffer.append( ", " );
+ }
+ }
+ counter++;
+ }
+ _popup_buffer.append( "]" );
+ }
+ if ( !enc_data ) {
+ if ( ( tax.getIdentifier() != null )
+ && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) ) {
+ if ( !ForesterUtil.isEmpty( tax.getIdentifier().getProvider() ) ) {
+ _popup_buffer.append( "[" );
+ _popup_buffer.append( tax.getIdentifier().getProvider() );
+ _popup_buffer.append( "] " );
+ }
+ _popup_buffer.append( tax.getIdentifier().getValue() );
+ }
+ }
+ }
+ if ( node.getNodeData().isHasSequence()
+ && !TreePanelUtil.isSequenceEmpty( node.getNodeData().getSequence() ) ) {
+ lines++;
+ boolean enc_data = false;
+ if ( _popup_buffer.length() > 0 ) {
+ _popup_buffer.append( "\n" );
+ }
+ final Sequence seq = node.getNodeData().getSequence();
+ if ( seq.getAccession() != null ) {
+ _popup_buffer.append( "[" );
+ if ( !ForesterUtil.isEmpty( seq.getAccession().getSource() ) ) {
+ _popup_buffer.append( seq.getAccession().getSource() );
+ _popup_buffer.append( ":" );
+ }
+ _popup_buffer.append( seq.getAccession().getValue() );
+ _popup_buffer.append( "]" );
+ enc_data = true;
+ }
+ if ( !ForesterUtil.isEmpty( seq.getSymbol() ) ) {
+ if ( enc_data ) {
+ _popup_buffer.append( " [" );
+ }
+ else {
+ _popup_buffer.append( "[" );
+ }
+ _popup_buffer.append( seq.getSymbol() );
+ _popup_buffer.append( "]" );
+ enc_data = true;
+ }
+ if ( !ForesterUtil.isEmpty( seq.getGeneName() ) ) {
+ if ( enc_data ) {
+ _popup_buffer.append( " [" );
+ }
+ else {
+ _popup_buffer.append( "[" );
+ }
+ _popup_buffer.append( seq.getGeneName() );
+ _popup_buffer.append( "]" );
+ enc_data = true;
+ }
+ if ( !ForesterUtil.isEmpty( seq.getName() ) ) {
+ if ( enc_data ) {
+ _popup_buffer.append( " " );
+ }
+ _popup_buffer.append( seq.getName() );
+ }
+ }
+ if ( node.getNodeData().isHasDate() ) {
+ lines++;
+ if ( _popup_buffer.length() > 0 ) {
+ _popup_buffer.append( "\n" );
+ }
+ _popup_buffer.append( node.getNodeData().getDate().asSimpleText() );
+ }
+ if ( node.getNodeData().isHasDistribution() ) {
+ lines++;
+ if ( _popup_buffer.length() > 0 ) {
+ _popup_buffer.append( "\n" );
+ }
+ _popup_buffer.append( node.getNodeData().getDistribution().asSimpleText() );
+ }
+ if ( node.getBranchData().isHasConfidences() ) {
+ final List<Confidence> confs = node.getBranchData().getConfidences();
+ for( final Confidence confidence : confs ) {
+ lines++;
+ if ( _popup_buffer.length() > 0 ) {
+ _popup_buffer.append( "\n" );
+ }
+ if ( !ForesterUtil.isEmpty( confidence.getType() ) ) {
+ _popup_buffer.append( "[" );
+ _popup_buffer.append( confidence.getType() );
+ _popup_buffer.append( "] " );
+ }
+ _popup_buffer.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( confidence.getValue(),
+ getOptions()
+ .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) );
+ if ( confidence.getStandardDeviation() != Confidence.CONFIDENCE_DEFAULT_VALUE ) {
+ _popup_buffer.append( " (sd=" );
+ _popup_buffer.append( FORMATTER_CONFIDENCE
+ .format( ForesterUtil.round( confidence.getStandardDeviation(),
+ getOptions()
+ .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) );
+ _popup_buffer.append( ")" );
+ }
+ }
+ }
+ if ( node.getNodeData().isHasProperties() ) {
+ if ( _popup_buffer.length() > 0 ) {
+ _popup_buffer.append( "\n" );
+ }
+ _popup_buffer.append( node.getNodeData().getProperties().asText() );
+ }
+ if ( _popup_buffer.length() > 0 ) {
+ if ( !getConfiguration().isUseNativeUI() ) {
+ _rollover_popup
+ .setBorder( BorderFactory.createLineBorder( getTreeColorSet().getBranchColor() ) );
+ _rollover_popup.setBackground( getTreeColorSet().getBackgroundColor() );
+ if ( isInFoundNodes0( node ) && !isInFoundNodes1( node ) ) {
+ _rollover_popup.setForeground( getTreeColorSet().getFoundColor0() );
+ }
+ else if ( !isInFoundNodes0( node ) && isInFoundNodes1( node ) ) {
+ _rollover_popup.setForeground( getTreeColorSet().getFoundColor1() );
+ }
+ else if ( isInFoundNodes0( node ) && isInFoundNodes1( node ) ) {
+ _rollover_popup.setForeground( getTreeColorSet().getFoundColor0and1() );
+ }
+ else {
+ _rollover_popup.setForeground( getTreeColorSet().getSequenceColor() );
+ }
+ }
+ else {
+ _rollover_popup.setBorder( BorderFactory.createLineBorder( Color.BLACK ) );
+ }
+ _rollover_popup.setText( _popup_buffer.toString() );
+ _node_desc_popup = PopupFactory.getSharedInstance()
+ .getPopup( null,
+ _rollover_popup,
+ e.getLocationOnScreen().x + 10,
+ e.getLocationOnScreen().y - ( lines * 20 ) );
+ _node_desc_popup.show();
+ }
+ }
+ }
+ catch ( final Exception ex ) {
+ // Do nothing.
+ }
+ }
+
+ final private void showNodeEditFrame( final PhylogenyNode n ) {
+ if ( _node_frame_index < TreePanel.MAX_NODE_FRAMES ) {
+ // pop up edit box for single node
+ _node_frames[ _node_frame_index ] = new NodeFrame( n, _phylogeny, this, _node_frame_index, "" );
+ _node_frame_index++;
+ }
+ else {
+ JOptionPane.showMessageDialog( this, "too many node windows are open" );
+ }
+ }
+
+ final private void showNodeFrame( final PhylogenyNode n ) {
+ if ( _node_frame_index < TreePanel.MAX_NODE_FRAMES ) {
+ // pop up edit box for single node
+ _node_frames[ _node_frame_index ] = new NodeFrame( n, _phylogeny, this, _node_frame_index );
+ _node_frame_index++;
+ }
+ else {
+ JOptionPane.showMessageDialog( this, "too many node windows are open" );
+ }
+ }
+
+ final private void switchDisplaygetPhylogenyGraphicsType() {
+ switch ( getPhylogenyGraphicsType() ) {
+ case RECTANGULAR:
+ setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE );
+ getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE );
+ break;
+ case EURO_STYLE:
+ setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.ROUNDED );
+ getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.ROUNDED );
+ break;
+ case ROUNDED:
+ setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CURVED );
+ getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CURVED );
+ break;
+ case CURVED:
+ setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.TRIANGULAR );
+ getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.TRIANGULAR );
+ break;
+ case TRIANGULAR:
+ setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CONVEX );
+ getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CONVEX );
+ break;
+ case CONVEX:
+ setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
+ getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
+ break;
+ case UNROOTED:
+ setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CIRCULAR );
+ getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CIRCULAR );
+ break;
+ case CIRCULAR:
+ setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
+ getOptions().setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
+ break;
+ default:
+ throw new RuntimeException( "unkwnown display type: " + getPhylogenyGraphicsType() );
+ }
+ if ( getControlPanel().getDynamicallyHideData() != null ) {
+ if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+ getControlPanel().getDynamicallyHideData().setEnabled( false );
+ }
+ else {
+ getControlPanel().getDynamicallyHideData().setEnabled( true );
+ }
+ }
+ if ( isPhyHasBranchLengths() && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
+ getControlPanel().setDrawPhylogramEnabled( true );
+ }
+ else {
+ getControlPanel().setDrawPhylogramEnabled( false );
+ }
+ getMainPanel().getMainFrame().setSelectedTypeInTypeMenu( getPhylogenyGraphicsType() );
+ }
+
+ final void calcMaxDepth() {
+ if ( _phylogeny != null ) {
+ _circ_max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny );
+ }
+ }
+
+ /**
+ * Set parameters for printing the displayed tree
+ *
+ */
+ final void calcParametersForPainting( final int x, final int y ) {
+ // updateStyle(); not needed?
+ if ( ( _phylogeny != null ) && !_phylogeny.isEmpty() ) {
+ initNodeData();
+ calculateLongestExtNodeInfo();
+ if ( ( getLongestExtNodeInfo() > ( x * 0.6 ) )
+ && ( getTreeFontSet().getLargeFont().getSize() > ( 2 + TreeFontSet.FONT_SIZE_CHANGE_STEP ) ) ) {
+ while ( ( getLongestExtNodeInfo() > ( x * 0.7 ) )
+ && ( getTreeFontSet().getLargeFont().getSize() > 2 ) ) {
+ getMainPanel().getTreeFontSet().decreaseFontSize( getConfiguration().getMinBaseFontSize(), true );
+ calculateLongestExtNodeInfo();
+ }
+ }
+ else {
+ while ( ( getLongestExtNodeInfo() < ( x * 0.6 ) ) && ( getTreeFontSet().getLargeFont()
+ .getSize() <= ( getTreeFontSet().getLargeFontMemory().getSize()
+ - TreeFontSet.FONT_SIZE_CHANGE_STEP ) ) ) {
+ getMainPanel().getTreeFontSet().increaseFontSize();
+ calculateLongestExtNodeInfo();
+ }
+ }
+ //_length_of_longest_text = calcLengthOfLongestText();
+ int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes();
+ final int max_depth = PhylogenyMethods.calculateMaxDepthConsiderCollapsed( _phylogeny ) + 1;
+ if ( ext_nodes == 1 ) {
+ ext_nodes = max_depth;
+ if ( ext_nodes < 1 ) {
+ ext_nodes = 1;
+ }
+ }
+ updateOvSizes();
+ float xdist = 0;
+ float ov_xdist = 0;
+ if ( !isNonLinedUpCladogram() ) {
+ xdist = ( float ) ( ( x - getLongestExtNodeInfo() - TreePanel.MOVE ) / ( ext_nodes + 3.0 ) );
+ ov_xdist = ( float ) ( getOvMaxWidth() / ( ext_nodes + 3.0 ) );
+ }
+ else {
+ xdist = ( ( x - getLongestExtNodeInfo() - TreePanel.MOVE ) / ( max_depth + 1 ) );
+ ov_xdist = ( getOvMaxWidth() / ( max_depth + 1 ) );
+ }
+ float ydist = ( float ) ( ( y - TreePanel.MOVE ) / ( ext_nodes * 2.0 ) );
+ if ( xdist < 0.0 ) {
+ xdist = 0.0f;
+ }
+ if ( ov_xdist < 0.0 ) {
+ ov_xdist = 0.0f;
+ }
+ if ( ydist < 0.0 ) {
+ ydist = 0.0f;
+ }
+ setXdistance( xdist );
+ setYdistance( ydist );
+ setOvXDistance( ov_xdist );
+ final double height = _phylogeny.calculateHeight( !_options.isCollapsedWithAverageHeigh() );
+ //final double height = PhylogenyMethods.calculateMaxDepth( _phylogeny );
+ if ( height > 0 ) {
+ final float corr = ( float ) ( ( x - ( 2.0 * TreePanel.MOVE ) - getLongestExtNodeInfo()
+ - getXdistance() ) / height );
+ setXcorrectionFactor( corr > 0 ? corr : 0 );
+ final float ov_corr = ( float ) ( ( getOvMaxWidth() - getOvXDistance() ) / height );
+ setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 );
+ }
+ else {
+ setXcorrectionFactor( 0 );
+ setOvXcorrectionFactor( 0 );
+ }
+ _circ_max_depth = max_depth;
+ setUpUrtFactor();
+ //
+ if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
+ && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
+ // int dynamic_hiding_factor = calcDynamicHidingFactor();
+ // if ( dynamic_hiding_factor > 1 ) {
+ // while ( dynamic_hiding_factor > 1
+ // && getTreeFontSet()._fm_large.getHeight() > TreeFontSet.SMALL_FONTS_BASE ) {
+ // getTreeFontSet().decreaseFontSize( 1, true );
+ // dynamic_hiding_factor = calcDynamicHidingFactor();
+ // }
+ // }
+ // else if ( getTreeFontSet().isDecreasedSizeBySystem() ) {
+ // while ( dynamic_hiding_factor < 1 && getTreeFontSet()._fm_large.getHeight() < 12 ) {
+ // getTreeFontSet().increaseFontSize();
+ // dynamic_hiding_factor = calcDynamicHidingFactor();
+ // }
+ // }
+ }
+ //
+ }
+ }
+
+ final void calculateLongestExtNodeInfo() {
+ if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
+ return;
+ }
+ int max_possible_length = ForesterUtil
+ .roundToInt( ( getSize().getWidth() - ( 2 * MOVE ) ) * AptxConstants.EXT_NODE_INFO_LENGTH_MAX_RATIO );
+ if ( max_possible_length < 20 ) {
+ max_possible_length = 20;
+ }
+ int longest = 30;
+ int longest_txt = 0;
+ _longest_domain = 0;
+ PhylogenyNode longest_txt_node = _phylogeny.getFirstExternalNode();
+ for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) {
+ int sum = 0;
+ if ( node.isCollapse() ) {
+ continue;
+ }
+ final StringBuilder sb = new StringBuilder();
+ nodeDataAsSB( node, sb );
+ if ( node.getNodeData().isHasTaxonomy() ) {
+ nodeTaxonomyDataAsSB( node.getNodeData().getTaxonomy(), sb );
+ }
+ final int txt = sb.length();
+ if ( txt > longest_txt ) {
+ longest_txt = txt;
+ longest_txt_node = node;
+ }
+ boolean use_vis = false;
+ final Graphics2D g = ( Graphics2D ) getGraphics();
+ if ( getControlPanel().isUseVisualStyles() ) {
+ use_vis = setFont( g, node, false );
+ }
+ if ( !use_vis ) {
+ sum = getFontMetricsForLargeDefaultFont().stringWidth( sb.toString() );
+ }
+ else {
+ sum = getFontMetrics( g.getFont() ).stringWidth( sb.toString() );
+ }
+ if ( getControlPanel().isShowBinaryCharacters() && node.getNodeData().isHasBinaryCharacters() ) {
+ sum += getFontMetricsForLargeDefaultFont().stringWidth( node.getNodeData().getBinaryCharacters()
+ .getGainedCharactersAsStringBuffer().toString() );
+ }
+ if ( getControlPanel().isShowVectorData() && ( node.getNodeData().getVector() != null )
+ && ( node.getNodeData().getVector().size() > 0 ) ) {
+ if ( getConfiguration() != null ) {
+ sum += getConfiguration().getVectorDataWidth() + 10;
+ }
+ else {
+ sum += RenderableVector.VECTOR_DEFAULT_WIDTH + 10;
+ }
+ }
+ if ( getControlPanel().isShowDomainArchitectures() && node.getNodeData().isHasSequence()
+ && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+ // FIXME
+ // TODO this might need some clean up
+ final DomainArchitecture d = node.getNodeData().getSequence().getDomainArchitecture();
+ sum += ( ( _domain_structure_width
+ / ( ( RenderableDomainArchitecture ) d ).getOriginalSize().getWidth() ) * d.getTotalLength() )
+ + 10;
+ if ( d.getTotalLength() > _longest_domain ) {
+ _longest_domain = d.getTotalLength();
+ }
+ }
+ if ( getControlPanel().isShowMolSequences() && ( node.getNodeData().isHasSequence() )
+ && ( node.getNodeData().getSequence().isMolecularSequenceAligned() )
+ && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) ) {
+ // FIXME
+ sum += RenderableMsaSequence.DEFAULT_WIDTH + 30;
+ }
+ if ( sum >= max_possible_length ) {
+ _longest_ext_node_info = max_possible_length;
+ // return; //FIXME why?
+ }
+ if ( sum > longest ) {
+ longest = sum;
+ }
+ }
+ _ext_node_with_longest_txt_info = longest_txt_node;
+ if ( longest >= max_possible_length ) {
+ _longest_ext_node_info = max_possible_length;
+ }
+ else {
+ _longest_ext_node_info = longest;
+ }
+ _length_of_longest_text = calcLengthOfLongestText();
+ }
+
+ final void calculateScaleDistance() {
+ if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
+ return;
+ }
+ final double height = getMaxDistanceToRoot();
+ if ( height > 0 ) {
+ if ( ( height <= 0.5 ) ) {
+ setScaleDistance( 0.01 );
+ }
+ else if ( height <= 5.0 ) {
+ setScaleDistance( 0.1 );
+ }
+ else if ( height <= 50.0 ) {
+ setScaleDistance( 1 );
+ }
+ else if ( height <= 500.0 ) {
+ setScaleDistance( 10 );
+ }
+ else {
+ setScaleDistance( 100 );
+ }
+ }
+ else {
+ setScaleDistance( 0.0 );
+ }
+ String scale_label = String.valueOf( getScaleDistance() );
+ if ( !ForesterUtil.isEmpty( _phylogeny.getDistanceUnit() ) ) {
+ scale_label += " [" + _phylogeny.getDistanceUnit() + "]";
+ }
+ setScaleLabel( scale_label );
+ }
+
+ final Color calculateSequenceBasedColor( final Sequence seq ) {
+ if ( ForesterUtil.isEmpty( seq.getName() ) ) {
+ return getTreeColorSet().getSequenceColor();
+ }
+ Color c = null;
+ final String seq_name = seq.getName();
+ c = getControlPanel().getSequenceColors().get( seq_name );
+ if ( c == null ) {
+ c = AptxUtil.calculateColorFromString( seq_name, false );
+ getControlPanel().getSequenceColors().put( seq_name, c );
+ }
+ return c;
+ }
+
+ final Color calculateTaxonomyBasedColor( final Taxonomy tax ) {
+ if ( getOptions().isColorByTaxonomicGroup() ) {
+ if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) {
+ boolean ex = false;
+ String group = null;
+ try {
+ group = TaxonomyUtil.getTaxGroupByTaxCode( tax.getTaxonomyCode() );
+ }
+ catch ( final Exception e ) {
+ ex = true;
+ }
+ if ( !ex && !ForesterUtil.isEmpty( group ) ) {
+ final Color c = ForesterUtil.obtainColorDependingOnTaxonomyGroup( group );
+ if ( c != null ) {
+ return c;
+ }
+ }
+ }
+ return getTreeColorSet().getTaxonomyColor();
+ }
+ else {
+ if ( ForesterUtil.isEmpty( tax.getTaxonomyCode() ) && ForesterUtil.isEmpty( tax.getScientificName() ) ) {
+ return getTreeColorSet().getTaxonomyColor();
+ }
+ Color c = null;
+ if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) {
+ c = getControlPanel().getSpeciesColors().get( tax.getTaxonomyCode() );
+ }
+ if ( ( c == null ) && !ForesterUtil.isEmpty( tax.getScientificName() ) ) {
+ c = getControlPanel().getSpeciesColors().get( tax.getScientificName() );
+ }
+ if ( c == null ) {
+ if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) {
+ c = AptxUtil.calculateColorFromString( tax.getTaxonomyCode(), true );
+ getControlPanel().getSpeciesColors().put( tax.getTaxonomyCode(), c );
+ }
+ else {
+ c = AptxUtil.calculateColorFromString( tax.getScientificName(), true );
+ getControlPanel().getSpeciesColors().put( tax.getScientificName(), c );
+ }
+ }
+ return c;
+ }
+ }
+
+ void clearCurrentExternalNodesDataBuffer() {
+ setCurrentExternalNodesDataBuffer( new StringBuilder() );
+ }
+
+ /**
+ * Collapse the tree from the given node
+ *
+ * @param node
+ * a PhylogenyNode
+ */
+ final void collapse( final PhylogenyNode node ) {
+ if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+ JOptionPane.showMessageDialog( this,
+ "Cannot collapse in unrooted display type",
+ "Attempt to collapse in unrooted display",
+ JOptionPane.WARNING_MESSAGE );
+ return;
+ }
+ if ( !node.isExternal() && !node.isRoot() ) {
+ final boolean collapse = !node.isCollapse();
+ TreePanelUtil.collapseSubtree( node, collapse );
+ updateSetOfCollapsedExternalNodes();
+ _phylogeny.recalculateNumberOfExternalDescendants( true );
+ resetNodeIdToDistToLeafMap();
+ calculateLongestExtNodeInfo();
+ setNodeInPreorderToNull();
+ _control_panel.displayedPhylogenyMightHaveChanged( true );
+ resetPreferredSize();
+ updateOvSizes();
+ _main_panel.adjustJScrollPane();
+ repaint();
+ }
+ }
+
+ final void uncollapseAll( final PhylogenyNode node ) {
+ if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+ JOptionPane.showMessageDialog( this,
+ "Cannot uncollapse in unrooted display type",
+ "Attempt to uncollapse in unrooted display",
+ JOptionPane.WARNING_MESSAGE );
+ return;
+ }
+ if ( !node.isExternal() ) {
+ TreePanelUtil.uncollapseSubtree( node );
+ updateSetOfCollapsedExternalNodes();
+ _phylogeny.recalculateNumberOfExternalDescendants( true );
+ resetNodeIdToDistToLeafMap();
+ calculateLongestExtNodeInfo();
+ setNodeInPreorderToNull();
+ _control_panel.displayedPhylogenyMightHaveChanged( true );
+ resetPreferredSize();
+ updateOvSizes();
+ _main_panel.adjustJScrollPane();
+ repaint();
+ }
+ }
+
+ final void collapseSpeciesSpecificSubtrees() {
+ if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+ return;
+ }
+ setWaitCursor();
+ TreePanelUtil.collapseSpeciesSpecificSubtrees( _phylogeny );
+ updateSetOfCollapsedExternalNodes();
+ _phylogeny.recalculateNumberOfExternalDescendants( true );
+ resetNodeIdToDistToLeafMap();
+ calculateLongestExtNodeInfo();
+ setNodeInPreorderToNull();
+ resetPreferredSize();
+ resetDepthCollapseDepthValue();
+ resetRankCollapseRankValue();
+ _main_panel.adjustJScrollPane();
+ getControlPanel().showWhole();
+ setArrowCursor();
+ }
+
+ final void colorRank( final String rank ) {
+ if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+ return;
+ }
+ setWaitCursor();
+ AptxUtil.removeBranchColors( _phylogeny );
+ final int colorizations = TreePanelUtil.colorPhylogenyAccordingToRanks( _phylogeny, rank, this );
+ if ( colorizations > 0 ) {
+ _control_panel.setColorBranches( true );
+ if ( _control_panel.getUseVisualStylesCb() != null ) {
+ _control_panel.getUseVisualStylesCb().setSelected( true );
+ }
+ if ( _control_panel.getColorAccSpeciesCb() != null ) {
+ _control_panel.getColorAccSpeciesCb().setSelected( false );
+ }
+ _options.setColorLabelsSameAsParentBranch( true );
+ if ( getMainPanel().getMainFrame()._color_labels_same_as_parent_branch != null ) {
+ getMainPanel().getMainFrame()._color_labels_same_as_parent_branch.setSelected( true );
+ }
+ _control_panel.repaint();
+ }
+ setArrowCursor();
+ repaint();
+ if ( colorizations > 0 ) {
+ String msg = "Taxonomy colorization via " + rank + " completed:\n";
+ if ( colorizations > 1 ) {
+ msg += "colorized " + colorizations + " subtrees";
+ }
+ else {
+ msg += "colorized one subtree";
+ }
+ setEdited( true );
+ JOptionPane.showMessageDialog( this,
+ msg,
+ "Taxonomy Rank-Colorization Completed (" + rank + ")",
+ JOptionPane.INFORMATION_MESSAGE );
+ }
+ else {
+ String msg = "Could not taxonomy rank-colorize any subtree via " + rank + ".\n";
+ msg += "Possible solutions (given that suitable taxonomic information is present):\n";
+ msg += "select a different rank (e.g. phylum, genus, ...)\n";
+ msg += " and/or\n";
+ msg += "execute:\n";
+ msg += "1. \"" + MainFrame.OBTAIN_DETAILED_TAXONOMIC_INFORMATION + "\" (Tools)\n";
+ msg += "2. \"" + MainFrame.INFER_ANCESTOR_TAXONOMIES + "\" (Analysis)";
+ JOptionPane.showMessageDialog( this,
+ msg,
+ "Taxonomy Rank-Colorization Failed",
+ JOptionPane.WARNING_MESSAGE );
+ }
+ }
+
+ final void confColor() {
+ if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+ return;
+ }
+ setWaitCursor();
+ AptxUtil.removeBranchColors( _phylogeny );
+ TreePanelUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this );
+ _control_panel.setColorBranches( true );
+ if ( _control_panel.getUseVisualStylesCb() != null ) {
+ _control_panel.getUseVisualStylesCb().setSelected( true );
+ }
+ setArrowCursor();
+ repaint();
+ }
+
+ final void decreaseDomainStructureEvalueThresholdExp() {
+ if ( _domain_structure_e_value_thr_exp > -20 ) {
+ _domain_structure_e_value_thr_exp -= 1;
+ }
+ }
+
+ /**
+ * Find the node, if any, at the given location
+ *
+ * @param x
+ * @param y
+ * @return pointer to the node at x,y, null if not found
+ */
+ public final PhylogenyNode findNode( final int x, final int y ) {
+ if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
+ return null;
+ }
+ final int half_box_size_plus_wiggle = ( getOptions().getDefaultNodeShapeSize() / 2 ) + WIGGLE;
+ for( final PhylogenyNodeIterator iter = _phylogeny.iteratorPostorder(); iter.hasNext(); ) {
+ final PhylogenyNode node = iter.next();
+ if ( ( _phylogeny.isRooted() || !node.isRoot() || ( node.getNumberOfDescendants() > 2 ) )
+ && ( ( node.getXcoord() - half_box_size_plus_wiggle ) <= x )
+ && ( ( node.getXcoord() + half_box_size_plus_wiggle ) >= x )
+ && ( ( node.getYcoord() - half_box_size_plus_wiggle ) <= y )
+ && ( ( node.getYcoord() + half_box_size_plus_wiggle ) >= y ) ) {
+ return node;
+ }
+ }
+ return null;
+ }
+
+ final Configuration getConfiguration() {
+ return _configuration;
+ }
+
+ final ControlPanel getControlPanel() {
+ return _control_panel;
+ }
+
+ String getCurrentExternalNodesDataBufferAsString() {
+ return _current_external_nodes_data_buffer.toString();
+ }
+
+ int getCurrentExternalNodesDataBufferChangeCounter() {
+ return _current_external_nodes_data_buffer_change_counter;
+ }
+
+ final int getDomainStructureEvalueThresholdExp() {
+ return _domain_structure_e_value_thr_exp;
+ }
+
+ public final Set<Long> getFoundNodes0() {
+ return _found_nodes_0;
+ }
+
+ public final Set<Long> getFoundNodes1() {
+ return _found_nodes_1;
+ }
+
+ public List<PhylogenyNode> getFoundNodesAsListOfPhylogenyNodes() {
+ final List<PhylogenyNode> additional_nodes = new ArrayList<PhylogenyNode>();
+ if ( getFoundNodes0() != null ) {
+ for( final Long id : getFoundNodes0() ) {
+ final PhylogenyNode n = _phylogeny.getNode( id );
+ if ( n != null ) {
+ additional_nodes.add( n );
+ }
+ }
+ }
+ if ( getFoundNodes1() != null ) {
+ for( final Long id : getFoundNodes1() ) {
+ if ( ( getFoundNodes0() == null ) || !getFoundNodes0().contains( id ) ) {
+ final PhylogenyNode n = _phylogeny.getNode( id );
+ if ( n != null ) {
+ additional_nodes.add( n );
+ }
+ }
+ }
+ }
+ return additional_nodes;
+ }
+
+ final Color getGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node ) {
+ if ( getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
+ return ( PhylogenyMethods.getBranchColorValue( node ) );
+ }
+ else {
+ return ( getTreeColorSet().getBranchColor() );
+ }
+ }
+
+ final int getLongestExtNodeInfo() {
+ return _longest_ext_node_info;
+ }
+
+ final Options getOptions() {
+ if ( _options == null ) {
+ _options = getControlPanel().getOptions();
+ }
+ return _options;
+ }
+
+ final Rectangle2D getOvRectangle() {
+ return _ov_rectangle;
+ }
+
+ final Rectangle getOvVirtualRectangle() {
+ return _ov_virtual_rectangle;
+ }
+
+ final PHYLOGENY_GRAPHICS_TYPE getPhylogenyGraphicsType() {
+ return _graphics_type;
+ }
+
+ final Color getSequenceBasedColor( final PhylogenyNode node ) {
+ if ( node.getNodeData().isHasSequence() ) {
+ return calculateSequenceBasedColor( node.getNodeData().getSequence() );
+ }
+ // return non-colorized color
+ return getTreeColorSet().getSequenceColor();
+ }
+
+ final double getStartingAngle() {
+ return _urt_starting_angle;
+ }
+
+ DescriptiveStatistics getStatisticsForExpressionValues() {
+ return _statistics_for_vector_data;
+ }
+
+ final Color getTaxonomyBasedColor( final PhylogenyNode node ) {
+ if ( node.isExternal() && node.getNodeData().isHasTaxonomy() ) {
+ return calculateTaxonomyBasedColor( node.getNodeData().getTaxonomy() );
+ }
+ // return non-colorized color
+ return getTreeColorSet().getTaxonomyColor();
+ }
+
+ final File getTreeFile() {
+ return _treefile;
+ }
+
+ final float getXcorrectionFactor() {
+ return _x_correction_factor;
+ }
+
+ final float getXdistance() {
+ return _x_distance;
+ }
+
+ final float getYdistance() {
+ return _y_distance;
+ }
+
+ final void increaseDomainStructureEvalueThresholdExp() {
+ if ( _domain_structure_e_value_thr_exp < 3 ) {
+ _domain_structure_e_value_thr_exp += 1;
+ }
+ }
+
+ final void initNodeData() {
+ if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
+ return;
+ }
+ double _max_original_domain_structure_width = 0.0;
+ for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) {
+ if ( node.getNodeData().isHasSequence()
+ && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+ RenderableDomainArchitecture rds = null;
+ if ( !( node.getNodeData().getSequence()
+ .getDomainArchitecture() instanceof RenderableDomainArchitecture ) ) {
+ if ( SPECIAL_DOMAIN_COLORING ) {
+ rds = new RenderableDomainArchitecture( node.getNodeData().getSequence()
+ .getDomainArchitecture(), node.getName() );
+ }
+ else {
+ rds = new RenderableDomainArchitecture( node.getNodeData().getSequence()
+ .getDomainArchitecture() );
+ }
+ node.getNodeData().getSequence().setDomainArchitecture( rds );
+ }
+ else {
+ rds = ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture();
+ }
+ if ( getControlPanel().isShowDomainArchitectures() ) {
+ final double dsw = rds.getOriginalSize().getWidth();
+ if ( dsw > _max_original_domain_structure_width ) {
+ _max_original_domain_structure_width = dsw;
+ }
+ }
+ }
+ }
+ if ( getControlPanel().isShowDomainArchitectures() ) {
+ final float ds_factor_width = ( float ) ( _domain_structure_width / _max_original_domain_structure_width );
+ for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) {
+ if ( node.getNodeData().isHasSequence()
+ && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+ final RenderableDomainArchitecture rds = ( RenderableDomainArchitecture ) node.getNodeData()
+ .getSequence().getDomainArchitecture();
+ rds.setRenderingFactorWidth( ds_factor_width );
+ rds.setParameter( _domain_structure_e_value_thr_exp );
+ }
+ }
+ }
+ }
+
+ final boolean inOv( final MouseEvent e ) {
+ return ( ( e.getX() > ( getVisibleRect().x + getOvXPosition() + 1 ) )
+ && ( e.getX() < ( ( getVisibleRect().x + getOvXPosition() + getOvMaxWidth() ) - 1 ) )
+ && ( e.getY() > ( getVisibleRect().y + getOvYPosition() + 1 ) )
+ && ( e.getY() < ( ( getVisibleRect().y + getOvYPosition() + getOvMaxHeight() ) - 1 ) ) );
+ }
+
+ final boolean inOvRectangle( final MouseEvent e ) {
+ return ( ( e.getX() >= ( getOvRectangle().getX() - 1 ) )
+ && ( e.getX() <= ( getOvRectangle().getX() + getOvRectangle().getWidth() + 1 ) )
+ && ( e.getY() >= ( getOvRectangle().getY() - 1 ) )
+ && ( e.getY() <= ( getOvRectangle().getY() + getOvRectangle().getHeight() + 1 ) ) );
+ }
+
+ final boolean isCanCollapse() {
+ return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
+ }
+
+ final boolean isCanUncollapseAll( final PhylogenyNode node ) {
+ if ( node.isExternal() || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) ) {
+ return false;
+ }
+ if ( node.isCollapse() ) {
+ return true;
+ }
+ final PhylogenyNodeIterator it = new PreorderTreeIterator( node );
+ while ( it.hasNext() ) {
+ if ( it.next().isCollapse() ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ final boolean isCanColorSubtree() {
+ return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
+ }
+
+ final boolean isCanCopy() {
+ return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
+ }
+
+ final boolean isCanCut( final PhylogenyNode node ) {
+ return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable()
+ && !node.isRoot() );
+ }
+
+ final boolean isCanDelete() {
+ return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
+ }
+
+ final boolean isCanPaste() {
+ return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable()
+ && ( getCutOrCopiedTree() != null ) && !getCutOrCopiedTree().isEmpty() );
+ }
+
+ final boolean isCanReroot() {
+ return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && ( _subtree_index < 1 ) );
+ }
+
+ final boolean isCanSubtree( final PhylogenyNode node ) {
+ return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && !node.isExternal()
+ && ( !node.isRoot() || ( _subtree_index > 0 ) ) );
+ }
+
+ final boolean isCurrentTreeIsSubtree() {
+ return ( _subtree_index > 0 );
+ }
+
+ final boolean isEdited() {
+ return _edited;
+ }
+
+ final boolean isInOvRect() {
+ return _in_ov_rect;
+ }
+
+ final boolean isOvOn() {
+ return _ov_on;
+ }
+
+ final boolean isPhyHasBranchLengths() {
+ return _phy_has_branch_lengths;
+ }
+
+ final void midpointRoot() {
+ if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+ return;