some additions being added
[jalview.git] / forester / java / src / org / forester / archaeopteryx / TreePanelUtil.java
1
2 package org.forester.archaeopteryx;
3
4 import java.awt.Color;
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;
13 import java.util.Map;
14 import java.util.Map.Entry;
15 import java.util.Set;
16 import java.util.SortedMap;
17 import java.util.SortedSet;
18 import java.util.TreeMap;
19
20 import javax.swing.JOptionPane;
21
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;
39
40 public class TreePanelUtil {
41
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 ) ) {
48             try {
49                 uri_str = ForesterUtil.UNIPROT_KB + URLEncoder.encode( upkb, ForesterConstants.UTF_8 );
50             }
51             catch ( final UnsupportedEncodingException e ) {
52                 AptxUtil.showErrorMessage( tp, e.toString() );
53                 e.printStackTrace();
54             }
55         }
56         if ( ForesterUtil.isEmpty( uri_str ) ) {
57             final String v = SequenceAccessionTools.obtainGenbankAccessorFromDataFields( node );
58             if ( !ForesterUtil.isEmpty( v ) ) {
59                 try {
60                     if ( SequenceAccessionTools.isProteinDbQuery( v ) ) {
61                         uri_str = ForesterUtil.NCBI_PROTEIN + URLEncoder.encode( v, ForesterConstants.UTF_8 );
62                     }
63                     else {
64                         uri_str = ForesterUtil.NCBI_NUCCORE + URLEncoder.encode( v, ForesterConstants.UTF_8 );
65                     }
66                 }
67                 catch ( final UnsupportedEncodingException e ) {
68                     AptxUtil.showErrorMessage( tp, e.toString() );
69                     e.printStackTrace();
70                 }
71             }
72         }
73         if ( ForesterUtil.isEmpty( uri_str ) ) {
74             final String v = SequenceAccessionTools.obtainRefSeqAccessorFromDataFields( node );
75             if ( !ForesterUtil.isEmpty( v ) ) {
76                 try {
77                     if ( SequenceAccessionTools.isProteinDbQuery( v ) ) {
78                         uri_str = ForesterUtil.NCBI_PROTEIN + URLEncoder.encode( v, ForesterConstants.UTF_8 );
79                     }
80                     else {
81                         uri_str = ForesterUtil.NCBI_NUCCORE + URLEncoder.encode( v, ForesterConstants.UTF_8 );
82                     }
83                 }
84                 catch ( final UnsupportedEncodingException e ) {
85                     AptxUtil.showErrorMessage( tp, e.toString() );
86                     e.printStackTrace();
87                 }
88             }
89         }
90         if ( ForesterUtil.isEmpty( uri_str ) ) {
91             final String v = SequenceAccessionTools.obtainGiNumberFromDataFields( node );
92             if ( !ForesterUtil.isEmpty( v ) ) {
93                 try {
94                     uri_str = ForesterUtil.NCBI_GI + URLEncoder.encode( v, ForesterConstants.UTF_8 );
95                 }
96                 catch ( final UnsupportedEncodingException e ) {
97                     AptxUtil.showErrorMessage( tp, e.toString() );
98                     e.printStackTrace();
99                 }
100             }
101         }
102         return uri_str;
103     }
104
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() );
114                 }
115             }
116         }
117         return uris;
118     }
119
120     /**
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,
124      * null is returned.
125      *
126      */
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() ) {
132                 return null;
133             }
134             tax_set.add( n.getNodeData().getTaxonomy() );
135         }
136         return tax_set;
137     }
138
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 );
145         }
146         if ( cp.isShowSeqNames() && node.getNodeData().isHasSequence()
147                 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) {
148             TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getName(), sb );
149         }
150         if ( cp.isShowSeqSymbols() && node.getNodeData().isHasSequence()
151                 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) {
152             TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getSymbol(),
153                                                                        sb );
154         }
155         if ( cp.isShowGeneNames() && node.getNodeData().isHasSequence()
156                 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getGeneName() ) ) {
157             TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getGeneName(),
158                                                                        sb );
159         }
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()
164                     .toString(), sb );
165         }
166         if ( cp.isShowTaxonomyCode() && node.getNodeData().isHasTaxonomy()
167                 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
168             TreePanelUtil
169                     .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getTaxonomyCode(),
170                                                                   sb );
171         }
172         if ( cp.isShowTaxonomyScientificNames() && node.getNodeData().isHasTaxonomy()
173                 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) {
174             TreePanelUtil
175                     .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getScientificName(),
176                                                                   sb );
177         }
178         if ( cp.isShowTaxonomyCommonNames() && node.getNodeData().isHasTaxonomy()
179                 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) {
180             TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getCommonName(),
181                                                                        sb );
182         }
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 );
188         //        }
189         final String s = sb.toString().trim();
190         if ( !ForesterUtil.isEmpty( s ) ) {
191             data.add( s );
192         }
193     }
194
195     public final static void showExtDescNodeDataUserSelectedHelperHelper( final String s, final StringBuilder sb ) {
196         if ( sb.length() > 0 ) {
197             sb.append( "\t" );
198         }
199         sb.append( s );
200     }
201
202     final public static void showInformationMessage( final Component parent, final String title, final String msg ) {
203         JOptionPane.showMessageDialog( parent, msg, title, JOptionPane.INFORMATION_MESSAGE );
204     }
205
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() );
217                     }
218                     inferred = true;
219                 }
220                 else {
221                     n.setCollapse( false );
222                 }
223             }
224         }
225         if ( inferred ) {
226             phy.setRerootable( false );
227         }
228     }
229
230     final static void collapseSubtree( final PhylogenyNode node, final boolean collapse ) {
231         node.setCollapse( collapse );
232         if ( node.isExternal() ) {
233             return;
234         }
235         final PhylogenyNodeIterator it = new PreorderTreeIterator( node );
236         while ( it.hasNext() ) {
237             it.next().setCollapse( collapse );
238         }
239     }
240
241     final static void uncollapseSubtree( final PhylogenyNode node ) {
242         node.setCollapse( false );
243         if ( node.isExternal() ) {
244             return;
245         }
246         final PhylogenyNodeIterator it = new PreorderTreeIterator( node );
247         while ( it.hasNext() ) {
248             it.next().setCollapse( false );
249         }
250     }
251
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 );
257         }
258     }
259
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 ) {
268                     max_conf = conf;
269                 }
270             }
271         }
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 );
281                 }
282             }
283         }
284     }
285
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 );
289         }
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 );
294                 if ( tax != null ) {
295                     n.getBranchData()
296                             .setBranchColor( new BranchColor( tree_panel.calculateTaxonomyBasedColor( tax ) ) );
297                     final List<PhylogenyNode> descs = PhylogenyMethods.getAllDescendants( n );
298                     for( final PhylogenyNode desc : descs ) {
299                         desc.getBranchData()
300                                 .setBranchColor( new BranchColor( tree_panel.calculateTaxonomyBasedColor( tax ) ) );
301                     }
302                 }
303             }
304         }
305     }
306
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 );
311         }
312         int collapsed = 0;
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 );
318                 ++collapsed;
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()  );
322                 }
323             }
324         }
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 ) ) {
333                             //TreePanelUtil
334                             //     .colorizeSubtree( node, new BranchColor( true_lineage_to_color_map.get( lin ) ) );
335                             TreePanelUtil.collapseSubtree( node, true );
336                             ++collapsed;
337                             success = true;
338                             break;
339                         }
340                     }
341                 }
342                 if ( !success ) {
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 );
353                             ++collapsed;
354                             true_lineage_set.add( lin );
355                             System.out.println( "2 true_lineage_set added " +  lin  );
356                             break;
357                         }
358                         else {
359                             UniProtTaxonomy up = null;
360                             try {
361                                 up = TaxonomyDataManager.obtainUniProtTaxonomy( temp_tax, null, null );
362                             }
363                             catch ( final Exception e ) {
364                                 e.printStackTrace();
365                             }
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 );
373                                     ++collapsed;
374                                     true_lineage_set.add( lin );
375                                     System.out.println( "3 true_lineage_set added " +  lin  );
376                                     break;
377                                 }
378                             }
379                         }
380                     }
381                 }
382             }
383         }
384         return collapsed;
385     }
386
387     final static int colorPhylogenyAccordingToRanks( final Phylogeny tree,
388                                                      final String rank,
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 );
403                     ++colorizations;
404                     if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
405                         true_lineage_to_color_map.put( n.getNodeData().getTaxonomy().getScientificName(),
406                                                        c.getValue() );
407                     }
408                 }
409             }
410         }
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 ) ) );
421                             ++colorizations;
422                             success = true;
423                             break;
424                         }
425                     }
426                 }
427                 if ( !success ) {
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 );
437                             ++colorizations;
438                             true_lineage_to_color_map.put( lin, c.getValue() );
439                             break;
440                         }
441                         else {
442                             UniProtTaxonomy up = null;
443                             try {
444                                 up = TaxonomyDataManager.obtainUniProtTaxonomy( temp_tax, null, null );
445                             }
446                             catch ( final Exception e ) {
447                                 e.printStackTrace();
448                             }
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 );
456                                     ++colorizations;
457                                     true_lineage_to_color_map.put( lin, c.getValue() );
458                                     break;
459                                 }
460                             }
461                         }
462                     }
463                 }
464             }
465         }
466         return colorizations;
467     }
468
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>() );
476             }
477             m.get( ref_source ).add( an );
478         }
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 ) {
484                 sb.append( "[" );
485             }
486             if ( show_ref_sources && !ref_source.equals( "?" ) ) {
487                 sb.append( ref_source );
488                 sb.append( ": " );
489             }
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() );
494                     sb.append( " " );
495                 }
496                 if ( !ForesterUtil.isEmpty( an.getDesc() ) ) {
497                     sb.append( an.getDesc() );
498                 }
499                 if ( sb.charAt( sb.length() - 1 ) == ' ' ) {
500                     sb.deleteCharAt( sb.length() - 1 );
501                 }
502                 if ( i < ( ans.size() - 1 ) ) {
503                     sb.append( ", " );
504                 }
505             }
506             if ( m.size() > 1 ) {
507                 sb.append( "] " );
508             }
509         }
510         return sb.toString();
511     }
512
513     final static String getPartAfterColon( final String s ) {
514         final int i = s.indexOf( ':' );
515         if ( ( i < 1 ) || ( i == ( s.length() - 1 ) ) ) {
516             return s;
517         }
518         return s.substring( i + 1, s.length() );
519     }
520
521     final static boolean isHasAssignedEvent( final PhylogenyNode node ) {
522         if ( !node.getNodeData().isHasEvent() ) {
523             return false;
524         }
525         if ( ( node.getNodeData().getEvent() ).isUnassigned() ) {
526             return false;
527         }
528         return true;
529     }
530
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() );
534     }
535
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() );
540     }
541
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>();
544         int size = 0;
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 );
551                     }
552                     else {
553                         map.put( d, 1 );
554                     }
555                 }
556             }
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() ) );
563                 }
564                 Collections.sort( sis, new StringInt.DescendingIntComparator() );
565                 for( final StringInt si : sis ) {
566                     sb.append( si.getString() );
567                     sb.append( "\t" );
568                     sb.append( si.getInt() );
569                     sb.append( ForesterUtil.LINE_SEPARATOR );
570                 }
571             }
572             else {
573                 for( final Entry<String, Integer> e : map.entrySet() ) {
574                     final String v = e.getKey();
575                     final Object c = e.getValue();
576                     sb.append( v );
577                     sb.append( "\t" );
578                     sb.append( c );
579                     sb.append( ForesterUtil.LINE_SEPARATOR );
580                 }
581             }
582             size = map.size();
583         }
584         else {
585             for( final String d : data ) {
586                 if ( !ForesterUtil.isEmpty( d ) ) {
587                     sb.append( d );
588                     sb.append( ForesterUtil.LINE_SEPARATOR );
589                 }
590             }
591             size = data.size();
592         }
593         return size;
594     }
595
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();
599         }
600         return accs.get( i ).getValue() + " (" + accs.get( i ).getComment().toLowerCase() + ")";
601     }
602
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() );
613         int i = 0;
614         for( final PhylogenyNode n : new_root.getDescendants() ) {
615             new_phy.getRoot().setChildNode( i++, n );
616         }
617         return new_phy;
618     }
619 }