+
+ public final static RIO executeAnalysis( final File gene_trees_file,
+ final File species_tree_file,
+ final ALGORITHM algorithm,
+ final REROOTING rerooting,
+ final String outgroup,
+ final int first,
+ final int last,
+ final boolean produce_log,
+ final boolean verbose ) throws IOException, SDIException, RIOException {
+ final Phylogeny[] gene_trees = parseGeneTrees( gene_trees_file );
+ if ( gene_trees.length < 1 ) {
+ throw new RIOException( "\"" + gene_trees_file + "\" is devoid of appropriate gene trees" );
+ }
+ final Phylogeny species_tree = SDIutil.parseSpeciesTree( gene_trees[ 0 ],
+ species_tree_file,
+ false,
+ true,
+ TAXONOMY_EXTRACTION.NO );
+ return new RIO( gene_trees, species_tree, algorithm, rerooting, outgroup, first, last, produce_log, verbose );
+ }
+
+ public final static RIO executeAnalysis( final File gene_trees_file,
+ final Phylogeny species_tree,
+ final ALGORITHM algorithm,
+ final REROOTING rerooting,
+ final String outgroup,
+ final boolean produce_log,
+ final boolean verbose ) throws IOException, SDIException, RIOException {
+ return new RIO( parseGeneTrees( gene_trees_file ),
+ species_tree,
+ algorithm,
+ rerooting,
+ outgroup,
+ DEFAULT_RANGE,
+ DEFAULT_RANGE,
+ produce_log,
+ verbose );
+ }
+
+ public final static RIO executeAnalysis( final File gene_trees_file,
+ final Phylogeny species_tree,
+ final ALGORITHM algorithm,
+ final REROOTING rerooting,
+ final String outgroup,
+ final int first,
+ final int last,
+ final boolean produce_log,
+ final boolean verbose ) throws IOException, SDIException, RIOException {
+ return new RIO( parseGeneTrees( gene_trees_file ),
+ species_tree,
+ algorithm,
+ rerooting,
+ outgroup,
+ first,
+ last,
+ produce_log,
+ verbose );
+ }
+
+ public final static RIO executeAnalysis( final Phylogeny[] gene_trees, final Phylogeny species_tree )
+ throws IOException, SDIException, RIOException {
+ return new RIO( gene_trees,
+ species_tree,
+ ALGORITHM.GSDIR,
+ REROOTING.BY_ALGORITHM,
+ null,
+ DEFAULT_RANGE,
+ DEFAULT_RANGE,
+ false,
+ false );
+ }
+
+ public final static RIO executeAnalysis( final Phylogeny[] gene_trees,
+ final Phylogeny species_tree,
+ final ALGORITHM algorithm,
+ final REROOTING rerooting,
+ final String outgroup,
+ final boolean produce_log,
+ final boolean verbose ) throws IOException, SDIException, RIOException {
+ return new RIO( gene_trees,
+ species_tree,
+ algorithm,
+ rerooting,
+ outgroup,
+ DEFAULT_RANGE,
+ DEFAULT_RANGE,
+ produce_log,
+ verbose );
+ }
+
+ public final static RIO executeAnalysis( final Phylogeny[] gene_trees,
+ final Phylogeny species_tree,
+ final ALGORITHM algorithm,
+ final REROOTING rerooting,
+ final String outgroup,
+ final int first,
+ final int last,
+ final boolean produce_log,
+ final boolean verbose ) throws IOException, SDIException, RIOException {
+ return new RIO( gene_trees, species_tree, algorithm, rerooting, outgroup, first, last, produce_log, verbose );
+ }
+
+ private final static void checkPreconditions( final Phylogeny[] gene_trees,
+ final Phylogeny species_tree,
+ final REROOTING rerooting,
+ final String outgroup,
+ final int first,
+ final int last ) throws RIOException {
+ if ( !species_tree.isRooted() ) {
+ throw new RIOException( "species tree is not rooted" );
+ }
+ if ( !( ( last == DEFAULT_RANGE ) && ( first == DEFAULT_RANGE ) )
+ && ( ( last < first ) || ( last >= gene_trees.length ) || ( last < 0 ) || ( first < 0 ) ) ) {
+ throw new RIOException( "attempt to set range (0-based) of gene to analyze to: from " + first + " to "
+ + last + " (out of " + gene_trees.length + ")" );
+ }
+ if ( ( rerooting == REROOTING.OUTGROUP ) && ForesterUtil.isEmpty( outgroup ) ) {
+ throw new RIOException( "outgroup not set for midpoint rooting" );
+ }
+ if ( ( rerooting != REROOTING.OUTGROUP ) && !ForesterUtil.isEmpty( outgroup ) ) {
+ throw new RIOException( "outgroup only used for midpoint rooting" );
+ }
+ if ( ( rerooting == REROOTING.MIDPOINT )
+ && ( PhylogenyMethods.calculateMaxDistanceToRoot( gene_trees[ 0 ] ) <= 0 ) ) {
+ throw new RIOException( "attempt to use midpoint rooting on gene trees which seem to have no (positive) branch lengths (cladograms)" );
+ }
+ if ( rerooting == REROOTING.OUTGROUP ) {
+ try {
+ gene_trees[ 0 ].getNode( outgroup );
+ }
+ catch ( final IllegalArgumentException e ) {
+ throw new RIOException( "cannot perform re-rooting by outgroup: " + e.getLocalizedMessage() );
+ }
+ }
+ }
+
+ private final static Phylogeny[] parseGeneTrees( final File gene_trees_file ) throws FileNotFoundException,
+ IOException {
+ final PhylogenyFactory factory = ParserBasedPhylogenyFactory.getInstance();
+ final PhylogenyParser p = ParserUtils.createParserDependingOnFileType( gene_trees_file, true );
+ if ( p instanceof NHXParser ) {
+ final NHXParser nhx = ( NHXParser ) p;
+ nhx.setReplaceUnderscores( false );
+ nhx.setIgnoreQuotes( true );
+ nhx.setTaxonomyExtraction( NHXParser.TAXONOMY_EXTRACTION.YES );
+ }
+ else if ( p instanceof NexusPhylogeniesParser ) {
+ final NexusPhylogeniesParser nex = ( NexusPhylogeniesParser ) p;
+ nex.setReplaceUnderscores( false );
+ nex.setIgnoreQuotes( true );
+ nex.setTaxonomyExtraction( TAXONOMY_EXTRACTION.YES );
+ }
+ return factory.create( gene_trees_file, p );
+ }
+
+ private final static void removeSingleDescendentsNodes( final Phylogeny species_tree, final boolean verbose ) {
+ final int o = PhylogenyMethods.countNumberOfOneDescendantNodes( species_tree );
+ if ( o > 0 ) {
+ if ( verbose ) {
+ System.out.println( "warning: species tree has " + o
+ + " internal nodes with only one descendent which are therefore going to be removed" );
+ }
+ PhylogenyMethods.deleteInternalNodesWithOnlyOneDescendent( species_tree );
+ }
+ }
+
+ public enum REROOTING {
+ NONE, BY_ALGORITHM, MIDPOINT, OUTGROUP;
+ }