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
« prev ^ index » next coverage.py v7.14.1, created at 2026-05-28 09:09 +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 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]))
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."""
170 # check input/output paths and parameters
171 self.check_data_params(self.out_log, self.err_log)
173 # Setup Biobb
174 if self.check_restart():
175 return 0
176 self.stage_files()
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", "")
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 )
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)
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 ]
226 # Run Biobb block
227 self.run_biobb()
229 # Copy files to host
230 self.copy_to_host()
232 # remove temporary folder(s)
233 self.remove_tmp_files()
235 self.check_arguments(output_files_created=True, raise_exception=False)
237 return self.return_code
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()
254autodock_vina_run.__doc__ = AutoDockVinaRun.__doc__
255main = AutoDockVinaRun.get_main(autodock_vina_run, "Prepares input ligand for an Autodock Vina Virtual Screening.")
258if __name__ == "__main__":
259 main()