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

69 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-28 12:00 +0000

1#!/usr/bin/env python3 

2 

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

4 

5import argparse 

6import os 

7from typing import Optional 

8 

9from biobb_common.configuration import settings 

10from biobb_common.generic.biobb_object import BiobbObject 

11from biobb_common.tools.file_utils import launchlogger 

12 

13from biobb_vs.vina.common import check_input_path, check_output_path 

14 

15 

16class AutoDockVinaRun(BiobbObject): 

17 """ 

18 | biobb_vs AutoDockVinaRun 

19 | Wrapper of the AutoDock Vina software. 

20 | 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. 

21 

22 Args: 

23 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). 

24 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). 

25 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). 

26 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). 

27 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). 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

44 

45 Examples: 

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

47 

48 from biobb_vs.vina.autodock_vina_run import autodock_vina_run 

49 prop = { 

50 'binary_path': 'vina' 

51 } 

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

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

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

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

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

57 properties=prop) 

58 

59 Info: 

60 * wrapped_software: 

61 * name: Autodock Vina 

62 * version: >=1.2.3 

63 * license: Apache-2.0 

64 * ontology: 

65 * name: EDAM 

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

67 

68 """ 

69 

70 def __init__( 

71 self, 

72 input_ligand_pdbqt_path, 

73 input_receptor_pdbqt_path, 

74 input_box_path, 

75 output_pdbqt_path, 

76 output_log_path=None, 

77 properties=None, 

78 **kwargs, 

79 ) -> None: 

80 properties = properties or {} 

81 

82 # Call parent class constructor 

83 super().__init__(properties) 

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

85 

86 # Input/Output files 

87 self.io_dict = { 

88 "in": { 

89 "input_ligand_pdbqt_path": input_ligand_pdbqt_path, 

90 "input_receptor_pdbqt_path": input_receptor_pdbqt_path, 

91 "input_box_path": input_box_path, 

92 }, 

93 "out": { 

94 "output_pdbqt_path": output_pdbqt_path, 

95 "output_log_path": output_log_path, 

96 }, 

97 } 

98 

99 # Properties specific for BB 

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

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

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

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

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

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

106 self.properties = properties 

107 

108 # Check the properties 

109 self.check_properties(properties) 

110 self.check_arguments() 

111 

112 def check_data_params(self, out_log, err_log): 

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

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

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

116 "input_ligand_pdbqt_path", 

117 self.out_log, 

118 self.__class__.__name__, 

119 ) 

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

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

122 "input_receptor_pdbqt_path", 

123 self.out_log, 

124 self.__class__.__name__, 

125 ) 

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

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

128 "input_box_path", 

129 self.out_log, 

130 self.__class__.__name__, 

131 ) 

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

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

134 "output_pdbqt_path", 

135 False, 

136 self.out_log, 

137 self.__class__.__name__, 

138 ) 

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

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

141 "output_log_path", 

142 True, 

143 self.out_log, 

144 self.__class__.__name__, 

145 ) 

146 

147 def calculate_box(self, box_file_path): 

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

149 for line in box_file: 

150 line = line.rstrip(os.linesep) 

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

152 fields = line.split() 

153 center = fields[3:6] 

154 size = fields[-3:] 

155 return list( 

156 map( 

157 str, 

158 [ 

159 center[0], 

160 center[1], 

161 center[2], 

162 size[0], 

163 size[1], 

164 size[2], 

165 ], 

166 ) 

167 ) 

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

169 

170 @launchlogger 

171 def launch(self) -> int: 

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

173 

174 # check input/output paths and parameters 

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

176 

177 # Setup Biobb 

178 if self.check_restart(): 

179 return 0 

180 self.stage_files() 

181 

182 # calculating box position and size 

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

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

185 ) 

186 

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

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

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

190 

191 # create cmd 

