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.HashMap;
10 import java.util.HashSet;
11 import java.util.List;
13 import java.util.Map.Entry;
15 import java.util.SortedMap;
16 import java.util.SortedSet;
17 import java.util.TreeMap;
19 import javax.swing.JOptionPane;
21 import org.forester.analysis.TaxonomyDataManager;
22 import org.forester.phylogeny.Phylogeny;
23 import org.forester.phylogeny.PhylogenyMethods;
24 import org.forester.phylogeny.PhylogenyNode;
25 import org.forester.phylogeny.data.Annotation;
26 import org.forester.phylogeny.data.BranchColor;
27 import org.forester.phylogeny.data.NodeData.NODE_DATA;
28 import org.forester.phylogeny.data.Sequence;
29 import org.forester.phylogeny.data.Taxonomy;
30 import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
31 import org.forester.phylogeny.iterators.PreorderTreeIterator;
32 import org.forester.util.ForesterConstants;
33 import org.forester.util.ForesterUtil;
34 import org.forester.util.SequenceIdParser;
35 import org.forester.ws.seqdb.UniProtTaxonomy;
37 public class TreePanelUtil {
39 static int makeSB( final List<String> data, final Options optz, final StringBuilder sb ) {
40 final SortedMap<String, Integer> map = new TreeMap<String, Integer>();
41 if ( ( optz.getExtDescNodeDataToReturn() != NODE_DATA.SEQUENCE_MOL_SEQ )
42 && ( optz.getExtDescNodeDataToReturn() != NODE_DATA.SEQUENCE_MOL_SEQ_FASTA ) ) {
43 for( final String d : data ) {
44 if ( !ForesterUtil.isEmpty( d ) ) {
45 if ( map.containsKey( d ) ) {
46 map.put( d, map.get( d ) + 1 );
55 if ( ( optz.getExtDescNodeDataToReturn() != NODE_DATA.SEQUENCE_MOL_SEQ )
56 && ( optz.getExtDescNodeDataToReturn() != NODE_DATA.SEQUENCE_MOL_SEQ_FASTA ) ) {
57 for( final Entry<String, Integer> e : map.entrySet() ) {
58 final String v = e.getKey();
59 final Object c = e.getValue();
63 sb.append( ForesterUtil.LINE_SEPARATOR );
68 for( final String d : data ) {
69 if ( !ForesterUtil.isEmpty( d ) ) {
71 sb.append( ForesterUtil.LINE_SEPARATOR );
79 public final static String createUriForSeqWeb( final PhylogenyNode node,
80 final Configuration conf,
81 final TreePanel tp ) {
82 String uri_str = null;
83 final String upkb = ForesterUtil.extractUniProtKbProteinSeqIdentifier( node );
84 if ( !ForesterUtil.isEmpty( upkb ) ) {
86 uri_str = ForesterUtil.UNIPROT_KB + URLEncoder.encode( upkb, ForesterConstants.UTF8 );
88 catch ( final UnsupportedEncodingException e ) {
89 AptxUtil.showErrorMessage( tp, e.toString() );
93 if ( ForesterUtil.isEmpty( uri_str ) ) {
94 final String v = ForesterUtil.extractGenbankAccessor( node );
95 if ( !ForesterUtil.isEmpty( v ) ) {
97 if ( SequenceIdParser.isProtein( v ) ) {
98 uri_str = ForesterUtil.NCBI_PROTEIN + URLEncoder.encode( v, ForesterConstants.UTF8 );
101 uri_str = ForesterUtil.NCBI_NUCCORE + URLEncoder.encode( v, ForesterConstants.UTF8 );
104 catch ( final UnsupportedEncodingException e ) {
105 AptxUtil.showErrorMessage( tp, e.toString() );
110 if ( ForesterUtil.isEmpty( uri_str ) ) {
111 final String v = ForesterUtil.extractRefSeqAccessorAccessor( node );
112 if ( !ForesterUtil.isEmpty( v ) ) {
114 if ( SequenceIdParser.isProtein( v ) ) {
115 uri_str = ForesterUtil.NCBI_PROTEIN + URLEncoder.encode( v, ForesterConstants.UTF8 );
118 uri_str = ForesterUtil.NCBI_NUCCORE + URLEncoder.encode( v, ForesterConstants.UTF8 );
121 catch ( final UnsupportedEncodingException e ) {
122 AptxUtil.showErrorMessage( tp, e.toString() );
127 if ( ForesterUtil.isEmpty( uri_str ) ) {
128 final String v = ForesterUtil.extractGInumber( node );
129 if ( !ForesterUtil.isEmpty( v ) ) {
131 uri_str = ForesterUtil.NCBI_GI + URLEncoder.encode( v, ForesterConstants.UTF8 );
133 catch ( final UnsupportedEncodingException e ) {
134 AptxUtil.showErrorMessage( tp, e.toString() );
143 * Returns the set of distinct taxonomies of
144 * all external nodes of node.
145 * If at least one the external nodes has no taxonomy,
149 public static Set<Taxonomy> obtainDistinctTaxonomies( final PhylogenyNode node ) {
150 final List<PhylogenyNode> descs = node.getAllExternalDescendants();
151 final Set<Taxonomy> tax_set = new HashSet<Taxonomy>();
152 for( final PhylogenyNode n : descs ) {
153 if ( !n.getNodeData().isHasTaxonomy() || n.getNodeData().getTaxonomy().isEmpty() ) {
156 tax_set.add( n.getNodeData().getTaxonomy() );
161 public final static void showExtDescNodeDataUserSelectedHelper( final ControlPanel cp,
162 final PhylogenyNode node,
163 final List<String> data ) {
164 final StringBuilder sb = new StringBuilder();
165 if ( cp.isShowNodeNames() && !ForesterUtil.isEmpty( node.getName() ) ) {
166 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getName(), sb );
168 if ( cp.isShowSeqNames() && node.getNodeData().isHasSequence()
169 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) {
170 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getName(), sb );
172 if ( cp.isShowSeqSymbols() && node.getNodeData().isHasSequence()
173 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) {
175 .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getSymbol(), sb );
177 if ( cp.isShowGeneNames() && node.getNodeData().isHasSequence()
178 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getGeneName() ) ) {
179 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getGeneName(),
182 if ( cp.isShowSequenceAcc() && node.getNodeData().isHasSequence()
183 && ( node.getNodeData().getSequence().getAccession() != null )
184 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().toString() ) ) {
185 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence().getAccession()
188 if ( cp.isShowTaxonomyCode() && node.getNodeData().isHasTaxonomy()
189 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
190 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy()
191 .getTaxonomyCode(), sb );
193 if ( cp.isShowTaxonomyScientificNames() && node.getNodeData().isHasTaxonomy()
194 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) {
195 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy()
196 .getScientificName(), sb );
198 if ( cp.isShowTaxonomyCommonNames() && node.getNodeData().isHasTaxonomy()
199 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) {
201 .showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getTaxonomy().getCommonName(), sb );
203 if ( ( cp.isShowSeqNames() || cp.isShowSeqSymbols() || cp.isShowSequenceAcc() )
204 && node.getNodeData().isHasSequence()
205 && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) {
206 TreePanelUtil.showExtDescNodeDataUserSelectedHelperHelper( node.getNodeData().getSequence()
207 .getMolecularSequence(), sb );
209 final String s = sb.toString().trim();
210 if ( !ForesterUtil.isEmpty( s ) ) {
215 public final static void showExtDescNodeDataUserSelectedHelperHelper( final String s, final StringBuilder sb ) {
216 if ( sb.length() > 0 ) {
222 final public static void showInformationMessage( final Component parent, final String title, final String msg ) {
223 JOptionPane.showMessageDialog( parent, msg, title, JOptionPane.INFORMATION_MESSAGE );
226 final static Color calculateColorFromString( final String str, final boolean is_taxonomy ) {
227 final String my_str = str.toUpperCase();
228 char first = my_str.charAt( 0 );
231 if ( my_str.length() > 1 ) {
233 second = my_str.charAt( 1 );
236 second = my_str.charAt( my_str.length() - 1 );
239 if ( my_str.length() > 2 ) {
240 if ( my_str.indexOf( " " ) > 0 ) {
241 third = my_str.charAt( my_str.indexOf( " " ) + 1 );
244 third = my_str.charAt( 2 );
248 else if ( my_str.length() > 2 ) {
249 third = my_str.charAt( ( my_str.length() - 1 ) / 2 );
252 first = TreePanelUtil.normalizeCharForRGB( first );
253 second = TreePanelUtil.normalizeCharForRGB( second );
254 third = TreePanelUtil.normalizeCharForRGB( third );
255 if ( ( first > 235 ) && ( second > 235 ) && ( third > 235 ) ) {
258 else if ( ( first < 60 ) && ( second < 60 ) && ( third < 60 ) ) {
261 return new Color( first, second, third );
264 final static void collapseSpeciesSpecificSubtrees( final Phylogeny phy ) {
265 boolean inferred = false;
266 for( final PhylogenyNodeIterator it = phy.iteratorPreorder(); it.hasNext(); ) {
267 final PhylogenyNode n = it.next();
268 if ( !n.isExternal() && !n.isCollapse() && ( n.getNumberOfDescendants() > 1 ) ) {
269 final Set<Taxonomy> taxs = TreePanelUtil.obtainDistinctTaxonomies( n );
270 if ( ( taxs != null ) && ( taxs.size() == 1 ) ) {
271 TreePanelUtil.collapseSubtree( n, true );
272 if ( !n.getNodeData().isHasTaxonomy() ) {
273 n.getNodeData().setTaxonomy( ( Taxonomy ) n.getAllExternalDescendants().get( 0 ).getNodeData()
274 .getTaxonomy().copy() );
279 n.setCollapse( false );
284 phy.setRerootable( false );
288 final static void collapseSubtree( final PhylogenyNode node, final boolean collapse ) {
289 node.setCollapse( collapse );
290 if ( node.isExternal() ) {
293 final PhylogenyNodeIterator it = new PreorderTreeIterator( node );
294 while ( it.hasNext() ) {
295 it.next().setCollapse( collapse );
299 static void colorizeSubtree( final PhylogenyNode node, final BranchColor c ) {
300 node.getBranchData().setBranchColor( c );
301 final List<PhylogenyNode> descs = PhylogenyMethods.getAllDescendants( node );
302 for( final PhylogenyNode desc : descs ) {
303 desc.getBranchData().setBranchColor( c );
307 final static void colorPhylogenyAccordingToConfidenceValues( final Phylogeny tree, final TreePanel tree_panel ) {
308 double max_conf = 0.0;
309 for( final PhylogenyNodeIterator it = tree.iteratorPreorder(); it.hasNext(); ) {
310 final PhylogenyNode n = it.next();
311 n.getBranchData().setBranchColor( null );
312 if ( n.getBranchData().isHasConfidences() ) {
313 final double conf = PhylogenyMethods.getConfidenceValue( n );
314 if ( conf > max_conf ) {
319 if ( max_conf > 0.0 ) {
320 final Color bg = tree_panel.getTreeColorSet().getBackgroundColor();
321 final Color br = tree_panel.getTreeColorSet().getBranchColor();
322 for( final PhylogenyNodeIterator it = tree.iteratorPreorder(); it.hasNext(); ) {
323 final PhylogenyNode n = it.next();
324 if ( n.getBranchData().isHasConfidences() ) {
325 final double conf = PhylogenyMethods.getConfidenceValue( n );
326 final BranchColor c = new BranchColor( ForesterUtil.calcColor( conf, 0.0, max_conf, bg, br ) );
327 TreePanelUtil.colorizeSubtree( n, c );
333 final static void colorPhylogenyAccordingToExternalTaxonomy( final Phylogeny tree, final TreePanel tree_panel ) {
334 for( final PhylogenyNodeIterator it = tree.iteratorPreorder(); it.hasNext(); ) {
335 it.next().getBranchData().setBranchColor( null );
337 for( final PhylogenyNodeIterator it = tree.iteratorPreorder(); it.hasNext(); ) {
338 final PhylogenyNode n = it.next();
339 if ( !n.getBranchData().isHasBranchColor() ) {
340 final Taxonomy tax = PhylogenyMethods.getExternalDescendantsTaxonomy( n );
342 n.getBranchData().setBranchColor( new BranchColor( tree_panel.calculateTaxonomyBasedColor( tax ) ) );
343 final List<PhylogenyNode> descs = PhylogenyMethods.getAllDescendants( n );
344 for( final PhylogenyNode desc : descs ) {
346 .setBranchColor( new BranchColor( tree_panel.calculateTaxonomyBasedColor( tax ) ) );
353 final static int colorPhylogenyAccordingToRanks( final Phylogeny tree, final String rank, final TreePanel tree_panel ) {
354 final Map<String, Color> true_lineage_to_color_map = new HashMap<String, Color>();
355 int colorizations = 0;
356 for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) {
357 final PhylogenyNode n = it.next();
358 if ( n.getNodeData().isHasTaxonomy()
359 && ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() )
360 || !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) || !ForesterUtil
361 .isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) {
362 if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getRank() )
363 && n.getNodeData().getTaxonomy().getRank().equalsIgnoreCase( rank ) ) {
364 final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( n.getNodeData()
366 TreePanelUtil.colorizeSubtree( n, c );
368 if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
369 true_lineage_to_color_map.put( n.getNodeData().getTaxonomy().getScientificName(), c.getValue() );
374 for( final PhylogenyNodeIterator it = tree.iteratorPostorder(); it.hasNext(); ) {
375 final PhylogenyNode node = it.next();
376 if ( ( node.getBranchData().getBranchColor() == null ) && node.getNodeData().isHasTaxonomy()
377 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getLineage() ) ) {
378 boolean success = false;
379 if ( !true_lineage_to_color_map.isEmpty() ) {
380 for( final String lin : node.getNodeData().getTaxonomy().getLineage() ) {
381 if ( true_lineage_to_color_map.containsKey( lin ) ) {
383 .colorizeSubtree( node, new BranchColor( true_lineage_to_color_map.get( lin ) ) );
391 final Map<String, String> lineage_to_rank_map = MainPanel.getLineageToRankMap();
392 for( final String lin : node.getNodeData().getTaxonomy().getLineage() ) {
393 final Taxonomy temp_tax = new Taxonomy();
394 temp_tax.setScientificName( lin );
395 if ( lineage_to_rank_map.containsKey( lin )
396 && !ForesterUtil.isEmpty( lineage_to_rank_map.get( lin ) )
397 && lineage_to_rank_map.get( lin ).equalsIgnoreCase( rank ) ) {
398 final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( temp_tax ) );
399 TreePanelUtil.colorizeSubtree( node, c );
401 true_lineage_to_color_map.put( lin, c.getValue() );
405 UniProtTaxonomy up = null;
407 up = TaxonomyDataManager.obtainUniProtTaxonomy( temp_tax, null, null );
409 catch ( final Exception e ) {
412 if ( ( up != null ) && !ForesterUtil.isEmpty( up.getRank() ) ) {
413 lineage_to_rank_map.put( lin, up.getRank() );
414 if ( up.getRank().equalsIgnoreCase( rank ) ) {
415 final BranchColor c = new BranchColor( tree_panel.calculateTaxonomyBasedColor( temp_tax ) );
416 TreePanelUtil.colorizeSubtree( node, c );
418 true_lineage_to_color_map.put( lin, c.getValue() );
427 return colorizations;
430 final static String createAnnotationString( final SortedSet<Annotation> annotations, final boolean show_ref_sources ) {
431 final SortedMap<String, List<Annotation>> m = new TreeMap<String, List<Annotation>>();
432 for( final Annotation an : annotations ) {
433 final String ref_source = ForesterUtil.isEmpty( an.getRefSource() ) ? "?" : an.getRefSource();
434 if ( !m.containsKey( ref_source ) ) {
435 m.put( ref_source, new ArrayList<Annotation>() );
437 m.get( ref_source ).add( an );
439 final StringBuilder sb = new StringBuilder();
440 for( final Entry<String, List<Annotation>> e : m.entrySet() ) {
441 final String ref_source = e.getKey();
442 final List<Annotation> ans = e.getValue();
443 if ( m.size() > 1 ) {
446 if ( show_ref_sources && !ref_source.equals( "?" ) ) {
447 sb.append( ref_source );
450 for( int i = 0; i < ans.size(); ++i ) {
451 final Annotation an = ans.get( i );
452 if ( !ForesterUtil.isEmpty( an.getRefValue() ) ) {
453 sb.append( an.getRefValue() );
456 if ( !ForesterUtil.isEmpty( an.getDesc() ) ) {
457 sb.append( an.getDesc() );
459 if ( sb.charAt( sb.length() - 1 ) == ' ' ) {
460 sb.deleteCharAt( sb.length() - 1 );
462 if ( i < ans.size() - 1 ) {
466 if ( m.size() > 1 ) {
470 return sb.toString();
473 final static String getPartAfterColon( final String s ) {
474 final int i = s.indexOf( ':' );
475 if ( ( i < 1 ) || ( i == ( s.length() - 1 ) ) ) {
478 return s.substring( i + 1, s.length() );
481 final static boolean isHasAssignedEvent( final PhylogenyNode node ) {
482 if ( !node.getNodeData().isHasEvent() ) {
485 if ( ( node.getNodeData().getEvent() ).isUnassigned() ) {
491 final static boolean isSequenceEmpty( final Sequence seq ) {
492 return ( seq.getAccession() == null ) && ForesterUtil.isEmpty( seq.getName() )
493 && ForesterUtil.isEmpty( seq.getGeneName() ) && ForesterUtil.isEmpty( seq.getSymbol() );
496 final static boolean isTaxonomyEmpty( final Taxonomy tax ) {
497 return ( ( tax.getIdentifier() == null ) && ForesterUtil.isEmpty( tax.getTaxonomyCode() )
498 && ForesterUtil.isEmpty( tax.getCommonName() ) && ForesterUtil.isEmpty( tax.getScientificName() ) && tax
499 .getSynonyms().isEmpty() );
502 final static char normalizeCharForRGB( char c ) {
505 c = c > 255 ? 255 : c;
510 final static Phylogeny subTree( final PhylogenyNode new_root, final Phylogeny source_phy ) {
511 final Phylogeny new_phy = new Phylogeny();
512 new_phy.setRooted( true );
513 new_phy.setName( source_phy.getName() );
514 new_phy.setDescription( source_phy.getDescription() );
515 new_phy.setType( source_phy.getType() );
516 new_phy.setDistanceUnit( source_phy.getDistanceUnit() );
517 new_phy.setConfidence( source_phy.getConfidence() );
518 new_phy.setIdentifier( source_phy.getIdentifier() );
519 new_phy.setRoot( new_root.copyNodeDataShallow() );
521 for( final PhylogenyNode n : new_root.getDescendants() ) {
522 new_phy.getRoot().setChildNode( i++, n );