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
« prev ^ index » next coverage.py v7.15.3, created at 2026-08-03 13:34 +0000
1#!/usr/bin/env python3
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
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.
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.
41 Examples:
42 This is a use example of how to use the building block from Python::
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)
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
64 """
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 {}
78 # Call parent class constructor
79 super().__init__(properties)
80 self.locals_var_dict = locals().copy()
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 }
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
104 # Check the properties
105 self.check_properties(properties)
106 self.check_arguments()
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 )
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.
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 )
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."""
178 # check input/output paths and parameters
179 self.check_data_params(self.out_log, self.err_log)
181 # Setup Biobb
182 if self.check_restart():
183 return 0
184 self.stage_files()
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", "")
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 )
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)
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 ]
234 # Run Biobb block
235 self.run_biobb()
237 # Copy files to host
238 self.copy_to_host()
240 # remove temporary folder(s)
241 self.remove_tmp_files()
243 self.check_arguments(output_files_created=True, raise_exception=False)
245 return self.return_code
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()
262autodock_vina_run.__doc__ = AutoDockVinaRun.__doc__
263main = AutoDockVinaRun.get_main(autodock_vina_run, "Prepares input ligand for an Autodock Vina Virtual Screening.")
266if __name__ == "__main__":
267 main()