192 self.cmd = [ 

193 self.binary_path, 

194 "--ligand", 

195 self.stage_io_dict["in"]["input_ligand_pdbqt_path"], 

196 "--receptor", 

197 self.stage_io_dict["in"]["input_receptor_pdbqt_path"], 

198 "--center_x=" + x0, 

199 "--center_y=" + y0, 

200 "--center_z=" + z0, 

201 "--size_x=" + sidex, 

202 "--size_y=" + sidey, 

203 "--size_z=" + sidez, 

204 "--cpu", 

205 str(self.cpu), 

206 "--exhaustiveness", 

207 str(self.exhaustiveness), 

208 "--num_modes", 

209 str(self.num_modes), 

210 "--min_rmsd", 

211 str(self.min_rmsd), 

212 "--energy_range", 

213 str(self.energy_range), 

214 "--out", 

215 self.stage_io_dict["out"]["output_pdbqt_path"], 

216 "--verbosity", 

217 "1", 

218 ">", 

219 self.stage_io_dict["out"]["output_log_path"], 

220 ] 

221 

222 # Run Biobb block 

223 self.run_biobb() 

224 

225 # Copy files to host 

226 self.copy_to_host() 

227 

228 # remove temporary folder(s) 

229 # self.tmp_files.extend([self.stage_io_dict.get("unique_dir", "")]) 

230 self.remove_tmp_files() 

231 

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

233 

234 return self.return_code 

235 

236 

237def autodock_vina_run( 

238 input_ligand_pdbqt_path: str, 

239 input_receptor_pdbqt_path: str, 

240 input_box_path: str, 

241 output_pdbqt_path: str, 

242 output_log_path: Optional[str] = None, 

243 properties: Optional[dict] = None, 

244 **kwargs, 

245) -> int: 

246 """Execute the :class:`AutoDockVinaRun <vina.autodock_vina_run.AutoDockVinaRun>` class and 

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

248 

249 return AutoDockVinaRun( 

250 input_ligand_pdbqt_path=input_ligand_pdbqt_path, 

251 input_receptor_pdbqt_path=input_receptor_pdbqt_path, 

252 input_box_path=input_box_path, 

253 output_pdbqt_path=output_pdbqt_path, 

254 output_log_path=output_log_path, 

255 properties=properties, 

256 **kwargs, 

257 ).launch() 

258 

259 autodock_vina_run.__doc__ = AutoDockVinaRun.__doc__ 

260 

261 

262def main(): 

263 """Command line execution of this building block. Please check the command line documentation.""" 

264 parser = argparse.ArgumentParser( 

265 description="Prepares input ligand for an Autodock Vina Virtual Screening.", 

266 formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999), 

267 ) 

268 parser.add_argument("--config", required=False, help="Configuration file") 

269 

270 # Specific args of each building block 

271 required_args = parser.add_argument_group("required arguments") 

272 required_args.add_argument( 

273 "--input_ligand_pdbqt_path", 

274 required=True, 

275 help="Path to the input PDBQT ligand. Accepted formats: pdbqt.", 

276 ) 

277 required_args.add_argument( 

278 "--input_receptor_pdbqt_path", 

279 required=True, 

280 help="Path to the input PDBQT receptor. Accepted formats: pdbqt.", 

281 ) 

282 required_args.add_argument( 

283 "--input_box_path", 

284 required=True, 

285 help="Path to the PDB containig the residues belonging to the binding site. Accepted formats: pdb.", 

286 ) 

287 required_args.add_argument( 

288 "--output_pdbqt_path", 

289 required=True, 

290 help="Path to the output PDBQT file. Accepted formats: pdbqt.", 

291 ) 

292 parser.add_argument( 

293 "--output_log_path", 

294 required=False, 

295 help="Path to the log file. Accepted formats: log.", 

296 ) 

297 

298 args = parser.parse_args() 

299 args.config = args.config or "{}" 

300 properties = settings.ConfReader(config=args.config).get_prop_dic() 

301 

302 # Specific call of each building block 

303 autodock_vina_run( 

304 input_ligand_pdbqt_path=args.input_ligand_pdbqt_path, 

305 input_receptor_pdbqt_path=args.input_receptor_pdbqt_path, 

306 input_box_path=args.input_box_path, 

307 output_pdbqt_path=args.output_pdbqt_path, 

308 output_log_path=args.output_log_path, 

309 properties=properties, 

310 ) 

311 

312 

313if __name__ == "__main__": 

314 main()