Coverage for PanACoTA/tree_module/iqtree_func.py: 100%
54 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-20 14:37 +0000
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-20 14:37 +0000
1#!/usr/bin/env python3
2# coding: utf-8
4# ###############################################################################
5# This file is part of PanACOTA. #
6# #
7# Authors: Amandine Perrin #
8# Copyright © 2018-2020 Institut Pasteur (Paris). #
9# See the COPYRIGHT file for details. #
10# #
11# PanACOTA is a software providing tools for large scale bacterial comparative #
12# genomics. From a set of complete and/or draft genomes, you can: #
13# - Do a quality control of your strains, to eliminate poor quality #
14# genomes, which would not give any information for the comparative study #
15# - Uniformly annotate all genomes #
16# - Do a Pan-genome #
17# - Do a Core or Persistent genome #
18# - Align all Core/Persistent families #
19# - Infer a phylogenetic tree from the Core/Persistent families #
20# #
21# PanACOTA is free software: you can redistribute it and/or modify it under the #
22# terms of the Affero GNU General Public License as published by the Free #
23# Software Foundation, either version 3 of the License, or (at your option) #
24# any later version. #
25# #
26# PanACOTA is distributed in the hope that it will be useful, but WITHOUT ANY #
27# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
28# FOR A PARTICULAR PURPOSE. See the Affero GNU General Public License #
29# for more details. #
30# #
31# You should have received a copy of the Affero GNU General Public License #
32# along with PanACOTA (COPYING file). #
33# If not, see <https://www.gnu.org/licenses/>. #
34# ###############################################################################
36"""
37Function to infer a phylogenetic tree from a persistent genome, using IQtree
39@author gem
40July 2020
41"""
43import os
44import logging
46from PanACoTA import utils
48logger = logging.getLogger("tree.iqtree")
50def run_tree(alignfile, boot, outdir, quiet, threads, **kwargs):
51 """
52 Run IQtree for the given alignment file and options
54 Parameters
55 ----------
56 alignfile: str
57 path to file containing all persistent families aligned, and grouped by genome
58 boot: int or None
59 number of bootstraps to calculate, None if no bootstrap asked
60 outdir: str or None
61 Path to the tree file that must be created
62 quiet: bool
63 True if nothing must be printed to stderr/stdout, False otherwise
64 threads: int
65 Maximum number of threads to use
66 kwargs["model"]: str
67 DNA substitution model chosen by user
68 kwards["wb"]: bool
69 True if all bootstrap pseudo-trees must be saved into a file, False otherwise
70 kwargs["mem"]: str
71 Maximal RAM usage in GB | MB | % - Only for iqtree
72 kwargs["s"]: str
73 soft to use (iqtree or iqtree2)
74 """
75 # Get optional arguments
76 model = kwargs["model"]
77 write_boot = kwargs["wb"]
78 memory = kwargs["mem"]
79 soft = kwargs["s"]
80 fast = kwargs["f"]
81 if not fast:
82 fast = ""
83 else:
84 fast = "-fast"
86 logger.info("Running IQtree...")
88 # Init non mandatory arguments
89 bootinfo = ""
90 wb_info = ""
91 mem_info = ""
92 threadinfo = ""
94 # Get info on all options (syntax changes according to IQtree version 1.x or 2.x)
95 if boot:
96 if soft=="iqtree":
97 bootinfo = f"-bb {boot}"
98 else:
99 bootinfo = f"-B {boot}"
100 if write_boot:
101 if soft == "iqtree":
102 wb_info = "-wbt"
103 else:
104 wb_info = "--boot-trees"
105 if memory:
106 if soft=="iqtree":
107 mem_info = f"-mem {memory}"
108 else:
109 mem_info = f"--mem {memory}"
110 # IQtree is always run quietly, but syntax depends on version:
111 if soft=="iqtree":
112 qu = "-quiet"
113 else:
114 qu = "--quiet"
115 # Get threads information
116 if threads:
117 if soft == "iqtree":
118 threadinfo = f"-nt {threads}"
119 else:
120 threadinfo = f"-T {threads}"
122 # get cmd for seqtype
123 if soft == "iqtree":
124 seqtype = "-st DNA"
125 else:
126 seqtype = "--seqtype DNA"
128 # Define treefile name if not given.
129 align_name = os.path.basename(alignfile)
130 logfile = os.path.join(outdir, align_name + ".iqtree.log")
131 treefile = os.path.join(outdir, align_name + ".iqtree_tree")
132 # get prefix cmd:
133 if soft == "iqtree":
134 prefix = f"-pre {treefile}"
135 else:
136 prefix = f"--prefix {treefile}"
137 cmd = (f"{soft} -s {alignfile} {threadinfo} -m {model} {mem_info} {bootinfo} {wb_info} "
138 f"{seqtype} {prefix} {qu} {fast}")
139 logger.details("IQtree command: " + cmd)
140 if quiet:
141 fnull = open(os.devnull, 'w')
142 else:
143 fnull = None
144 error = (f"Problem while running IQtree. See log file ({logfile}) for "
145 "more information.")
146 utils.run_cmd(cmd, error, eof=True, logger=logger, stderr=fnull)