+ private final void inferOrthologs( final Phylogeny[] gene_trees,
+ final Phylogeny species_tree,
+ final ALGORITHM algorithm,
+ final String outgroup,
+ final int first,
+ final int last,
+ final boolean transfer_taxonomy ) throws SDIException, RIOException,
+ FileNotFoundException, IOException {
+ if ( algorithm == ALGORITHM.SDIR ) {
+ // Removes from species_tree all species not found in gene_tree.
+ PhylogenyMethods.taxonomyBasedDeletionOfExternalNodes( gene_trees[ 0 ], species_tree );
+ if ( species_tree.isEmpty() ) {
+ throw new RIOException( "failed to establish species based mapping between gene and species trees" );
+ }
+ }
+ final Phylogeny[] my_gene_trees;
+ if ( ( first >= 0 ) && ( last >= first ) && ( last < gene_trees.length ) ) {
+ my_gene_trees = new Phylogeny[ ( 1 + last ) - first ];
+ int c = 0;
+ for( int i = first; i <= last; ++i ) {
+ my_gene_trees[ c++ ] = gene_trees[ i ];
+ }
+ }
+ else {
+ my_gene_trees = gene_trees;
+ }
+ if ( log() ) {
+ preLog( gene_trees.length, species_tree, algorithm, outgroup );
+ }
+ if ( _verbose && ( my_gene_trees.length >= 4 ) ) {
+ System.out.println();
+ }
+ _analyzed_gene_trees = new Phylogeny[ my_gene_trees.length ];
+ int gene_tree_ext_nodes = 0;
+ for( int i = 0; i < my_gene_trees.length; ++i ) {
+ final Phylogeny gt = my_gene_trees[ i ];
+ if ( gt.isEmpty() ) {
+ throw new RIOException( "gene tree #" + i + " is empty" );
+ }
+ if ( gt.getNumberOfExternalNodes() == 1 ) {
+ throw new RIOException( "gene tree #" + i + " has only one external node" );
+ }
+ if ( _verbose && ( my_gene_trees.length > 4 ) ) {
+ ForesterUtil.updateProgress( ( ( double ) i ) / my_gene_trees.length );
+ }
+ if ( i == 0 ) {
+ gene_tree_ext_nodes = gt.getNumberOfExternalNodes();
+ }
+ else if ( gene_tree_ext_nodes != gt.getNumberOfExternalNodes() ) {
+ throw new RIOException( "gene tree #" + i + " has a different number of external nodes ("
+ + gt.getNumberOfExternalNodes() + ") than the preceding gene tree(s) (" + gene_tree_ext_nodes
+ + ")" );
+ }
+ if ( algorithm == ALGORITHM.SDIR ) {
+ // Removes from gene_tree all species not found in species_tree.
+ PhylogenyMethods.taxonomyBasedDeletionOfExternalNodes( species_tree, gt );
+ if ( gt.isEmpty() ) {
+ throw new RIOException( "failed to establish species based mapping between gene and species trees" );
+ }
+ }
+ _analyzed_gene_trees[ i ] = performOrthologInference( gt,
+ species_tree,
+ algorithm,
+ outgroup,
+ i,
+ transfer_taxonomy );
+ }
+ if ( log() ) {
+ postLog( species_tree, first, last );
+ }
+ if ( _verbose && ( my_gene_trees.length > 4 ) ) {
+ System.out.println();
+ System.out.println();
+ }
+ }
+