Skip to content

Commit

Permalink
Allow users to specify arbitrary IQ-TREE models
Browse files Browse the repository at this point in the history
IQ-TREE supports hundreds of models through its `-m` argument. When
users omit this argument, IQ-TREE will run a model test and use the best
model to build the tree. Users can refer to the IQ-TREE log file to find
the best model and use that in future runs of the command.

Unfortunately, augur tree hardcodes only a handful of possible
substitution models as viable choices for the `--substitution-model`
argument. Although the help text for `--substitution-model` says users
can provide "none" as an argument to run the IQ-TREE model test, "none"
is not one of the hardcoded choices. This means the model test
functionality of IQ-TREE hasn't been available for years. Additionally,
the message we print to stdout when users can select "none" refers to
the wrong log file, and once users find the best model for their data,
they cannot provide it to augur tree unless it happens to be one of the
predefined choices.

To address these issues, this commit removes the list of hardcoded
substitution model choices from augur tree, allowing users to provide
any valid IQ-TREE model or "none", as described in the help text. This
commit also adds a functional test of this "model test" interface that
revealed a typo in the code that calls IQ-TREE, fixes the typo, and
prints the path of the actual IQ-TREE log file to check for model test
results.

Fixes #619
  • Loading branch information
huddlej committed Oct 6, 2021
1 parent a44db6e commit 04b0bf4
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
6 changes: 3 additions & 3 deletions augur/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,15 @@ def random_string(n):
call = [iqtree, *fast_opts, "-nt", str(nthreads), "-s", shquote(tmp_aln_file),
"-m", substitution_model, tree_builder_args, ">", log_file]
else:
call = [iqtree *fast_opts, "-nt", str(nthreads), "-s", shquote(tmp_aln_file), tree_builder_args, ">", shquote(log_file)]
call = [iqtree, *fast_opts, "-nt", str(nthreads), "-s", shquote(tmp_aln_file), tree_builder_args, ">", shquote(log_file)]

cmd = " ".join(call)

print("Building a tree via:\n\t" + cmd +
"\n\tNguyen et al: IQ-TREE: A fast and effective stochastic algorithm for estimating maximum likelihood phylogenies."
"\n\tMol. Biol. Evol., 32:268-274. https://doi.org/10.1093/molbev/msu300\n")
if substitution_model.lower() == "none":
print("Conducting a model test... see iqtree.log for the result. You can specify this with --substitution-model in future runs.")
print(f"Conducting a model test... see '{shquote(log_file)}' for the result. You can specify this with --substitution-model in future runs.")

try:
run_shell_command(cmd, raise_errors = True)
Expand Down Expand Up @@ -344,7 +344,7 @@ def register_arguments(parser):
parser.add_argument('--alignment', '-a', required=True, help="alignment in fasta or VCF format")
parser.add_argument('--method', default='iqtree', choices=["fasttree", "raxml", "iqtree"], help="tree builder to use")
parser.add_argument('--output', '-o', type=str, help='file name to write tree to')
parser.add_argument('--substitution-model', default="GTR", choices=["HKY", "GTR", "HKY+G", "GTR+G", "GTR+R10"],
parser.add_argument('--substitution-model', default="GTR",
help='substitution model to use. Specify \'none\' to run ModelTest. Currently, only available for IQTREE.')
parser.add_argument('--nthreads', type=nthreads_value, default=1,
help="number of threads to use; specifying the value 'auto' will cause the number of available CPU cores on your system, if determinable, to be used")
Expand Down
9 changes: 9 additions & 0 deletions tests/functional/tree.t
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ Try building a tree with IQ-TREE with more threads (4) than there are input sequ
> --nthreads 4 > /dev/null
WARNING: more threads requested than there are sequences; falling back to IQ-TREE's `-nt AUTO` mode.

Try building a tree with IQ-TREE using its ModelTest functionality, by supplying a substitution model of "none".

$ ${AUGUR} tree \
> --alignment tree/aligned.fasta \
> --method iqtree \
> --substitution-model none \
> --output "$TMP/tree_raw.nwk" \
> --nthreads 1 > /dev/null

Clean up tree log files.

$ rm -f tree/*.log
Expand Down

0 comments on commit 04b0bf4

Please sign in to comment.