Coverage for biobb_vs/fpocket/fpocket_filter.py: 83%
86 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 12:00 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 12:00 +0000
1#!/usr/bin/env python3
3"""Module containing the FPocketFilter class and the command line interface."""
5import argparse
6import json
7from typing import Optional
9from biobb_common.configuration import settings
10from biobb_common.generic.biobb_object import BiobbObject
11from biobb_common.tools import file_utils as fu
12from biobb_common.tools.file_utils import launchlogger
14from biobb_vs.fpocket.common import (
15 check_input_path,
16 check_output_path,
17 check_range,
18 process_output_fpocket_filter,
19)
20from biobb_vs.utils.common import _from_string_to_list
23class FPocketFilter(BiobbObject):
24 """
25 | biobb_vs FPocketFilter
26 | Performs a search over the outputs of the fpocket building block.
27 | Finds one or more binding sites in the outputs of the fpocket building block from given parameters.
29 Args:
30 input_pockets_zip (str): Path to all the pockets found by fpocket. File type: input. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/data/fpocket/input_pockets.zip>`_. Accepted formats: zip (edam:format_3987).
31 input_summary (str): Path to the JSON summary file returned by fpocket. File type: input. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/data/fpocket/input_summary.json>`_. Accepted formats: json (edam:format_3464).
32 output_filter_pockets_zip (str): Path to the selected pockets after filtering. File type: output. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/reference/fpocket/ref_output_filter_pockets.zip>`_. Accepted formats: zip (edam:format_3987).
33 properties (dic - Python dictionary object containing the tool parameters, not input/output files):
34 * **score** (*list*) - (None) List of two float numbers between 0 and 1 indicating the score range. Indicates the fpocket score after the evaluation of pocket prediction accuracy as defined in the `fpocket paper <https://doi.org/10.1186/1471-2105-10-168>`_.
35 * **druggability_score** (*list*) - (None) List of two float numbers between 0 and 1 indicating the druggability_score range. It's a value between 0 and 1, 0 signifying that the pocket is likely to not bind a drug like molecule and 1, that it is very likely to bind the latter.
36 * **volume** (*list*) - (None) List of two float numbers indicating the volume range. Indicates the pocket volume.
37 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
38 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
39 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
41 Examples:
42 This is a use example of how to use the building block from Python::
44 from biobb_vs.fpocket.fpocket_filter import fpocket_filter
45 prop = {
46 'score': [0.2, 1],
47 'druggability_score': [0.2, 0.8],
48 'volume': [100, 600.2]
49 }
50 fpocket_filter(input_pockets_zip='/path/to/myPockets.zip',
51 input_summary='/path/to/mySummary.json',
52 output_filter_pockets_zip='/path/to/newPockets.json',
53 properties=prop)
55 Info:
56 * wrapped_software:
57 * name: In house
58 * license: Apache-2.0
59 * ontology:
60 * name: EDAM
61 * schema: http://edamontology.org/EDAM.owl
63 """
65 def __init__(
66 self,
67 input_pockets_zip,
68 input_summary,
69 output_filter_pockets_zip,
70 properties=None,
71 **kwargs,
72 ) -> None:
73 properties = properties or {}
75 # Call parent class constructor
76 super().__init__(properties)
77 self.locals_var_dict = locals().copy()
79 # Input/Output files
80 self.io_dict = {
81 "in": {
82 "input_pockets_zip": input_pockets_zip,
83 "input_summary": input_summary,
84 },
85 "out": {"output_filter_pockets_zip": output_filter_pockets_zip},
86 }
88 # Properties specific for BB
89 self.score = [
90 float(elem) for elem in _from_string_to_list(properties.get("score", None))
91 ]
92 self.druggability_score = [
93 float(elem)
94 for elem in _from_string_to_list(properties.get("druggability_score", None))
95 ]
97 self.volume = [
98 float(elem) for elem in _from_string_to_list(properties.get("volume", None))
99 ]
100 self.properties = properties
102 # Check the properties
103 self.check_properties(properties)
104 self.check_arguments()
106 def check_data_params(self, out_log, err_log):
107 """Checks all the input/output paths and parameters"""
108 self.io_dict["in"]["input_pockets_zip"] = check_input_path(
109 self.io_dict["in"]["input_pockets_zip"],
110 "input_pockets_zip",
111 out_log,
112 self.__class__.__name__,
113 )
114 self.io_dict["in"]["input_summary"] = check_output_path(
115 self.io_dict["in"]["input_summary"],
116 "input_summary",
117 False,
118 out_log,
119 self.__class__.__name__,
120 )
121 self.io_dict["out"]["output_filter_pockets_zip"] = check_output_path(
122 self.io_dict["out"]["output_filter_pockets_zip"],
123 "output_filter_pockets_zip",
124 True,
125 out_log,
126 self.__class__.__name__,
127 )
129 def score_matcher(self, score):
130 return lambda d: d["score"] > score[0] and d["score"] <= score[1]
132 def druggability_score_matcher(self, druggability_score):
133 return (
134 lambda d: d["druggability_score"] > druggability_score[0] and d["druggability_score"] <= druggability_score[1]
135 )
137 def volume_matcher(self, volume):
138 return lambda d: d["volume"] > volume[0] and d["volume"] <= volume[1]
140 @launchlogger
141 def launch(self) -> int:
142 """Execute the :class:`FPocketFilter <fpocket.fpocket_filter.FPocketFilter>` fpocket.fpocket_filter.FPocketFilter object."""
144 # check input/output paths and parameters
145 self.check_data_params(self.out_log, self.err_log)
147 # Setup Biobb
148 if self.check_restart():
149 return 0
150 self.stage_files()
152 # load input_summary into a dictionary
153 with open(self.io_dict["in"]["input_summary"]) as json_file:
154 data = json.load(json_file)
156 # build search_list
157 search_list = []
158 ranges = {}
159 if self.score:
160 check_range(
161 "score", self.score, [0, 1], self.out_log, self.__class__.__name__
162 )
163 search_list.append(self.score_matcher(self.score))
164 ranges["score"] = self.score
165 if self.druggability_score:
166 check_range(
167 "druggability_score",
168 self.druggability_score,
169 [0, 1],
170 self.out_log,
171 self.__class__.__name__,
172 )
173 search_list.append(self.druggability_score_matcher(self.druggability_score))
174 ranges["druggability_score"] = self.druggability_score
175 if self.volume:
176 check_range(
177 "volume", self.volume, [0, 10000], self.out_log, self.__class__.__name__
178 )
179 search_list.append(self.volume_matcher(self.volume))
180 ranges["volume"] = self.volume
182 fu.log(
183 "Performing a search under the next parameters: %s"
184 % (", ".join(["{0}: {1}".format(k, v) for k, v in ranges.items()])),
185 self.out_log,
186 )
188 # perform search
189 search = [x for x in data if all([f(data[x]) for f in search_list])]
191 if len(search) == 0:
192 fu.log("No matches found", self.out_log)
193 return 0
195 str_out = ""
196 for s in search:
197 str_out = str_out + (
198 "\n**********\n%s\n**********\nscore: %s\ndruggability_score: %s\nvolume: %s\n"
199 % (
200 s,
201 data[s]["score"],
202 data[s]["druggability_score"],
203 data[s]["volume"],
204 )
205 )
207 fu.log("Found %d matches:%s" % (len(search), str_out), self.out_log)
209 # create tmp_folder
210 self.tmp_folder = fu.create_unique_dir()
211 fu.log("Creating %s temporary folder" % self.tmp_folder, self.out_log)
213 process_output_fpocket_filter(
214 search,
215 self.tmp_folder,
216 self.io_dict["in"]["input_pockets_zip"],
217 self.io_dict["out"]["output_filter_pockets_zip"],
218 self.remove_tmp,
219 self.out_log,
220 )
222 # Copy files to host
223 self.copy_to_host()
225 self.tmp_files.extend([
226 # self.stage_io_dict.get("unique_dir", ""),
227 self.tmp_folder
228 ])
229 self.remove_tmp_files()
231 self.check_arguments(output_files_created=True, raise_exception=False)
233 return 0
236def fpocket_filter(
237 input_pockets_zip: str,
238 input_summary: str,
239 output_filter_pockets_zip: str,
240 properties: Optional[dict] = None,
241 **kwargs,
242) -> int:
243 """Execute the :class:`FPocketFilter <fpocket.fpocket_filter.FPocketFilter>` class and
244 execute the :meth:`launch() <fpocket.fpocket_filter.FPocketFilter.launch>` method."""
246 return FPocketFilter(
247 input_pockets_zip=input_pockets_zip,
248 input_summary=input_summary,
249 output_filter_pockets_zip=output_filter_pockets_zip,
250 properties=properties,
251 **kwargs,
252 ).launch()
254 fpocket_filter.__doc__ = FPocketFilter.__doc__
257def main():
258 """Command line execution of this building block. Please check the command line documentation."""
259 parser = argparse.ArgumentParser(
260 description="Finds one or more binding sites in the outputs of the fpocket building block from given parameters.",
261 formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999),
262 )
263 parser.add_argument("--config", required=False, help="Configuration file")
265 # Specific args of each building block
266 required_args = parser.add_argument_group("required arguments")
267 required_args.add_argument(
268 "--input_pockets_zip",
269 required=True,
270 help="Path to all the pockets found by fpocket. Accepted formats: zip.",
271 )
272 required_args.add_argument(
273 "--input_summary",
274 required=True,
275 help="Path to the JSON summary file returned by fpocket. Accepted formats: json.",
276 )
277 required_args.add_argument(
278 "--output_filter_pockets_zip",
279 required=True,
280 help="Path to the selected pockets after filtering. Accepted formats: zip.",
281 )
283 args = parser.parse_args()
284 args.config = args.config or "{}"
285 properties = settings.ConfReader(config=args.config).get_prop_dic()
287 # Specific call of each building block
288 fpocket_filter(
289 input_pockets_zip=args.input_pockets_zip,
290 input_summary=args.input_summary,
291 output_filter_pockets_zip=args.output_filter_pockets_zip,
292 properties=properties,
293 )
296if __name__ == "__main__":
297 main()