Coverage for biobb_vs/vina/autodock_vina_run.py: 93%

59 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-05-28 09:09 +0000

1#!/usr/bin/env python3 

2 

3"""Module containing the AutoDockVinaRun class and the command line interface.""" 

4import os 

5from pathlib import PurePath 

6from typing import Optional 

7from biobb_common.generic.biobb_object import BiobbObject 

8from biobb_common.tools.file_utils import launchlogger 

9from biobb_vs.vina.common import check_input_path, check_output_path 

10 

11 

12class AutoDockVinaRun(BiobbObject): 

13 """ 

14 | biobb_vs AutoDockVinaRun 

15 | Wrapper of the AutoDock Vina software. 

16 | This class performs docking of the ligand to a set of grids describing the target protein via the `AutoDock Vina <http://vina.scripps.edu/index.html>`_ software. 

17 

18 Args: 

19 input_ligand_pdbqt_path (str): Path to the input PDBQT ligand. File type: input. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/data/vina/vina_ligand.pdbqt>`_. Accepted formats: pdbqt (edam:format_1476). 

20 input_receptor_pdbqt_path (str): Path to the input PDBQT receptor. File type: input. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/data/vina/vina_receptor.pdbqt>`_. Accepted formats: pdbqt (edam:format_1476). 

21 input_box_path (str): Path to the PDB containig the residues belonging to the binding site. File type: input. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/data/vina/vina_box.pdb>`_. Accepted formats: pdb (edam:format_1476). 

22 output_pdbqt_path (str): Path to the output PDBQT file. File type: output. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/reference/vina/ref_output_vina.pdbqt>`_. Accepted formats: pdbqt (edam:format_1476). 

23 output_log_path (str) (Optional): Path to the log file. File type: output. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/reference/vina/ref_output_vina.log>`_. Accepted formats: log (edam:format_2330). 

24 properties (dic - Python dictionary object containing the tool parameters, not input/output files): 

25 * **cpu** (*int*) - (1) [1~1000|1] the number of CPUs to use. 

26 * **exhaustiveness** (*int*) - (8) [1~10000|1] exhaustiveness of the global search (roughly proportional to time). 

27 * **num_modes** (*int*) - (9) [1~1000|1] maximum number of binding modes to generate. 

28 * **min_rmsd** (*int*) - (1) [1~1000|1] minimum RMSD between output poses. 

29 * **energy_range** (*int*) - (3) [1~1000|1] maximum energy difference between the best binding mode and the worst one displayed (kcal/mol). 

30 * **binary_path** (*string*) - ('vina') path to vina in your local computer. 

31 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files. 

32 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist. 

33 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory. 

34 * **container_path** (*str*) - (None) Container path definition. 

35 * **container_image** (*str*) - ('biocontainers/autodock-vina:v1.1.2-5b1-deb_cv1') Container image definition. 

36 * **container_volume_path** (*str*) - ('/tmp') Container volume path definition. 

37 * **container_working_dir** (*str*) - (None) Container working directory definition. 

38 * **container_user_id** (*str*) - (None) Container user_id definition. 

39 * **container_shell_path** (*str*) - ('/bin/bash') Path to default shell inside the container. 

40 

41 Examples: 

42 This is a use example of how to use the building block from Python:: 

43 

44 from biobb_vs.vina.autodock_vina_run import autodock_vina_run 

45 prop = { 

46 'binary_path': 'vina' 

47 } 

48 autodock_vina_run(input_ligand_pdbqt_path='/path/to/myLigand.pdbqt', 

49 input_receptor_pdbqt_path='/path/to/myReceptor.pdbqt', 

50 input_box_path='/path/to/myBox.pdb', 

51 output_pdbqt_path='/path/to/newStructure.pdbqt', 

52 output_log_path='/path/to/newLog.log', 

53 properties=prop) 

54 

55 Info: 

56 * wrapped_software: 

57 * name: Autodock Vina 

58 * version: >=1.2.3 

59 * license: Apache-2.0 

60 * ontology: 

61 * name: EDAM 

62 * schema: http://edamontology.org/EDAM.owl 

63 

64 """ 

65 

66 def __init__( 

67 self, 

68 input_ligand_pdbqt_path, 

69 input_receptor_pdbqt_path, 

70 input_box_path, 

71 output_pdbqt_path, 

72 output_log_path=None, 

73 properties=None, 

74 **kwargs, 

75 ) -> None: 

76 properties = properties or {} 

77 

78 # Call parent class constructor 

79 super().__init__(properties) 

80 self.locals_var_dict = locals().copy() 

81 

82 # Input/Output files 

83 self.io_dict = { 

84 "in": { 

85 "input_ligand_pdbqt_path": input_ligand_pdbqt_path, 

86 "input_receptor_pdbqt_path": input_receptor_pdbqt_path, 

87 "input_box_path": input_box_path, 

88 }, 

89 "out": { 

90 "output_pdbqt_path": output_pdbqt_path, 

91 "output_log_path": output_log_path, 

92 }, 

93 } 

94 

95 # Properties specific for BB 

96 self.cpu = properties.get("cpu", 1) 

97 self.exhaustiveness = properties.get("exhaustiveness", 8) 

98 self.num_modes = properties.get("num_modes", 9) 

99 self.min_rmsd = properties.get("min_rmsd", 1) 

100 self.energy_range = properties.get("energy_range", 3) 

101 self.binary_path = properties.get("binary_path", "vina") 

102 self.properties = properties 

103 

104 # Check the properties 

105 self.check_properties(properties) 

106 self.check_arguments() 

107 

108 def check_data_params(self, out_log, err_log): 

109 """Checks all the input/output paths and parameters""" 

