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

59 statements  

« prev     ^ index     » next       coverage.py v7.15.3, created at 2026-08-03 13:34 +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 """Read the box center and the box edge lengths from the REMARK line of a box PDB file. 

145 

146 The SIZE field is the full edge length of the box, matching what AutoDock Vina 

147 expects in --size_x/y/z. 

148 """ 

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

150 for line in box_file: 

151 line = line.rstrip(os.linesep) 

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

153 fields = line.split() 

154 center = fields[3:6] 

155 size = fields[-3:] 

156 return list( 

157 map( 

158 str, 

159 [ 

160 center[0], 

161 center[1], 

162 center[2], 

163 size[0], 

164 size[1], 

165 size[2], 

166 ], 

167 ) 

168 ) 

169 raise SystemExit( 

170 "No 'REMARK BOX CENTER' line found in the input box file: %s" 

171 % (box_file_path) 

172 ) 

173 

174 @launchlogger 

175 def launch(self) -> int: 

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

177 

178 # check input/output paths and parameters 

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

180 

181 # Setup Biobb 

182 if self.check_restart(): 

183 return 0 

184 self.stage_files() 

185 

186 if self.container_path: 

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

188 else: 

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

190 

191 # calculating box position and size 

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

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

194 ) 

195 

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

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

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

199 

200 # create cmd 

201 self.cmd = [ 

202 "cd", 

203 working_dir, 

204 ";", 

205 self.binary_path, 

206 "--ligand", 

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

208 "--receptor", 

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

210 "--center_x=" + x0, 

211 "--center_y=" + y0, 

212 "--center_z=" + z0, 

213 "--size_x=" + sidex, 

214 "--size_y=" + sidey, 

215 "--size_z=" + sidez, 

216 "--cpu", 

217 str(self.cpu), 

218 "--exhaustiveness", 

219 str(self.exhaustiveness), 

220 "--num_modes", 

221 str(self.num_modes), 

222 "--min_rmsd", 

223 str(self.min_rmsd), 

224 "--energy_range", 

225 str(self.energy_range), 

226 "--out", 

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

228 "--verbosity", 

229 "1", 

230 ">", 

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

232 ] 

233 

234 # Run Biobb block 

235 self.run_biobb() 

236 

237 # Copy files to host 

238 self.copy_to_host() 

239 

240 # remove temporary folder(s) 

241 self.remove_tmp_files() 

242 

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

244 

245 return self.return_code 

246 

247 

248def autodock_vina_run( 

249 input_ligand_pdbqt_path: str, 

250 input_receptor_pdbqt_path: str, 

251 input_box_path: str, 

252 output_pdbqt_path: str, 

253 output_log_path: Optional[str] = None, 

254 properties: Optional[dict] = None, 

255 **kwargs, 

256) -> int: 

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

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

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

260 

261 

262autodock_vina_run.__doc__ = AutoDockVinaRun.__doc__ 

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

264 

265 

266if __name__ == "__main__": 

267 main()