+ CLADE_NAME,
+ SEQUENCE_NAME,
+ SEQUENCE_SYMBOL,
+ TAXONOMY_CODE,
+ TAXONOMY_COMMON_NAME,
+ TAXONOMY_ID,
+ TAXONOMY_ID_UNIPROT_1,
+ TAXONOMY_ID_UNIPROT_2,
+ TAXONOMY_SCIENTIFIC_NAME;
+ }
+
+ public static void addMolecularSeqsToTree( final Phylogeny phy, final Msa msa ) {
+ for( int s = 0; s < msa.getNumberOfSequences(); ++s ) {
+ final org.forester.sequence.MolecularSequence seq = msa.getSequence( s );
+ final PhylogenyNode node = phy.getNode( seq.getIdentifier() );
+ final org.forester.phylogeny.data.Sequence new_seq = new Sequence();
+ new_seq.setMolecularSequenceAligned( true );
+ new_seq.setMolecularSequence( seq.getMolecularSequenceAsString() );
+ new_seq.setName( seq.getIdentifier() );
+ try {
+ new_seq.setType( PhyloXmlUtil.SEQ_TYPE_PROTEIN );
+ }
+ catch ( final PhyloXmlDataFormatException ignore ) {
+ // do nothing
+ }
+ node.getNodeData().addSequence( new_seq );
+ }
+ }
+
+ final private static class PhylogenyNodeSortTaxonomyPriority implements Comparator<PhylogenyNode> {
+
+ @Override
+ public int compare( final PhylogenyNode n1, final PhylogenyNode n2 ) {
+ if ( n1.getNodeData().isHasTaxonomy() && n2.getNodeData().isHasTaxonomy() ) {
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getScientificName() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getScientificName() ) ) ) {
+ return n1.getNodeData().getTaxonomy().getScientificName().toLowerCase()
+ .compareTo( n2.getNodeData().getTaxonomy().getScientificName().toLowerCase() );
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getTaxonomyCode() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) {
+ return n1.getNodeData().getTaxonomy().getTaxonomyCode()
+ .compareTo( n2.getNodeData().getTaxonomy().getTaxonomyCode() );
+ }
+ }
+ if ( n1.getNodeData().isHasSequence() && n2.getNodeData().isHasSequence() ) {
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getName() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getName() ) ) ) {
+ return n1.getNodeData().getSequence().getName().toLowerCase()
+ .compareTo( n2.getNodeData().getSequence().getName().toLowerCase() );
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getGeneName() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getGeneName() ) ) ) {
+ return n1.getNodeData().getSequence().getGeneName()
+ .compareTo( n2.getNodeData().getSequence().getGeneName() );
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getSymbol() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getSymbol() ) ) ) {
+ return n1.getNodeData().getSequence().getSymbol()
+ .compareTo( n2.getNodeData().getSequence().getSymbol() );
+ }
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getName() ) ) && ( !ForesterUtil.isEmpty( n2.getName() ) ) ) {
+ return n1.getName().toLowerCase().compareTo( n2.getName().toLowerCase() );
+ }
+ return 0;
+ }
+ }
+
+ final private static class PhylogenyNodeSortSequencePriority implements Comparator<PhylogenyNode> {
+
+ @Override
+ public int compare( final PhylogenyNode n1, final PhylogenyNode n2 ) {
+ if ( n1.getNodeData().isHasSequence() && n2.getNodeData().isHasSequence() ) {
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getName() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getName() ) ) ) {
+ return n1.getNodeData().getSequence().getName().toLowerCase()
+ .compareTo( n2.getNodeData().getSequence().getName().toLowerCase() );
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getGeneName() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getGeneName() ) ) ) {
+ return n1.getNodeData().getSequence().getGeneName()
+ .compareTo( n2.getNodeData().getSequence().getGeneName() );
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getSymbol() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getSymbol() ) ) ) {
+ return n1.getNodeData().getSequence().getSymbol()
+ .compareTo( n2.getNodeData().getSequence().getSymbol() );
+ }
+ }
+ if ( n1.getNodeData().isHasTaxonomy() && n2.getNodeData().isHasTaxonomy() ) {
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getScientificName() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getScientificName() ) ) ) {
+ return n1.getNodeData().getTaxonomy().getScientificName().toLowerCase()
+ .compareTo( n2.getNodeData().getTaxonomy().getScientificName().toLowerCase() );
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getTaxonomyCode() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) {
+ return n1.getNodeData().getTaxonomy().getTaxonomyCode()
+ .compareTo( n2.getNodeData().getTaxonomy().getTaxonomyCode() );
+ }
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getName() ) ) && ( !ForesterUtil.isEmpty( n2.getName() ) ) ) {
+ return n1.getName().toLowerCase().compareTo( n2.getName().toLowerCase() );
+ }
+ return 0;
+ }
+ }
+
+ final private static class PhylogenyNodeSortNodeNamePriority implements Comparator<PhylogenyNode> {
+
+ @Override
+ public int compare( final PhylogenyNode n1, final PhylogenyNode n2 ) {
+ if ( ( !ForesterUtil.isEmpty( n1.getName() ) ) && ( !ForesterUtil.isEmpty( n2.getName() ) ) ) {
+ return n1.getName().toLowerCase().compareTo( n2.getName().toLowerCase() );
+ }
+ if ( n1.getNodeData().isHasTaxonomy() && n2.getNodeData().isHasTaxonomy() ) {
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getScientificName() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getScientificName() ) ) ) {
+ return n1.getNodeData().getTaxonomy().getScientificName().toLowerCase()
+ .compareTo( n2.getNodeData().getTaxonomy().getScientificName().toLowerCase() );
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getTaxonomy().getTaxonomyCode() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) {
+ return n1.getNodeData().getTaxonomy().getTaxonomyCode()
+ .compareTo( n2.getNodeData().getTaxonomy().getTaxonomyCode() );
+ }
+ }
+ if ( n1.getNodeData().isHasSequence() && n2.getNodeData().isHasSequence() ) {
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getName() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getName() ) ) ) {
+ return n1.getNodeData().getSequence().getName().toLowerCase()
+ .compareTo( n2.getNodeData().getSequence().getName().toLowerCase() );
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getGeneName() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getGeneName() ) ) ) {
+ return n1.getNodeData().getSequence().getGeneName()
+ .compareTo( n2.getNodeData().getSequence().getGeneName() );
+ }
+ if ( ( !ForesterUtil.isEmpty( n1.getNodeData().getSequence().getSymbol() ) )
+ && ( !ForesterUtil.isEmpty( n2.getNodeData().getSequence().getSymbol() ) ) ) {
+ return n1.getNodeData().getSequence().getSymbol()
+ .compareTo( n2.getNodeData().getSequence().getSymbol() );
+ }
+ }
+ return 0;
+ }
+ }
+
+ public final static Map<Long, Integer> calculateDepths( final Phylogeny phy ) {
+ final Map<Long, Integer> depths = new HashMap<Long, Integer>();
+ calculateDepthsHelper( phy.getRoot(), 0, depths );
+ return depths;
+ }
+
+ private final static void calculateDepthsHelper( final PhylogenyNode n, int d, final Map<Long, Integer> depths ) {
+ depths.put( n.getId(), d );
+ ++d;
+ final List<PhylogenyNode> descs = n.getDescendants();
+ for( final PhylogenyNode desc : descs ) {
+ calculateDepthsHelper( desc, d, depths );
+ }
+ }
+
+ public final static void collapseToDepth( final Phylogeny phy, final int depth ) {
+ if ( phy.getNumberOfExternalNodes() < 3 ) {
+ return;
+ }
+ collapseToDepthHelper( phy.getRoot(), 0, depth );
+ }
+
+ private final static void collapseToDepthHelper( final PhylogenyNode n, int d, final int depth ) {
+ if ( n.isExternal() ) {
+ n.setCollapse( false );
+ return;
+ }
+ if ( d >= depth ) {
+ n.setCollapse( true );
+ final PhylogenyNodeIterator it = new PreorderTreeIterator( n );
+ while ( it.hasNext() ) {
+ it.next().setCollapse( true );
+ }
+ }
+ else {
+ n.setCollapse( false );
+ ++d;
+ final List<PhylogenyNode> descs = n.getDescendants();
+ for( final PhylogenyNode desc : descs ) {
+ collapseToDepthHelper( desc, d, depth );
+ }
+ }
+ }
+
+
+
+ public final static void collapseToRank( final Phylogeny phy, final int rank ) {
+ if ( phy.getNumberOfExternalNodes() < 3 ) {
+ return;
+ }
+ if ( rank < 0 || rank >= TaxonomyUtil.RANKS.length ) {
+ throw new IllegalArgumentException( "Rank " + rank + " is out of range" );
+ }
+ collapseToRankHelper( phy.getRoot(), rank );
+ }
+
+ private final static void collapseToRankHelper( final PhylogenyNode n, final int target_rank ) {
+ if ( n.isExternal() ) {
+ n.setCollapse( false );
+ return;
+ }
+ if ( ( n.getNodeData().getTaxonomy() != null )
+ && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getRank() ) ) {
+ final String current_rank = n.getNodeData().getTaxonomy().getRank();
+ if ( !TaxonomyUtil.RANK_TO_INT.containsKey( current_rank ) ) {
+ System.out.println( "Don't know rank \"" + current_rank + "\", ignoring." );
+ }
+ else {
+ if ( TaxonomyUtil.RANK_TO_INT.get( current_rank ) >= target_rank ) {
+ n.setCollapse( true );
+
+ final PhylogenyNodeIterator it = new PreorderTreeIterator( n );
+ while ( it.hasNext() ) {
+ it.next().setCollapse( true );
+ }
+ return;
+ }
+ }
+ }
+ n.setCollapse( false );
+ final List<PhylogenyNode> descs = n.getDescendants();
+ for( final PhylogenyNode desc : descs ) {
+ collapseToRankHelper( desc, target_rank );
+ }
+ }
+
+ public final static PhylogenyNode getFirstExternalNode( final PhylogenyNode node ) {
+ PhylogenyNode n = node;
+ while ( n.isInternal() ) {
+ n = n.getFirstChildNode();
+ }
+ return n;
+ }
+
+ public final static PhylogenyNode getLastExternalNode( final PhylogenyNode node ) {
+ PhylogenyNode n = node;
+ while ( n.isInternal() ) {
+ n = n.getLastChildNode();
+ }
+ return n;