110 self.io_dict["in"]["input_ligand_pdbqt_path"] = check_input_path( 

111 self.io_dict["in"]["input_ligand_pdbqt_path"], 

112 "input_ligand_pdbqt_path", 

113 self.out_log, 

114 self.__class__.__name__, 

115 ) 

116 self.io_dict["in"]["input_receptor_pdbqt_path"] = check_input_path( 

117 self.io_dict["in"]["input_receptor_pdbqt_path"], 

118 "input_receptor_pdbqt_path", 

119 self.out_log, 

120 self.__class__.__name__, 

121 ) 

122 self.io_dict["in"]["input_box_path"] = check_input_path( 

123 self.io_dict["in"]["input_box_path"], 

124 "input_box_path", 

125 self.out_log, 

126 self.__class__.__name__, 

127 ) 

128 self.io_dict["out"]["output_pdbqt_path"] = check_output_path( 

129 self.io_dict["out"]["output_pdbqt_path"], 

130 "output_pdbqt_path", 

131 False, 

132 self.out_log, 

133 self.__class__.__name__, 

134 ) 

135 self.io_dict["out"]["output_log_path"] = check_output_path( 

136 self.io_dict["out"]["output_log_path"], 

137 "output_log_path", 

138 True, 

139 self.out_log, 

140 self.__class__.__name__, 

141 ) 

142 

143 def calculate_box(self, box_file_path): 

144 with open(box_file_path, "r") as box_file: 

145 for line in box_file: 

146 line = line.rstrip(os.linesep) 

147 if line.startswith("REMARK BOX CENTER"): 

148 fields = line.split() 

149 center = fields[3:6] 

150 size = fields[-3:] 

151 return list( 

152 map( 

153 str, 

154 [ 

155 center[0], 

156 center[1], 

157 center[2], 

158 size[0], 

159 size[1], 

160 size[2], 

161 ], 

162 ) 

163 ) 

164 return list(map(str, [0, 0, 0, 0, 0, 0])) 

165 

166 @launchlogger 

167 def launch(self) -> int: 

168 """Execute the :class:`AutoDockVinaRun_run <vina.autodock_vina_run.AutoDockVinaRun_run>` vina.autodock_vina_run.AutoDockVinaRun_run object.""" 

169 

170 # check input/output paths and parameters 

171 self.check_data_params(self.out_log, self.err_log) 

172 

173 # Setup Biobb 

174 if self.check_restart(): 

175 return 0 

176 self.stage_files() 

177 

178 if self.container_path: 

179 working_dir = self.container_volume_path if self.container_volume_path else "/tmp" 

180 else: 

181 working_dir = self.stage_io_dict.get("unique_dir", "") 

182 

183 # calculating box position and size 

184 x0, y0, z0, sidex, sidey, sidez = self.calculate_box( 

185 self.io_dict["in"]["input_box_path"] 

186 ) 

187 

188 # in case ligand or receptor end with END, remove last line 

189 # check_input_autodock(self.io_dict["in"]["input_ligand_pdbqt_path"], self.out_log) 

190 # check_input_autodock(self.io_dict["in"]["input_receptor_pdbqt_path"], self.out_log) 

191 

192 # create cmd 

193 self.cmd = [ 

194 "cd", 

195 working_dir, 

196 ";", 

197 self.binary_path, 

198 "--ligand", 

199 PurePath(self.stage_io_dict["in"]["input_ligand_pdbqt_path"]).name, 

200 "--receptor", 

201 PurePath(self.stage_io_dict["in"]["input_receptor_pdbqt_path"]).name, 

202 "--center_x=" + x0, 

203 "--center_y=" + y0, 

204 "--center_z=" + z0, 

205 "--size_x=" + sidex, 

206 "--size_y=" + sidey, 

207 "--size_z=" + sidez, 

208 "--cpu", 

209 str(self.cpu), 

210 "--exhaustiveness", 

211 str(self.exhaustiveness), 

212 "--num_modes", 

213 str(self.num_modes), 

214 "--min_rmsd", 

215 str(self.min_rmsd), 

216 "--energy_range", 

217 str(self.energy_range), 

218 "--out", 

219 PurePath(self.stage_io_dict["out"]["output_pdbqt_path"]).name, 

220 "--verbosity", 

221 "1", 

222 ">", 

223 PurePath(self.stage_io_dict["out"]["output_log_path"]).name, 

224 ] 

225 

226 # Run Biobb block 

227 self.run_biobb() 

228 

229 # Copy files to host 

230 self.copy_to_host() 

231 

232 # remove temporary folder(s) 

233 self.remove_tmp_files() 

234 

235 self.check_arguments(output_files_created=True, raise_exception=False) 

236 

237 return self.return_code 

238 

239 

240def autodock_vina_run( 

241 input_ligand_pdbqt_path: str, 

242 input_receptor_pdbqt_path: str, 

243 input_box_path: str, 

244 output_pdbqt_path: str, 

245 output_log_path: Optional[str] = None, 

246 properties: Optional[dict] = None, 

247 **kwargs, 

248) -> int: 

249 """Create the :class:`AutoDockVinaRun <vina.autodock_vina_run.AutoDockVinaRun>` class and 

250 execute the :meth:`launch() <vina.autodock_vina_run.AutoDockVinaRun.launch>` method.""" 

251 return AutoDockVinaRun(**dict(locals())).launch() 

252 

253 

254autodock_vina_run.__doc__ = AutoDockVinaRun.__doc__ 

255main = AutoDockVinaRun.get_main(autodock_vina_run, "Prepares input ligand for an Autodock Vina Virtual Screening.") 

256 

257 

258if __name__ == "__main__": 

259 main()