Coverage for biobb_vs/fpocket/fpocket_run.py: 79%

70 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 FPocketRun class and the command line interface.""" 

4import argparse 

5from typing import Optional 

6import shutil 

7from pathlib import PurePath 

8from biobb_common.generic.biobb_object import BiobbObject 

9from biobb_common.configuration import settings 

10from biobb_common.tools import file_utils as fu 

11from biobb_common.tools.file_utils import launchlogger 

12from biobb_vs.fpocket.common import check_input_path, check_output_path, process_output_fpocket 

13 

14 

15class FPocketRun(BiobbObject): 

16 """ 

17 | biobb_vs FPocketRun 

18 | Wrapper of the fpocket software. 

19 | Finds the binding site of the input_pdb_path file via the `fpocket <https://github.com/Discngine/fpocket>`_ software. 

20 

21 Args: 

22 input_pdb_path (str): Path to the PDB structure where the binding site is to be found. File type: input. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/data/fpocket/fpocket_input.pdb>`_. Accepted formats: pdb (edam:format_1476). 

23 output_pockets_zip (str): Path to all the pockets found by fpocket in the input_pdb_path structure. File type: output. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/reference/fpocket/ref_output_pockets.zip>`_. Accepted formats: zip (edam:format_3987). 

24 output_summary (str): Path to the JSON summary file. File type: output. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/reference/fpocket/ref_output_summary.json>`_. Accepted formats: json (edam:format_3464). 

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

26 * **min_radius** (*float*) - (None) [0.1~1000|0.1] The minimum radius in Ångstroms an alpha sphere might have in a binding pocket. 

27 * **max_radius** (*float*) - (None) [2~1000|0.1] The maximum radius in Ångstroms of alpha spheres in a pocket. 

28 * **num_spheres** (*int*) - (None) [1~1000|1] Indicates how many alpha spheres a pocket must contain at least in order to figure in the results. 

29 * **sort_by** (*str*) - ('druggability_score') From which property the output will be sorted. Values: druggability_score (this score intends to assess the likeliness of the pocket to bind a small drug like molecule), score (fpocket score as defined in the `fpocket paper <https://doi.org/10.1186/1471-2105-10-168>`_), volume (volume of the pocket). 

30 * **binary_path** (*string*) - ('fpocket') path to fpocket 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*) - ('fpocket/fpocket:latest') 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.fpocket.fpocket_run import fpocket_run 

45 prop = { 

46 'min_radius': 3, 

47 'max_radius': 6, 

48 'num_spheres': 35, 

49 'sort_by': 'druggability_score' 

50 } 

51 fpocket_run(input_pdb_path='/path/to/myStructure.pdb', 

52 output_pockets_zip='/path/to/newPockets.zip', 

53 output_summary='/path/to/newSummary.json', 

54 properties=prop) 

55 

56 Info: 

57 * wrapped_software: 

58 * name: fpocket 

59 * version: ==4.1 

60 * license: MIT 

61 * ontology: 

62 * name: EDAM 

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

64 

