2 package org.forester.archaeopteryx;
5 import java.awt.Component;
6 import java.io.UnsupportedEncodingException;
7 import java.net.URLEncoder;
8 import java.util.ArrayList;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.List;
14 import java.util.Map.Entry;
16 import java.util.SortedMap;
17 import java.util.SortedSet;
18 import java.util.TreeMap;
20 import javax.swing.JOptionPane;
22 import org.forester.analysis.TaxonomyDataManager;
23 import org.forester.phylogeny.Phylogeny;
24 import org.forester.phylogeny.PhylogenyMethods;
25 import org.forester.phylogeny.PhylogenyNode;
26 import org.forester.phylogeny.data.Accession;
27 import org.forester.phylogeny.data.Annotation;
28 import org.forester.phylogeny.data.BranchColor;
29 import org.forester.phylogeny.data.NodeDataField;
30 import org.forester.phylogeny.data.Sequence;
31 import org.forester.phylogeny.data.Taxonomy;
32 import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
33 import org.forester.phylogeny.iterators.PreorderTreeIterator;
34 import org.forester.util.ForesterConstants;
35 import org.forester.util.ForesterUtil;
36 import org.forester.util.SequenceAccessionTools;
37 import org.forester.util.StringInt;
38 import org.forester.ws.seqdb.UniProtTaxonomy;
40 public class TreePanelUtil {
42 public final static String createUriForSeqWeb( final PhylogenyNode node,
43 final Configuration conf,
44 final TreePanel tp ) {
45 String uri_str = null;
46 final String upkb = SequenceAccessionTools.obtainUniProtAccessorFromDataFields( node );
47 if ( !ForesterUtil.isEmpty( upkb ) ) {
49 uri_str = ForesterUtil.UNIPROT_KB + URLEncoder.encode( upkb, ForesterConstants.UTF_8 );
51 catch ( final UnsupportedEncodingException e ) {
52 AptxUtil.showErrorMessage( tp, e.toString() );
56 if ( ForesterUtil.isEmpty( uri_str ) ) {
57 final String v = SequenceAccessionTools.obtainGenbankAccessorFromDataFields( node );
58 if ( !ForesterUtil.isEmpty( v ) ) {
60 if ( SequenceAccessionTools.isProteinDbQuery( v ) ) {
61 uri_str = ForesterUtil.NCBI_PROTEIN + URLEncoder.encode( v, ForesterConstants.UTF_8 );
64 uri_str = ForesterUtil.NCBI_NUCCORE + URLEncoder.encode( v, ForesterConstants.UTF_8 );
67 catch ( final UnsupportedEncodingException e ) {
68 AptxUtil.showErrorMessage( tp, e.toString() );
73 if ( ForesterUtil.isEmpty( uri_str ) ) {
74 final String v = SequenceAccessionTools.obtainRefSeqAccessorFromDataFields( node );
75 if ( !ForesterUtil.isEmpty( v ) ) {
77 if ( SequenceAccessionTools.isProteinDbQuery( v ) ) {
78 uri_str = ForesterUtil.NCBI_PROTEIN + URLEncoder.encode( v, ForesterConstants.UTF_8 );
81 uri_str = ForesterUtil.NCBI_NUCCORE + URLEncoder.encode( v, ForesterConstants.UTF_8 );
84 catch ( final UnsupportedEncodingException e ) {
85 AptxUtil.showErrorMessage( tp, e.toString() );
90 if ( ForesterUtil.isEmpty( uri_str ) ) {
91 final String v = SequenceAccessionTools.obtainGiNumberFromDataFields( node );
92 if ( !ForesterUtil.isEmpty( v ) ) {
94 uri_str = ForesterUtil.NCBI_GI + URLEncoder.encode( v, ForesterConstants.UTF_8 );
96 catch ( final UnsupportedEncodingException e ) {
97 AptxUtil.showErrorMessage( tp, e.toString() );
105 public static List<String> createUrisForPdbWeb( final PhylogenyNode node,
106 final List<Accession> pdb_accs,
107 final Configuration configuration,
108 final TreePanel treePanel ) {
109 final List<String> uris = new ArrayList<String>();
110 if ( !ForesterUtil.isEmpty( pdb_accs ) ) {
111 for( final Accession pdb_acc : pdb_accs ) {
112 if ( !ForesterUtil.isEmpty( pdb_acc.getValue() ) ) {
113 uris.add( ForesterUtil.PDB + pdb_acc.getValue() );
121 * Returns the set of distinct taxonomies of
122 * all external nodes of node.
123 * If at least one the external nodes has no taxonomy,
127 public static Set<Taxonomy> obtainDistinctTaxonomies( final PhylogenyNode node ) {
128 final List<PhylogenyNode> descs = node.getAllExternalDescendants();
129 final Set<Taxonomy> tax_set = new HashSet<Taxonomy>();
130 for( final PhylogenyNode n : descs ) {
131 if ( !n.getNodeData().isHasTaxonomy() || n.getNodeData().getTaxonomy().isEmpty() ) {
134 tax_set.add( n.getNodeData().getTaxonomy() );
139 public final static void showExtDescNodeDataUserSelectedHelper( final ControlPanel cp,
140 final PhylogenyNode node,
141 final List<String> data ) {
142 final StringBuilder sb = new StringBuilder();
143 if ( cp.isShowNodeNames() && !ForesterUtil.isEmpty( node.getName() ) ) {
144 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getName(), sb );
146 if ( cp.isShowSeqNames() && node.getNodeData().isHasSequence()
147 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) {
148 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getName(), sb );
150 if ( cp.isShowSeqSymbols() && node.getNodeData().isHasSequence()
151 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) {
152 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getSymbol(),
155 if ( cp.isShowGeneNames() && node.getNodeData().isHasSequence()
156 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getGeneName() ) ) {
157 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getGeneName(),
160 if ( cp.isShowSequenceAcc() && node.getNodeData().isHasSequence()
161 && ( node.getNodeData().getSequence().getAccession() != null )
162 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().toString() ) ) {
163 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getAccession()
166 if ( cp.isShowTaxonomyCode() && node.getNodeData().isHasTaxonomy()
167 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
169 .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getTaxonomyCode(),
172 if ( cp.isShowTaxonomyScientificNames() && node.getNodeData().isHasTaxonomy()
173 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) {
175 .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getScientificName(),
178 if ( cp.isShowTaxonomyCommonNames() && node.getNodeData().isHasTaxonomy()
179 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) {
180 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getCommonName(),
183 // if ( ( cp.isShowSeqNames() || cp.isShowSeqSymbols() || cp.isShowSequenceAcc() )
184 // && node.getNodeData().isHasSequence()
185 // && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) {
186 // TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence()
187 // .getMolecularSequence(), sb );
189 final String s = sb.toString().trim();
190 if ( !ForesterUtil.isEmpty( s ) ) {
195 public final static void showExtDescNodeDataUserSelectedHelperHelper( final String s, final StringBuilder sb ) {
196 if ( sb.length() > 0 ) {
202 final public static void showInformationMessage( final Component parent, final String title, final String msg ) {
203 JOptionPane.showMessageDialog( parent, msg, title, JOptionPane.INFORMATION_MESSAGE );
206 final static void collapseSpeciesSpecificSubtrees( final Phylogeny phy ) {
207 boolean inferred = false;
208 for( final PhylogenyNodeIterator it = phy.iteratorPreorder(); it.hasNext(); ) {
209 final PhylogenyNode n = it.next();
210 if ( !n.isExternal() && !n.isCollapse() && ( n.getNumberOfDescendants() > 1 ) ) {
211 final Set<Taxonomy> taxs = TreePanelUtil.obtainDistinctTaxonomies( n );
212 if ( ( taxs != null ) && ( taxs.size() == 1 ) ) {
213 TreePanelUtil.collapseSubtree( n, true );
214 if ( !n.getNodeData().isHasTaxonomy() ) {
215 n.getNodeData().setTaxonomy( ( Taxonomy ) n.getAllExternalDescendants().get( 0 ).getNodeData()
216 .getTaxonomy().copy() );
221 n.setCollapse( false );
226 phy.setRerootable( false );
230 final static void collapseSubtree( final PhylogenyNode node, final boolean collapse ) {
231 node.setCollapse( collapse );
232 if ( node.isExternal() ) {
235 final PhylogenyNodeIterator it = new PreorderTreeIterator( node );
236 while ( it.hasNext() ) {
237 it.next().setCollapse( collapse );
241 final static void uncollapseSubtree( final PhylogenyNode node ) {
242 node.setCollapse( false );
243 if ( node.isExternal() ) {
246 final PhylogenyNodeIterator it = new PreorderTreeIterator( node );
247 while ( it.hasNext() ) {
248 it.next().setCollapse( false );
252 static void colorizeSubtree( final PhylogenyNode node, final BranchColor c ) {
253 node.getBranchData().setBranchColor( c );
254 final List<PhylogenyNode> descs = PhylogenyMethods.getAllDescendants( node );
255 for( final PhylogenyNode desc : descs ) {
256 desc.getBranchData().setBranchColor( c );
260 final static void colorPhylogenyAccordingToConfidenceValues( final Phylogeny tree, final TreePanel tree_panel ) {
261 double max_conf = 0.0;
262 for( final PhylogenyNodeIterator it = tree.iteratorPreorder(); it.hasNext(); ) {
263 final PhylogenyNode n = it.next();
264 n.getBranchData().setBranchColor( null );
265 if ( n.getBranchData().isHasConfidences() ) {
266 final double conf = PhylogenyMethods.getConfidenceValue( n );
267 if ( conf > max_conf ) {
272 if ( max_conf > 0.0 ) {
273 final Color bg = tree_panel.getTreeColorSet().getBackgroundColor();
274 final Color br = tree_panel.getTreeColorSet().getBranchColor();
275 for( final PhylogenyNodeIterator it = tree.iteratorPreorder(); it.hasNext(); ) {
276 final PhylogenyNode n = it.next();
277 if ( n.getBranchData().isHasConfidences() ) {
278 final double conf = PhylogenyMethods.getConfidenceValue( n );
279 final BranchColor c = new BranchColor( ForesterUtil.calcColor( conf, 0.0, max_conf, bg, br ) );
280 TreePanelUtil.colorizeSubtree( n, c );
286 final static void colorPhylogenyAccordingToExternalTaxonomy( final Phylogeny tree, final TreePanel tree_panel ) {
287 for( final PhylogenyNodeIterator it = tree.iteratorPreorder(); it.hasNext(); ) {
288 it.next().getBranchData().setBranchColor( null );
290 for( final PhylogenyNodeIterator it = tree.iteratorPreorder(); it.hasNext(); ) {
291 final PhylogenyNode n = it.next();
292 if ( !n.getBranchData().isHasBranchColor() ) {
293 final Taxonomy tax = PhylogenyMethods.getExternalDescendantsTaxonomy( n );
296 .setBranchColor( new BranchColor( tree_panel.calculateTaxonomyBasedColor( tax ) ) );
297 final List<PhylogenyNode> descs = PhylogenyMethods.getAllDescendants( n );
298 for( final PhylogenyNode desc : descs ) {
300 .setBranchColor( new BranchColor( tree_panel.calculateTaxonomyBasedColor( tax ) ) );
307 final static int collapseByTaxonomicRank( final Phylogeny tree, final String rank, final TreePanel tree_panel ) {
308 final Set<String> true_lineage_set = new HashSet<String>();
309 for( final PhylogenyNodeIterator iter = tree.iteratorPreorder(); iter.hasNext(); ) {
310 iter.next().setCollapse( false );
313 for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) {
314 final PhylogenyNode n = it.next();
315 if ( !n.isExternal() && n.getNodeData().isHasTaxonomy() && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getRank() )
316 && n.getNodeData().getTaxonomy().getRank().equalsIgnoreCase( rank ) /*&& !n.isRoot()*/ ) {
317 TreePanelUtil.collapseSubtree( n, true );
319 if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
320 true_lineage_set.add( n.getNodeData().getTaxonomy().getScientificName() );
321 System.out.println( "1 true_lineage_set added " + n.getNodeData().getTaxonomy().getScientificName() );
325 for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) {
326 final PhylogenyNode node = it.next();
327 if ( ( !node.isExternal() && !node.isCollapse() ) && node.getNodeData().isHasTaxonomy()
328 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getLineage() ) /* && !node.isRoot()*/ ) {
329 boolean success = false;
330 if ( !true_lineage_set.isEmpty() ) {
331 for( final String lin : node.getNodeData().getTaxonomy().getLineage() ) {
332 if ( true_lineage_set.contains( lin ) ) {
334 // .colorizeSubtree( node, new BranchColor( true_lineage_to_color_map.get( lin ) ) );
335 TreePanelUtil.collapseSubtree( node, true );
343 final Map<String, String> lineage_to_rank_map = MainPanel.getLineageToRankMap();
344 for( final String lin : node.getNodeData().getTaxonomy().getLineage() ) {
345 final Taxonomy temp_tax = new Taxonomy();
346 temp_tax.setScientificName( lin );
347 if ( lineage_to_rank_map.containsKey( lin )
348 && !ForesterUtil.isEmpty( lineage_to_rank_map.get( lin ) )
349 && lineage_to_rank_map.get( lin ).equalsIgnoreCase( rank ) ) {
350 //final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( temp_tax ) );
351 //TreePanelUtil.colorizeSubtree( node, c );
352 TreePanelUtil.collapseSubtree( node, true );
354 true_lineage_set.add( lin );
355 System.out.println( "2 true_lineage_set added " + lin );
359 UniProtTaxonomy up = null;
361 up = TaxonomyDataManager.obtainUniProtTaxonomy( temp_tax, null, null );
363 catch ( final Exception e ) {
366 if ( ( up != null ) && !ForesterUtil.isEmpty( up.getRank() ) ) {
367 lineage_to_rank_map.put( lin, up.getRank() );
368 System.out.println( lin + "->" + up.getRank() );
369 if ( up.getRank().equalsIgnoreCase( rank ) ) {
370 // final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( temp_tax ) );
371 // TreePanelUtil.colorizeSubtree( node, c );
372 TreePanelUtil.collapseSubtree( node, true );
374 true_lineage_set.add( lin );
375 System.out.println( "3 true_lineage_set added " + lin );
387 final static int colorPhylogenyAccordingToRanks( final Phylogeny tree,
389 final TreePanel tree_panel ) {
390 final Map<String, Color> true_lineage_to_color_map = new HashMap<String, Color>();
391 int colorizations = 0;
392 for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) {
393 final PhylogenyNode n = it.next();
394 if ( n.getNodeData().isHasTaxonomy()
395 && ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() )
396 || !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() )
397 || !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) {
398 if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getRank() )
399 && n.getNodeData().getTaxonomy().getRank().equalsIgnoreCase( rank ) ) {
400 final BranchColor c = new BranchColor( tree_panel
401 .calculateTaxonomyBasedColor( n.getNodeData().getTaxonomy() ) );
402 TreePanelUtil.colorizeSubtree( n, c );
404 if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
405 true_lineage_to_color_map.put( n.getNodeData().getTaxonomy().getScientificName(),
411 for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) {
412 final PhylogenyNode node = it.next();
413 if ( ( node.getBranchData().getBranchColor() == null ) && node.getNodeData().isHasTaxonomy()
414 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getLineage() ) ) {
415 boolean success = false;
416 if ( !true_lineage_to_color_map.isEmpty() ) {
417 for( final String lin : node.getNodeData().getTaxonomy().getLineage() ) {
418 if ( true_lineage_to_color_map.containsKey( lin ) ) {
419 TreePanelUtil.colorizeSubtree( node,
420 new BranchColor( true_lineage_to_color_map.get( lin ) ) );
428 final Map<String, String> lineage_to_rank_map = MainPanel.getLineageToRankMap();
429 for( final String lin : node.getNodeData().getTaxonomy().getLineage() ) {
430 final Taxonomy temp_tax = new Taxonomy();
431 temp_tax.setScientificName( lin );
432 if ( lineage_to_rank_map.containsKey( lin )
433 && !ForesterUtil.isEmpty( lineage_to_rank_map.get( lin ) )
434 && lineage_to_rank_map.get( lin ).equalsIgnoreCase( rank ) ) {
435 final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( temp_tax ) );
436 TreePanelUtil.colorizeSubtree( node, c );
438 true_lineage_to_color_map.put( lin, c.getValue() );
442 UniProtTaxonomy up = null;
444 up = TaxonomyDataManager.obtainUniProtTaxonomy( temp_tax, null, null );
446 catch ( final Exception e ) {
449 if ( ( up != null ) && !ForesterUtil.isEmpty( up.getRank() ) ) {
450 lineage_to_rank_map.put( lin, up.getRank() );
451 System.out.println( lin + "->" + up.getRank() );
452 if ( up.getRank().equalsIgnoreCase( rank ) ) {
453 final BranchColor c = new BranchColor( tree_panel
454 .calculateTaxonomyBasedColor( temp_tax ) );
455 TreePanelUtil.colorizeSubtree( node, c );
457 true_lineage_to_color_map.put( lin, c.getValue() );
466 return colorizations;
469 final static String createAnnotationString( final SortedSet<Annotation> annotations,
470 final boolean show_ref_sources ) {
471 final SortedMap<String, List<Annotation>> m = new TreeMap<String, List<Annotation>>();
472 for( final Annotation an : annotations ) {
473 final String ref_source = ForesterUtil.isEmpty( an.getRefSource() ) ? "?" : an.getRefSource();
474 if ( !m.containsKey( ref_source ) ) {
475 m.put( ref_source, new ArrayList<Annotation>() );
477 m.get( ref_source ).add( an );
479 final StringBuilder sb = new StringBuilder();
480 for( final Entry<String, List<Annotation>> e : m.entrySet() ) {
481 final String ref_source = e.getKey();
482 final List<Annotation> ans = e.getValue();
483 if ( m.size() > 1 ) {
486 if ( show_ref_sources && !ref_source.equals( "?" ) ) {
487 sb.append( ref_source );
490 for( int i = 0; i < ans.size(); ++i ) {
491 final Annotation an = ans.get( i );
492 if ( !ForesterUtil.isEmpty( an.getRefValue() ) ) {
493 sb.append( an.getRefValue() );
496 if ( !ForesterUtil.isEmpty( an.getDesc() ) ) {
497 sb.append( an.getDesc() );
499 if ( sb.charAt( sb.length() - 1 ) == ' ' ) {
500 sb.deleteCharAt( sb.length() - 1 );
502 if ( i < ( ans.size() - 1 ) ) {
506 if ( m.size() > 1 ) {
510 return sb.toString();
513 final static String getPartAfterColon( final String s ) {
514 final int i = s.indexOf( ':' );
515 if ( ( i < 1 ) || ( i == ( s.length() - 1 ) ) ) {
518 return s.substring( i + 1, s.length() );
521 final static boolean isHasAssignedEvent( final PhylogenyNode node ) {
522 if ( !node.getNodeData().isHasEvent() ) {
525 if ( ( node.getNodeData().getEvent() ).isUnassigned() ) {
531 final static boolean isSequenceEmpty( final Sequence seq ) {
532 return ( seq.getAccession() == null ) && ForesterUtil.isEmpty( seq.getName() )
533 && ForesterUtil.isEmpty( seq.getGeneName() ) && ForesterUtil.isEmpty( seq.getSymbol() );
536 final static boolean isTaxonomyEmpty( final Taxonomy tax ) {
537 return ( ( tax.getIdentifier() == null ) && ForesterUtil.isEmpty( tax.getTaxonomyCode() )
538 && ForesterUtil.isEmpty( tax.getCommonName() ) && ForesterUtil.isEmpty( tax.getScientificName() )
539 && tax.getSynonyms().isEmpty() );
542 static final int nodeDataIntoStringBuffer( final List<String> data, final Options optz, final StringBuilder sb ) {
543 final SortedMap<String, Integer> map = new TreeMap<String, Integer>();
545 if ( ( optz.getExtDescNodeDataToReturn() != NodeDataField.SEQUENCE_MOL_SEQ_FASTA )
546 && ( optz.getExtDescNodeDataToReturn() != NodeDataField.GO_TERM_IDS ) ) {
547 for( final String d : data ) {
548 if ( !ForesterUtil.isEmpty( d ) ) {
549 if ( map.containsKey( d ) ) {
550 map.put( d, map.get( d ) + 1 );
557 if ( ( optz.getExtDescNodeDataToReturn() == NodeDataField.DOMAINS_ALL )
558 || ( optz.getExtDescNodeDataToReturn() == NodeDataField.DOMAINS_COLLAPSED_PER_PROTEIN )
559 || ( optz.getExtDescNodeDataToReturn() == NodeDataField.SEQ_ANNOTATIONS ) ) {
560 final ArrayList<StringInt> sis = new ArrayList<StringInt>();
561 for( final Entry<String, Integer> e : map.entrySet() ) {
562 sis.add( new StringInt( e.getKey(), e.getValue() ) );
564 Collections.sort( sis, new StringInt.DescendingIntComparator() );
565 for( final StringInt si : sis ) {
566 sb.append( si.getString() );
568 sb.append( si.getInt() );
569 sb.append( ForesterUtil.LINE_SEPARATOR );
573 for( final Entry<String, Integer> e : map.entrySet() ) {
574 final String v = e.getKey();
575 final Object c = e.getValue();
579 sb.append( ForesterUtil.LINE_SEPARATOR );
585 for( final String d : data ) {
586 if ( !ForesterUtil.isEmpty( d ) ) {
588 sb.append( ForesterUtil.LINE_SEPARATOR );
596 final static String pdbAccToString( final List<Accession> accs, final int i ) {
597 if ( ForesterUtil.isEmpty( accs.get( i ).getComment() ) ) {
598 return accs.get( i ).getValue();
600 return accs.get( i ).getValue() + " (" + accs.get( i ).getComment().toLowerCase() + ")";
603 final static Phylogeny subTree( final PhylogenyNode new_root, final Phylogeny source_phy ) {
604 final Phylogeny new_phy = new Phylogeny();
605 new_phy.setRooted( true );
606 new_phy.setName( source_phy.getName() );
607 new_phy.setDescription( source_phy.getDescription() );
608 new_phy.setType( source_phy.getType() );
609 new_phy.setDistanceUnit( source_phy.getDistanceUnit() );
610 new_phy.setConfidence( source_phy.getConfidence() );
611 new_phy.setIdentifier( source_phy.getIdentifier() );
612 new_phy.setRoot( new_root.copyNodeDataShallow() );
614 for( final PhylogenyNode n : new_root.getDescendants() ) {
615 new_phy.getRoot().setChildNode( i++, n );