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

1#!/usr/bin/env python3 

2# coding: utf-8 

3 

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# ############################################################################### 

35 

36""" 

37Function to infer a phylogenetic tree from a persistent genome, using IQtree 

38 

39@author gem 

40July 2020 

41""" 

42 

43import os 

44import logging 

45 

46from PanACoTA import utils 

47 

48logger = logging.getLogger("tree.iqtree") 

49 

50def run_tree(alignfile, boot, outdir, quiet, threads, **kwargs): 

51 """ 

52 Run IQtree for the given alignment file and options 

53 

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" 

85 

86 logger.info("Running IQtree...") 

87 

88 # Init non mandatory arguments 

89 bootinfo = "" 

90 wb_info = "" 

91 mem_info = "" 

92 threadinfo = "" 

93 

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}" 

121 

122 # get cmd for seqtype 

123 if soft == "iqtree": 

124 seqtype = "-st DNA" 

125 else: 

126 seqtype = "--seqtype DNA" 

127 

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)