65 """ 

66 

67 def __init__(self, input_pdb_path, output_pockets_zip, output_summary, 

68 properties=None, **kwargs) -> None: 

69 properties = properties or {} 

70 

71 # Call parent class constructor 

72 super().__init__(properties) 

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

74 

75 # Input/Output files 

76 self.io_dict = { 

77 "in": {"input_pdb_path": input_pdb_path}, 

78 "out": {"output_pockets_zip": output_pockets_zip, "output_summary": output_summary} 

79 } 

80 

81 # Properties specific for BB 

82 self.binary_path = properties.get('binary_path', 'fpocket') 

83 self.min_radius = properties.get('min_radius', None) 

84 self.max_radius = properties.get('max_radius', None) 

85 self.num_spheres = properties.get('num_spheres', None) 

86 self.sort_by = properties.get('sort_by', 'druggability_score') 

87 self.properties = properties 

88 

89 # Check the properties 

90 self.check_properties(properties) 

91 self.check_arguments() 

92 

93 def check_data_params(self, out_log, err_log): 

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

95 self.io_dict["in"]["input_pdb_path"] = check_input_path(self.io_dict["in"]["input_pdb_path"], "input_pdb_path", out_log, self.__class__.__name__) 

96 self.io_dict["out"]["output_pockets_zip"] = check_output_path(self.io_dict["out"]["output_pockets_zip"], "output_pockets_zip", False, out_log, self.__class__.__name__) 

97 self.io_dict["out"]["output_summary"] = check_output_path(self.io_dict["out"]["output_summary"], "output_summary", True, out_log, self.__class__.__name__) 

98 

99 @launchlogger 

100 def launch(self) -> int: 

101 """Execute the :class:`FPocketRun <fpocket.fpocket_run.FPocketRun>` fpocket.fpocket_run.FPocketRun object.""" 

102 

103 # check input/output paths and parameters 

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

105 

106 # Setup Biobb 

107 if self.check_restart(): 

108 return 0 

109 self.stage_files() 

110 

111 if self.container_path: 

112 tmp_input = str(PurePath(self.container_volume_path).joinpath(PurePath(self.io_dict["in"]["input_pdb_path"]).name)) 

113 self.tmp_folder = self.stage_io_dict['unique_dir'] 

114 else: 

115 # create tmp_folder 

116 self.tmp_folder = fu.create_unique_dir() 

117 fu.log('Creating %s temporary folder' % self.tmp_folder, self.out_log) 

118 tmp_input = str(PurePath(self.tmp_folder).joinpath('input.pdb')) 

119 # copy input_pdb_path to tmp_folder 

120 shutil.copy(self.io_dict["in"]["input_pdb_path"], tmp_input) 

121 

122 # create cmd 

123 self.cmd = [self.binary_path, 

124 '-f', tmp_input] 

125 

126 # adding extra properties 

127 if self.min_radius: 

128 self.cmd.extend(['-m', str(self.min_radius)]) 

129 

130 if self.max_radius: 

131 self.cmd.extend(['-M', str(self.max_radius)]) 

132 

133 if self.num_spheres: 

134 self.cmd.extend(['-i', str(self.num_spheres)]) 

135 

136 fu.log('Executing fpocket', self.out_log, self.global_log) 

137 

138 # Run Biobb block 

139 self.run_biobb() 

140 

141 # Copy files to host 

142 self.copy_to_host() 

143 

144 process_output_fpocket(self.tmp_folder, 

145 self.io_dict["out"]["output_pockets_zip"], 

146 self.io_dict["out"]["output_summary"], 

147 self.sort_by, 

148 self.remove_tmp, 

149 self.container_path, 

150 self.out_log, 

151 self.__class__.__name__) 

152 

153 self.tmp_files.extend([ 

154 # self.stage_io_dict.get("unique_dir", ""), 

155 self.tmp_folder 

156 ]) 

157 self.remove_tmp_files() 

158 

159 return self.return_code 

160 

161 

162def fpocket_run(input_pdb_path: str, output_pockets_zip: str, output_summary: str, properties: Optional[dict] = None, **kwargs) -> int: 

163 """Execute the :class:`FPocketRun <fpocket.fpocket_run.FPocketRun>` class and 

164 execute the :meth:`launch() <fpocket.fpocket_run.FPocketRun.launch>` method.""" 

165 

166 return FPocketRun(input_pdb_path=input_pdb_path, 

167 output_pockets_zip=output_pockets_zip, 

168 output_summary=output_summary, 

169 properties=properties, **kwargs).launch() 

170 

171 fpocket_run.__doc__ = FPocketRun.__doc__ 

172 

173 

174def main(): 

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

176 parser = argparse.ArgumentParser(description="Finds the binding site of the input_pdb_path file via the fpocket software", formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999)) 

177 parser.add_argument('--config', required=False, help='Configuration file') 

178 

179 # Specific args of each building block 

180 required_args = parser.add_argument_group('required arguments') 

181 required_args.add_argument('--input_pdb_path', required=True, help='Path to the PDB structure where the binding site is to be found. Accepted formats: pdb.') 

182 required_args.add_argument('--output_pockets_zip', required=True, help='Path to all the pockets found by fpocket in the input_pdb_path structure. Accepted formats: zip.') 

183 required_args.add_argument('--output_summary', required=True, help='Path to the JSON summary file. Accepted formats: json.') 

184 

185 args = parser.parse_args() 

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

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

188 

189 # Specific call of each building block 

190 fpocket_run(input_pdb_path=args.input_pdb_path, 

191 output_pockets_zip=args.output_pockets_zip, 

192 output_summary=args.output_summary, 

193 properties=properties) 

194 

195 

196if __name__ == '__main__': 

197 main()